diff --git a/README.md b/README.md index b5ca5f4..5c0e658 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,19 @@ -git-recipes -==== +# git-recipes + 高质量的Git中文教程,来自国外社区的优秀文章和个人实践 -目录 ---- +## [目录]((https://github.com/geeeeeeeeek/git-recipes/wiki/) + git-recipes的所有文章都以Wiki的方式呈现,请移步[项目Wiki](https://github.com/geeeeeeeeek/git-recipes/wiki/)查看目录和详细内容。 -我为什么要做这份菜单 ---- +## 我为什么要做这份菜单 + 在整理Git资料的时候,我发现社区贡献了非常多高质量的博客文章、指南等等。尤其英文的那些资料,除了大家熟知的《Git图解》,还有好多优秀的文章仍无人翻译。此外,这些资料往往只涉及某些特定的话题,如果能有一份菜单将这些菜谱以特定的方式串起来,那么对于Git学习者来说将会是极大的便利。尤其对于我这样热爱查阅社区资料胜过出版物的懒人 : ) 随着我的学习节奏还会不断有新的菜谱加入进来,或许不会很频繁,不过也没有确定的终点。 -版权说明 ---- -除非另行注明,这个项目中的所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享,童仲毅(geeeeeeeeek@github)版权所有。 +## 版权说明 -其中不少资料是在原基础上翻译或演绎而来的,我都在页面最上方标明了原作者、原文链接以及原文采用的协议。如仍有版权疑问,请在issue中提出。 +除非另行注明,这个项目中的所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享,BY 童仲毅(geeeeeeeeek@github)。 -欢迎通过issue或者pr推荐你认为合适的资料,让这份菜单更充实一些。 +不少文章在原基础上翻译或演绎而来,页面上方均标明了原作者、原文链接以及原文采用的协议。如仍有版权疑问,请在issue中提出。 + +欢迎通过issue或者pr推荐你认为合适的资料,让这份菜单更充实一些。 \ No newline at end of file diff --git a/sources/保存你的更改.md b/sources/保存你的更改.md new file mode 100644 index 0000000..8eb2e9a --- /dev/null +++ b/sources/保存你的更改.md @@ -0,0 +1,147 @@ +# 保存你的更改 + +> BY 童仲毅(geeeeeeeeek@github) +> +> 这是一篇在[原文](https://www.atlassian.com/git/tutorials/saving-changes)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。 + +## git add + +`git add`命令将工作目录中的变化添加到缓存区。它告诉Git你想要在下一次提交时包含这个文件的更新。但是,`git add`不会怎么影响你的仓库——在你运行`git commit`前更改都不会被记录。 + +使用这些命令之时,你还需要`git status`来查看工作目录和缓存区的状态。 + +### 用法 + +``` +git add +``` + +将``中的更改加入下次提交的缓存。 + +``` +git add +``` + +将``下的更改加入下次提交的缓存。 + +``` +git add -p +``` + +开始交互式的缓存,你可以选择文件的一部分加入到下次提交缓存。它会向你展示一堆更改,等待你输入一个命令。`y`将这块更改加入缓存,`n`忽略这块更改,`s`将它分割成更小的块,`e`手动编辑这块更改,以及`q`退出。 + +### 讨论 + +`git add`和`git commit`这两个命令组成了最基本的Git工作流。每一个Git用户都需要理解这两个命令,不管他们团队的协作模型是如何的。我有一千种方式可以将项目版本记录在仓库的历史中。 + +在一个只有编辑、缓存、提交这样基本流程的项目上开发。首先,你要在工作目录中编辑你的文件。当你准备备份项目的当前状态时,你通过`git add`来缓存更改。当你对缓存的快照满意之后,你通过`git commit`将它提交到你的项目历史中去。 + + + +![Git Tutorial: git add Snapshot](https://www.atlassian.com/git/images/tutorials/getting-started/saving-changes/01.svg) + + + +`git add`命令不能和 `svn add`混在一起理解,后者将文件添加到仓库中。而`git add` 发生于更抽象的 *更改* 层面。也就是说,`git add`在每次你修改一个文件时都需要被调用,而`svn add`只需要每个文件调用一次。这听上去很多余,但这样的工作流使得一个项目更容易组织。 + +#### 缓存区 + +缓存区是Git更为独特的地方之一,如果你是从SVN(甚至是Mercurial)迁移而来,那你可得花点时间理解了。你可以简单地把它想成是工作目录和项目历史之间的缓冲区。 + +缓存允许你在实际提交到项目历史之前,将相关的更改组合成一份高度专注的快照,而不是将你上次提交以后产生的所有更改一并提交。也就是说你可以更改各种不相关的文件,然后回过去将它们按逻辑切分,将相关的更改添加到缓存,一份一份提交。在任何修改控制系统中,很重要的一点是提交必须是原子性的,以便于追踪bug,并用最小的代价回滚更改。 + +### 栗子 + +当你开始新项目的时候,`git add`和`svn import`类似。为了创建当前目录的初始提交,使用下面两个命令: + +``` +git add . +git commit +``` + +当你项目设置好之后,新的文件可以通过路径传递给`git add`来添加: + +``` +git add hello.py +git commit +``` + +上面的命令同样可以用于记录已有文件的更改。重复一次,Git不会区分缓存的更改来自新文件,还是仓库中已有的文件。 + +## git commit + +`git commit`命令将缓存的快照提交到项目历史。提交的快照可以认为是项目『安全』的版本——Git永远不会改变它们,除非你这么要求。和`git add`一样,这是最重要的Git命令之一。 + +尽管和它和`svn commit`名字一样,但实际上它们毫无关联。快照被提交到本地仓库,不会和其他Git仓库有任何交互。 + +### 用法 + +``` +git commit +``` + +提交已经缓存的快照。它会运行文本编辑器,等待你输入提交信息。当你输入信息之后,保存文件,关闭编辑器,创建实际的提交。 + +``` +git commit -m "" +``` + +提交已经缓存的快照。但将``作为提交信息,而不是运行文本编辑器。 + +``` +git commit -a +``` + +提交一份包含工作目录所有更改的快照。它只包含跟踪过的文件的更改(那些之前已经通过`git add`添加过的文件)。 + +### 讨论 + +快照总是提交到 *本地* 仓库。这一点和SVN截然不同,后者的工作拷贝提交到中央仓库。而Git不会强制你和中央仓库进行交互,直到你准备好了。就像缓存区是工作目录和项目历史之间的缓冲地带,每个开发者的本地仓库是他们贡献的代码和中央仓库之间的缓冲地带。 + +这一点改变了Git用户基本的开发模型。Git开发者可以在本地仓库中积累一些提交,而不是一发生更改就直接提交到中央仓库。这对于SVN风格的协作有着诸多优点:更容易将功能切分成原子性的提交,让相关的提交组合在一起,发布到中央仓库之前整理好本地的历史。开发者得以在一个隔离的环境中工作,直到他们方便的时候再整合代码。 + +#### 记录快照,而不是记录差异 + +SVN和Git除了使用上存在巨大差异,它们底层的实现同样遵循截然不同的设计哲学。SVN追踪文件的 *变化* ,而Git的版本控制模型基于 *快照* 。比如说,一个SVN提交由仓库中原文件相比的差异(diff)组成。而Git在每次提交中记录文件的 *完整内容* 。 + + + +![Git Tutorial: Snapshots, Not Differences](https://www.atlassian.com/git/images/tutorials/getting-started/saving-changes/02.svg) + + + +这让很多Git操作比SVN来的快得多,因为文件的某个版本不需要通过版本间的差异组装得到——每个文件完整的修改能立刻从Git 的内部数据库中得到。 + +Git的快照模型对它版本控制模型的方方面面都有着深远的影响,从分支到合并工具,再到协作工作流,以至于影响了所有特性。 + +### 栗子 + +下面这个栗子假设你编辑了`hello.py`文件的一些内容,并且准备好将它提交到项目历史。首先,你需要用`git add`缓存文件,然后提交缓存的快照。 + +``` +git add hello.py +git commit +``` + +它会打开一个文件编辑器(可以通过`git config`设置) 询问提交信息,同时列出将被提交的文件。 + +``` +# Please enter the commit message for your changes. Lines starting +# with '#' will be ignored, and an empty message aborts the commit. +# On branch master +# Changes to be committed: +# (use "git reset HEAD ..." to unstage) +# +#modified: hello.py +``` + +Git对提交信息没有特定的格式限制,但约定俗成的格式是:在第一行用50个以内的字符总结这个提交,留一空行,然后详细阐述具体的更改。比如: + +``` +Change the message displayed by hello.py + +- Update the sayHello() function to output the user's name +- Change the sayGoodbye() function to a friendlier message +``` + +注意,很多开发者倾向于在提交信息中使用一般现在时态。这样看起来更像是对仓库进行的操作,让很多改写历史的操作更加符合直觉。 \ No newline at end of file diff --git a/wiki/catagory.md b/wiki/catagory.md index 365359e..6811bc3 100644 --- a/wiki/catagory.md +++ b/wiki/catagory.md @@ -1,56 +1,67 @@ **第1篇 Git** - **第2篇 从零搭建本地代码仓库** 这篇完全面向入门者。我假设你从零开始创建一个项目并且想用Git来进行版本控制,我们会讨论如何在你的个人项目中使用Git,比如如何初始化你的项目,如何管理新的或者已有的文件,如何在远端仓库中储存你的代码。 - - - **第1章** [快速指南](https://github.com/geeeeeeeeek/git-recipes/wiki/2.1-%E5%BF%AB%E9%80%9F%E6%8C%87%E5%8D%97) - - **第2章** [创建代码仓库](https://github.com/geeeeeeeeek/git-recipes/wiki/2.2-%E5%88%9B%E5%BB%BA%E4%BB%A3%E7%A0%81%E4%BB%93%E5%BA%93) - - - **第3章** 保存你的更改 **第4章** 查看仓库状态 **第5章** 查看以前的提交 **第6章** 回滚错误的更改 **第7章** 重写项目历史 +- **第1章** [快速指南](https://github.com/geeeeeeeeek/git-recipes/wiki/2.1-%E5%BF%AB%E9%80%9F%E6%8C%87%E5%8D%97) +- **第2章** [创建代码仓库](https://github.com/geeeeeeeeek/git-recipes/wiki/2.2-%E5%88%9B%E5%BB%BA%E4%BB%A3%E7%A0%81%E4%BB%93%E5%BA%93) +- **第3章** [保存你的更改](https://github.com/geeeeeeeeek/git-recipes/wiki/2.3-%E4%BF%9D%E5%AD%98%E4%BD%A0%E7%9A%84%E6%9B%B4%E6%94%B9) +- **第4章** 查看仓库状态 **第5章** 查看以前的提交 **第6章** 回滚错误的更改 **第7章** 重写项目历史 **第3章 远程团队协作和管理** - - **第1章** 快速指南 **第2章** 同步代码 **第3章** 创建Pull Request **第4章** 使用分支 **第5章** 几种工作流 - +- **第1章** 快速指南 **第2章** 同步代码 **第3章** 创建Pull Request **第4章** 使用分支 **第5章** 几种工作流 + **第4篇 Git命令详解** - - 第1章 [图解Git命令](https://github.com/geeeeeeeeek/git-recipes/wiki/4.1-%E5%9B%BE%E8%A7%A3Git%E5%91%BD%E4%BB%A4) +- **第1章** [图解Git命令](https://github.com/geeeeeeeeek/git-recipes/wiki/4.1-%E5%9B%BE%E8%A7%A3Git%E5%91%BD%E4%BB%A4) + 如果你稍微理解git的工作原理,这篇文章能够让你理解的更透彻。 - + + **第5篇 Git实用贴士** - - **第1章** [代码合并:Merge、Rebase的选择](https://github.com/geeeeeeeeek/git-recipes/wiki/5.1-%E4%BB%A3%E7%A0%81%E5%90%88%E5%B9%B6%EF%BC%9AMerge%E3%80%81Rebase%E7%9A%84%E9%80%89%E6%8B%A9) +- **第1章** [代码合并:Merge、Rebase的选择](https://github.com/geeeeeeeeek/git-recipes/wiki/5.1-%E4%BB%A3%E7%A0%81%E5%90%88%E5%B9%B6%EF%BC%9AMerge%E3%80%81Rebase%E7%9A%84%E9%80%89%E6%8B%A9) + `git rebase` 和`git merge` 都是用来合并分支,只不过方式不太相同。`git rebase` 经常被人认为是一种Git巫术,初学者应该避而远之。但如果使用得当,它能省去太多烦恼。在这篇文章中,我们会通过比较找到Git工作流中所有可以使用rebase的机会。 - - - **第2章** [代码回滚:Reset、Checkout、Revert的选择](https://github.com/geeeeeeeeek/git-recipes/wiki/5.2-%E4%BB%A3%E7%A0%81%E5%9B%9E%E6%BB%9A%EF%BC%9AReset%E3%80%81Checkout%E3%80%81Revert%E7%9A%84%E9%80%89%E6%8B%A9) + + +- **第2章** [代码回滚:Reset、Checkout、Revert的选择](https://github.com/geeeeeeeeek/git-recipes/wiki/5.2-%E4%BB%A3%E7%A0%81%E5%9B%9E%E6%BB%9A%EF%BC%9AReset%E3%80%81Checkout%E3%80%81Revert%E7%9A%84%E9%80%89%E6%8B%A9) + git reset、git checkout和git revert都是用来撤销代码仓库中的某些更改,所以我们经常弄混。在这篇文章中,我们比较最常见的用法,分析在什么场景下该用哪个命令。 - - **第3章** [Git log高级用法](https://github.com/geeeeeeeeek/git-recipes/wiki/5.3-Git-log%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95) - + +- **第3章** [Git log高级用法](https://github.com/geeeeeeeeek/git-recipes/wiki/5.3-Git-log%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95) + + 任何一个版本控制系统设计的目的都是为了记录你代码的变化——谁贡献了什么,找出bug是什么时候引入的,以及撤回一些有问题的更改。`git log` 可以格式化commit输出的形式,或过滤输出的commit从而找到项目中你需要的任何信息。 - - **第4章** [Git钩子:自定义你的工作流](https://github.com/geeeeeeeeek/git-recipes/wiki/5.4-Git%E9%92%A9%E5%AD%90%EF%BC%9A%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BD%A0%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%B5%81) + +- **第4章** [Git钩子:自定义你的工作流](https://github.com/geeeeeeeeek/git-recipes/wiki/5.4-Git%E9%92%A9%E5%AD%90%EF%BC%9A%E8%87%AA%E5%AE%9A%E4%B9%89%E4%BD%A0%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%B5%81) + Git钩子是在Git仓库中特定事件发生时自动运行的脚本。它可以让你自定义Git内部的行为,在开始周期中的关键点触发自定义的行为,自动化或者优化你开发工作流中任意部分。 - - - **第5章** [Git提交引用和引用日志](https://github.com/geeeeeeeeek/git-recipes/wiki/5.5-Git%E6%8F%90%E4%BA%A4%E5%BC%95%E7%94%A8%E5%92%8C%E5%BC%95%E7%94%A8%E6%97%A5%E5%BF%97) + + +- **第5章** [Git提交引用和引用日志](https://github.com/geeeeeeeeek/git-recipes/wiki/5.5-Git%E6%8F%90%E4%BA%A4%E5%BC%95%E7%94%A8%E5%92%8C%E5%BC%95%E7%94%A8%E6%97%A5%E5%BF%97) + 提交是Git的精髓所在,你无时不刻不在创建和缓存提交、查看以前的提交,或者用各种Git命令在仓库间转移你的提交。在这章中,我们研究提交的各种引用方式,以及涉及到的Git命令的工作原理。我们还会学到如何使用Git的引用日志查看看似已经删除的提交。 + **第6篇 Git应用实践:用GitLab搭建一个课程教学仓库** - - **第1章** 教师和学生的最佳实践指南 +- **第1章** 教师和学生的最佳实践指南 + GitLab本身的权限管理和组织结构已经满足了教学中课程创建、学生管理、收发作业、通知统计等需求。不过,在实践中我们要尤其注意各处的权限和命名规范。因此,我总结了一份教师和学生的最佳实践指南,保证各门课程能够顺畅地进行。 - - - **第2章** 在上层搭建一个Classroom应用 + + +- **第2章** 在上层搭建一个Classroom应用 + 在实践中,我们要手动地导入大量学生、创建分支以及在Gitlab复杂的页面中穿梭。显然我们可以做得更好,那就是在GitLab上再搭建一层Classroom应用。在这章中,我会介绍我们是如何抽取需求,以及构建这个应用的。 - -