diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.md b/README.md index 21a9271..b5ca5f4 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,10 @@ git-recipes ==== -高质量的Git中文教程 +高质量的Git中文教程,来自国外社区的优秀文章和个人实践 目录 --- -**第1篇 Git** - - -**第2篇 从零搭建本地代码仓库** - - - **第1章** [快速指南](https://github.com/geeeeeeeeek/git-recipes/blob/master/Git%E7%AE%80%E6%98%93%E6%8C%87%E5%8D%97(%E4%B8%8A).md) - - 这节完全面向入门者。我假设你从零开始创建一个项目并且想用Git来进行版本控制,我们会讨论如何在你的个人项目中使用Git,比如如何初始化你的项目,如何管理新的或者已有的文件,如何在远端仓库中储存你的代码。 - - - **第2章** 创建代码仓库 - - - **第3章** 保存你的更改 - - - **第4章** 查看仓库状态 - - - **第5章** 查看以前的提交 - - - **第6章** 回滚错误的更改 - - - **第7章** 重写项目历史 - -**第3章 远程团队协作和管理** - - - **第1章** 快速指南 - - - **第2章** 同步代码 - - - **第3章** 创建Pull Request - - - **第4章** 使用分支 - - - **第5章** 几种工作流 - -**第4篇 Git命令详解** - - - 第1章 [图解Git命令](https://github.com/geeeeeeeeek/git-recipes/blob/master/Git%E5%9B%BE%E8%A7%A3.md) - - 如果你稍微理解git的工作原理,这篇文章能够让你理解的更透彻。 - -**第5篇 Git实用贴士** - - - **第1章** [代码合并:Merge、Rebase的选择](https://github.com/geeeeeeeeek/git-recipes/blob/master/%E4%BB%A3%E7%A0%81%E5%90%88%E5%B9%B6:Merge%E8%BF%98%E6%98%AFRebase.md) - - `git rebase` 和`git merge` 都是用来合并分支,只不过方式不太相同。`git rebase` 经常被人认为是一种Git巫术,初学者应该避而远之。但如果使用得当,它能省去太多烦恼。在这篇文章中,我们会通过比较找到Git工作流中所有可以使用rebase的机会。 - - - **第2章** [代码回滚:Reset、Checkout、Revert的选择](https://github.com/geeeeeeeeek/git-recipes/blob/master/%E5%9B%9E%E6%BB%9A%E5%91%BD%E4%BB%A4Reset%E3%80%81Checkout%E3%80%81Revert%E8%BE%A8%E6%9E%90.md) - - git reset、git checkout和git revert都是用来撤销代码仓库中的某些更改,所以我们经常弄混。在这篇文章中,我们比较最常见的用法,分析在什么场景下该用哪个命令。 - - - **第3章** [Git log高级用法](https://github.com/geeeeeeeeek/git-recipes/blob/master/Git_log%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95.md) - - 任何一个版本控制系统设计的目的都是为了记录你代码的变化——谁贡献了什么,找出bug是什么时候引入的,以及撤回一些有问题的更改。`git log` 可以格式化commit输出的形式,或过滤输出的commit从而找到项目中你需要的任何信息。 - - - **第4章** [Git钩子:自定义你的工作流](https://github.com/geeeeeeeeek/git-recipes/blob/master/Git%E9%92%A9%E5%AD%90.md) - - Git钩子是在Git仓库中特定事件发生时自动运行的脚本。它可以让你自定义Git内部的行为,在开始周期中的关键点触发自定义的行为,自动化或者优化你开发工作流中任意部分。 - - - **第5章** Git ref引用 - -**第6篇 Git应用实践:用GitLab搭建一个课程教学仓库** - - - **第1章** 教师和学生的最佳实践指南 - - GitLab本身的权限管理和组织结构已经满足了教学中课程创建、学生管理、收发作业、通知统计等需求。不过,在实践中我们要尤其注意各处的权限和命名规范。因此,我总结了一份教师和学生的最佳实践指南,保证各门课程能够顺畅地进行。 - - **第2章** 在上层搭建一个Classroom应用 - - 在实践中,我们要手动地导入大量学生、创建分支以及在Gitlab复杂的页面中穿梭。显然我们可以做得更好,那就是在GitLab上再搭建一层Classroom应用。在这章中,我会介绍我们是如何抽取需求,以及构建这个应用的。 - +git-recipes的所有文章都以Wiki的方式呈现,请移步[项目Wiki](https://github.com/geeeeeeeeek/git-recipes/wiki/)查看目录和详细内容。 我为什么要做这份菜单 --- diff --git a/Git_log高级用法.md b/sources/Git_log高级用法.md similarity index 76% rename from Git_log高级用法.md rename to sources/Git_log高级用法.md index 4680fcf..7181328 100644 --- a/Git_log高级用法.md +++ b/sources/Git_log高级用法.md @@ -5,17 +5,17 @@ Git log高级用法 > > 这是一篇在[原文](https://www.atlassian.com/git/tutorials/git-log)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。 -每一个版本控制系统的目的都是为了记录你代码的变化。你可以看到你项目的历史记录——谁贡献了什么,找出bug是什么时候引入的,还有撤回一些有问题的更改。但是,掌控这些的前提是你知道如何来使用它。这就是为什么会有`git log` 这个命令。 +每一个版本控制系统的出现都是为了让你记录代码的变化。你可以看到项目的历史记录——谁贡献了什么、bug是什么时候引入的,还可以撤回有问题的更改。但是,首先你得知道如何来使用它。这也就是为什么会有`git log` 这个命令。 -到现在为止,你应该已经知道如何用`git log` 命令来显示最基本的commit的信息。但是,你还可以传入各种不同的参数来获得不一样的输出。 +到现在为止,你应该已经知道如何用`git log` 命令来显示最基本的提交信息。但除此之外,你还可以传入各种不同的参数来获得不一样的输出。 -`git log` 有两个高级用法:一是格式化commit输出的方式,二是过滤哪些commit要输出。这两个用法合二为一,你可以找到你项目中你需要的任何信息。 +`git log` 有两个高级用法:一是自定义commit的输出格式,二是过滤哪些commit要输出。这两个用法合二为一,你就可以找到你项目中你需要的任何信息。 格式化Log输出 --- -首先,这篇文章会展示几种`git log` 格式化输出的例子。它们大多数只是通过标记来向`git log` 请求或多或少的信息。 +首先,这篇文章会展示几种`git log` 格式化输出的例子。大多数例子只是通过标记来向`git log` 请求或多或少的信息。 -如果你不喜欢默认的`git log` 格式,你可以用`git config` 的别名功能来为任何一种格式创建一个快捷方式。 +如果你不喜欢默认的`git log` 格式,你可以用`git config` 的别名功能来给你想要的格式创建一个快捷方式。 ### Oneline @@ -27,11 +27,11 @@ ad8621a Fix a bug in the feature 16b36c6 Add a new feature 23ad9ad Add the initial code base ``` -这对于获得你项目的大致情况是很有帮助的。 +它对于获得你项目的大致情况很有帮助。 ### Decorate -很多时候,知道每个commit关联的分支或者标签是很有用的。`--decorate` 标记让`git log` 显示指向这个commit的所有引用(比如说分支、标签等等)。 +很多时候,知道每个commit关联的分支或者标签很有用。`--decorate` 标记让`git log` 显示指向这个commit的所有引用(比如说分支、标签等)。 这可以和另一个配置项一起使用。比如,执行`git log --oneline --decorate` 会将commit历史格式化成这样: @@ -50,7 +50,7 @@ ad8621a (feature) Fix a bug in the feature `git log` 提供了很多选项来显示两个commit之间的差异。其中最常用的两个是`--stat` 和`-p`。 -`--stat` 选项显示每次commit对文件的增删数量(注意修改一行记作增加一行且删去一行)当你想要查看commit产生的变化时这会非常有用。比如说,下面这个commit在hello.py文件中增加了67行,删去了38行。 +`--stat` 选项显示每次commit的文件增删数量(注意修改一行记作增加一行且删去一行),当你想要查看commit引入的变化时这会非常有用。比如说,下面这个commit在hello.py文件中增加了67行,删去了38行。 ``` commit f2a238924e89ca1d4947662928218a06d39068c3 @@ -63,7 +63,7 @@ Date: Fri Jun 25 17:30:28 2014 -0500 1 file changed, 67 insertion(+), 38 deletions(-) ``` -文件名后面+和-号数量是这个commit造成的更改中增删的相对比例。它给你一个直观的感觉,关于每次commit做了什么。如果你想知道每次commit删改的绝对数量,你可以将`-p` 选项传入`git log` 。这样commit所有的删改都会被输出: +文件名后面+和-的数量是这个commit造成的更改中增删的相对比例。它给你一个直观的感觉,关于这次commit有多少改动。如果你想知道每次commit删改的绝对数量,你可以将`-p` 选项传入`git log` 。这样commit所有的删改都会被输出: ``` commit 16b36c697eb2d24302f89aa22d9170dfe609855b @@ -81,7 +81,7 @@ index 18ca709..c673b40 100644 +print("Hello, Git!") ``` -对于改动很多的commit来说,这个输出会变得又长又大。一般来说,当你输出所有删改的时候,你应该是想要查找某一具体的改动。这种情况你会想用`pickaxe` 选项。 +对于改动很多的commit来说,这个输出会变得又长又大。一般来说,当你输出所有删改的时候,你应该是想要查找某一具体的改动,这时你就要用到`pickaxe` 选项。 ### Shortlog `git shortlog` 是一种特别的`git log` ,它是为创建发布声明设计的。它把每个commit按作者分类,显示commit信息的第一行。这样可以容易地看到谁做了什么。 @@ -119,7 +119,7 @@ For a simple repository with just 2 branches, this will produce the following: 星号表明这个commit所在的分支,所以上面这个图的意思是`23ad9ad` 和`16b36c6` 这两个commit在topic分之上,其余的在master分支上。 -虽然这对简单的项目来说是个很好用的选项,但你可能会更喜欢gitk或SourceTree这些更强大的可视化工具来分析庞大的项目。 +虽然这对简单的项目来说是个很好用的选择,但你可能会更喜欢gitk或SourceTree这些更强大的可视化工具来分析大型项目。 ### 自定义格式 @@ -143,10 +143,10 @@ John committed f12ca28 on Wed Jun 22 13:50:31 2014 -0500 过滤提交历史 --- -格式化commit输出只是`git log` 其中一个用途。另一半是理解如何浏览整个提交历史。接下来的文章会介绍如果用`git log` 选择项目历史中的特定的commit。所有的用法都可以和上面讨论过的格式化选项结合起来。 +格式化commit输出只是`git log` 其中的一个用途。另一半是理解如何浏览整个提交历史。接下来的文章会介绍如何用`git log` 选择项目历史中的特定的commit。所有的用法都可以和上面讨论过的格式化选项结合起来。 ### 按数量 -`git log` 最基础的过滤选项是限制显示的commit数量。当你只对最近几次commit感兴趣时,它会节省你一页一页查看的时间。 +`git log` 最基础的过滤选项是限制显示的commit数量。当你只对最近几次commit感兴趣时,它可以节省你一页一页查看的时间。 你可以在后面加上`-`选项。比如说,下面这个命令会显示最新的3次commit: ``` @@ -172,7 +172,7 @@ get log --after="yesterday" git log --after="2014-7-1" --before="2014-7-4" ``` -注意`--since` 、`--until` 标记和`--after` 、`--before` 标记是分别相同的。 +注意`--since` 、`--until` 标记和`--after` 、`--before` 标记分别是等价的。 ### 按作者 当你只想看某一特定作者的commit的时候,你可以使用`--author` 标记。它接受正则表达式,返回所有作者名字满足这个规则的commit。如果你知道那个作者的确切名字你可以直接传入文本字符串: @@ -213,7 +213,7 @@ git log --grep="JRA-224:" git log -- foo.py bar.py ``` -`--` 参数告诉`git log` 接下来的参数是文件路径而不是分支名。如果分支名和文件名不可能冲突,你可以省略`--`。 +`--` 告诉`git log` 接下来的参数是文件路径而不是分支名。如果分支名和文件名不可能冲突,你可以省略`--`。 ### 按内容 @@ -225,11 +225,11 @@ git log -S "Hello, World!" 如果你想用正则表达式而不是字符串来搜索,你可以使用`-G""` 标记。 -这是一个非常强大的调试工具,因为它让你定位所有影响代码中特定一行的commit。它甚至可以让你看到某一行是什么时候复制或者移动到另一个文件中去的。 +这是一个非常强大的调试工具,它能让你定位到所有影响代码中特定一行的commit。它甚至可以让你看到某一行是什么时候复制或者移动到另一个文件中去的。 ### 按范围 -你可以传入commit的返回来筛选在那个范围内的commit。这个范围由下面这样的格式指定,其中< since > 和< until >是commit的引用: +你可以传入范围来筛选commit。这个范围由下面这样的格式指定,其中< since > 和< until >是commit的引用: ``` git log .. @@ -241,7 +241,7 @@ git log .. git log master..feature ``` -其中的master..feature范围包含了在feature分支而不在feature分支中所有的commit。换句话说,这个命令可以看出从master分支Fork后feature分支发生了哪些变化。这可以像下面这样可视化: +其中的master..feature范围包含了在feature分支而不在feature分支中所有的commit。换句话说,这个命令可以看出从master分支Fork到feature分支后发生了哪些变化。它可以这样可视化: ![enter image description here](https://www.atlassian.com/git/images/tutorials/advanced/git-log/01.svg) @@ -249,7 +249,7 @@ git log master..feature ### 过滤出merge commit -`git log` 默认会在输出中包括merge commit。但是,如果你的团队采用强制合并策略(意思是merge上游修改你的分支而不是将你的分支rebase到上游分支),你的项目历史中会有很多外来的commit。 +`git log` 输出时默认包括merge commit。但是,如果你的团队采用强制合并策略(意思是merge上游修改你的分支而不是将你的分支rebase到上游分支),你的项目历史中会有很多外来的commit。 你可以通过`--no-merges` 标记来排除这些commit: @@ -270,4 +270,4 @@ git log --merges 你现在应该对使用`git log` 来格式化输出和选择你要显示的commit的用法比较熟悉了。它允许你查看你项目历史中任何需要的内容。 -这些技巧是你Git工具箱中重要的部分,不过注意`git log` 往往和其他Git命令连着使用。当你找到了你要的commit,你把它传给`git checkout` 、`git revert` 或是其他控制你提交历史的工具。所以,请不要停止继续学习Git的高级用法。 +这些技巧是你Git工具箱中重要的部分,不过注意`git log` 往往和其他Git命令连着使用。当你找到了你要的commit,你把它传给`git checkout` 、`git revert` 或是其他控制你提交历史的工具。所以,请继续坚持Git高级用法的学习。 diff --git a/Git图解.md b/sources/Git图解.md similarity index 100% rename from Git图解.md rename to sources/Git图解.md diff --git a/Git简易指南(上).md b/sources/Git简易指南(上).md similarity index 100% rename from Git简易指南(上).md rename to sources/Git简易指南(上).md diff --git a/Git钩子.md b/sources/Git钩子.md similarity index 99% rename from Git钩子.md rename to sources/Git钩子.md index ddac09e..6c78c7b 100644 --- a/Git钩子.md +++ b/sources/Git钩子.md @@ -300,7 +300,7 @@ session.quit() - 新的HEAD的引用 - 1或0,分别代表是分支checkout还是文件checkout。 -Python程序员经常遇到的问题是切换分支后那些之前生成的`.pyc` 文件。解释器有时使用`.pyc` 而不是`.py` 文件。为了避免起义,你可以在每次用`post-checkout` 切换到新的分支的时候,删除所有`.pyc` 文件。 +Python程序员经常遇到的问题是切换分支后那些之前生成的`.pyc` 文件。解释器有时使用`.pyc` 而不是`.py` 文件。为了避免歧义,你可以在每次用`post-checkout` 切换到新的分支的时候,删除所有`.pyc` 文件。 ``` #!/usr/bin/env python @@ -325,7 +325,7 @@ for root, dirs, files in os.walk('.'): os.unlink(os.path.join(root, filename)) ``` -钩子脚本当前的工作目录总是在仓库的根目录下,所以`os.walk('.')` 调用便利了仓库中所有文件。接下来,我们检查它的拓展名,如果是`.pyc` 就删除它。 +钩子脚本当前的工作目录总是在仓库的根目录下,所以`os.walk('.')` 调用遍历了仓库中所有文件。接下来,我们检查它的拓展名,如果是`.pyc` 就删除它。 通过`post-checkout` 钩子,你还可以根据你切换的分支来来更改工作目录。比如说,你可以在代码库外面使用一个插件分支来储存你所有的插件。如果这些插件需要很多二进制文件而其他分支不需要,你可以选择只在插件分支上build。 @@ -448,4 +448,4 @@ print "Moving '%s' from %s to %s" % (branch, old_commit, new_commit) 在这篇文章中,我们学习了如果用Git钩子来修改内部行为,当仓库中特定的事件发生时接受消息。钩子是存在于`git/hooks` 仓库中的普通脚本,因此也非常容易安装和定制。 -我们还看了一些常用的本地和服务端的钩子。这使得我们能够介入到整个开发生命周期中去。我们现在知道了如何在创建提交或推送的每个阶段执行自定义的操作。有了这些简单的脚本知识,你就可以对Git仓库为所欲为了 : ) 。 +我们还看了一些常用的本地和服务端的钩子。这使得我们能够介入到整个开发生命周期中去。我们现在知道了如何在创建提交或推送的每个阶段执行自定义的操作。有了这些简单的脚本知识,你就可以对Git仓库为所欲为了 : ) diff --git a/代码合并:Merge还是Rebase.md b/sources/代码合并:Merge还是Rebase.md similarity index 92% rename from 代码合并:Merge还是Rebase.md rename to sources/代码合并:Merge还是Rebase.md index 6aa4f53..ef4882f 100644 --- a/代码合并:Merge还是Rebase.md +++ b/sources/代码合并:Merge还是Rebase.md @@ -5,13 +5,13 @@ > > 这是一篇在[原文](https://www.atlassian.com/git/tutorials/merging-vs-rebasing)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。 -`git rebase` 这个命令经常被人认为是一种Git巫术,初学者应该避而远之。但如果使用得当的话,它能给你的团队开发省去太多烦恼。在这篇文章中,我们会比较`git rebase` 和类似的`git merge` 命令,找到Git工作流中所有可以使用rebase的机会。 +`git rebase` 这个命令经常被人认为是一种Git巫术,初学者应该避而远之。但如果使用得当的话,它能给你的团队开发省去太多烦恼。在这篇文章中,我们会比较`git rebase` 和类似的`git merge` 命令,找到Git工作流中rebase的所有用法。 概述 --- 你要知道的第一件事是,`git rebase` 和`git merge` 做的事其实是一样的。它们都被设计来将一个分支的更改并入另一个分支,只不过方式有些不同。 -想象一下,你刚开始在一个专门的分支上开发新功能,然后团队中另一个成员在master分支上添加了新的commit。这就会造成commit历史被Fork一份,这对于所有用Git来协作的开发者来说都很熟悉。 +想象一下,你刚创建了一个专门的分支开发新功能,然后团队中另一个成员在master分支上添加了新的commit。这就会造成提交历史被Fork一份,用Git来协作的开发者应该都很清楚。 ![enter image description here](https://www.atlassian.com/git/images/tutorials/advanced/merging-vs-rebasing/01.svg) @@ -19,13 +19,13 @@ ### Merge -将master分支合并到feature分支最简单的办法就是下面这些命令: +将master分支合并到feature分支最简单的办法就是用下面这些命令: ``` git checkout feature git merge master ``` -或者。你也可以把它们缩在一行里。 +或者。你也可以把它们压缩在一行里。 ``` git merge master feature ``` @@ -52,9 +52,9 @@ git rebase master ![enter image description here](https://www.atlassian.com/git/images/tutorials/advanced/merging-vs-rebasing/03.svg) -rebase最大的好处是你的项目历史会非常整洁。首先,它不像`git merge` 那样引入不必要的merge commit。其次,如上图所示,rebase导致最后的项目历史呈现出完美的线性——你可以从项目终点到起点浏览而不需要任何的Fork。这让你更容易使用 `git log` 、`git bisect` 和`gitk` 来查看项目历史。 +rebase最大的好处是你的项目历史会非常整洁。首先,它不像`git merge` 那样引入不必要的merge commit。其次,如上图所示,rebase导致最后的项目历史呈现出完美的线性——你可以从项目终点到起点浏览而不需要任何的Fork。这让你更容易使用`git log` 、`git bisect` 和`gitk` 来查看项目历史。 -不过,这种简单的commit历史会带来两个后果:安全性和可跟踪性。如果你违反了Rebase黄金法则,重写项目历史可能会给你的协作工作流带来灾难性的影响。以及rebase不会有merge commit中附带的信息——你看不到feature分支中并入了上游的哪些更改。 +不过,这种简单的commit历史会带来两个后果:安全性和可跟踪性。如果你违反了Rebase黄金法则,重写项目历史可能会给你的协作工作流带来灾难性的影响。此外,rebase不会有merge commit中附带的信息——你看不到feature分支中并入了上游的哪些更改。 ### 交互式的rebase @@ -102,7 +102,7 @@ Rebase的黄金法则 同步两个master分支的唯一办法是把它们merge到一起,导致一个额外的merge commit和两堆包含同样更改的commit。不用说,这会让人非常困惑。 -所以,在你运行`git rebase` 之前,一定要问问你自己“有没有别人正在这个分支上工作?”。如果答案就是有,那么把你的爪子放回去,重新找到一个无害的方式(如`git revert`)来提交你的更改。不如,你可以随心所欲地重写历史。 +所以,在你运行`git rebase` 之前,一定要问问你自己“有没有别人正在这个分支上工作?”。如果答案是有,那么把你的爪子放回去,重新找到一个无害的方式(如`git revert`)来提交你的更改。不如,你可以随心所欲地重写历史。 ### 强制push 如果你想把rebase之后的master分支push到远程仓库中去的话,Git会阻止你这么做,因为两个分支有冲突。但你可以传入`--force` 标记来强行push。就像下面一样: @@ -148,7 +148,7 @@ git rebase -i HEAD~3 git merge-base feature master ``` -交互式rebase是在你工作流中引入`git rebase` 的的好办法,因为它只影响本地分支。其他开发者只能看到你已经完成的结果,那就是一个非常正解、易于追踪的分支历史。 +交互式rebase是在你工作流中引入`git rebase` 的的好办法,因为它只影响本地分支。其他开发者只能看到你已经完成的结果,那就是一个非常整洁、易于追踪的分支历史。 但同样的,这只能用在私有分支上。如果你在同一个feature分支和其他开发者合作的话,这个分支是公开的,你不能重写这个历史。 @@ -178,7 +178,7 @@ By default, the git pull command performs a merge, but you can force it to integ ### 用Pull Request进行审查 -如果你将pull request作为你代码审查过程中的一换,你需要避免在创建pull request之后使用`git rebase`。只要你发起了pull request,其他开发者能看到你的代码,也就是说这个分支变成了公共分支。重写历史会造成Git和你的同事难以找到这个分支接下来的任何commit。 +如果你将pull request作为你代码审查过程中的一环,你需要避免在创建pull request之后使用`git rebase`。只要你发起了pull request,其他开发者能看到你的代码,也就是说这个分支变成了公共分支。重写历史会造成Git和你的同事难以找到这个分支接下来的任何commit。 来自其他开发者的任何更改都应该用`git merge` 而不是`git rebase` 来并入。 diff --git a/回滚命令Reset、Checkout、Revert辨析.md b/sources/回滚命令Reset、Checkout、Revert辨析.md similarity index 92% rename from 回滚命令Reset、Checkout、Revert辨析.md rename to sources/回滚命令Reset、Checkout、Revert辨析.md index e01bc92..92a51a5 100644 --- a/回滚命令Reset、Checkout、Revert辨析.md +++ b/sources/回滚命令Reset、Checkout、Revert辨析.md @@ -5,14 +5,14 @@ Reset、Checkout和Revert > > 这是一篇在[原文](https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。 -`git reset`、`git checkout`和`git revert`是你的Git工具箱中最有用的一些命令。它们都是用来撤销代码仓库中的某些更改,而前两个命令不仅可以作用于commit,还可以作用于特定文件。 +`git reset`、`git checkout`和`git revert`是你的Git工具箱中最有用的命令。它们都用来撤销代码仓库中的某些更改,而前两个命令不仅可以作用于commit,还可以作用于特定文件。 因为它们非常相似,所以我们经常会搞混,不知道什么场景下该用哪个命令。在这篇文章中,我们会比较`git reset`、`git checkout`和`git revert`最常见的用法。希望你在看完后能游刃有余地使用这些命令来管理你的仓库。 ![Git repo的主要组成](https://www.atlassian.com/git/images/tutorials/advanced/resetting-checking-out-and-reverting/01.svg) -Git仓库有三个主要组成——工作目录,stage缓存和commit历史。这张图有助于理解每个命令到底产生了哪些影响。当你阅读的时候,牢记这张图。 +Git仓库有三个主要组成——工作目录,stage缓存和提交历史。这张图有助于理解每个命令到底产生了哪些影响。当你阅读的时候,牢记这张图。 Commit层面的操作 -------------- @@ -20,7 +20,7 @@ Commit层面的操作 你传给`git reset`和`git checkout`的参数决定了它们的作用域。如果你没有包含文件路径,这些操作对所有commit生效。我们这一节要探讨的就是commit层面的操作。注意`git revert`没有文件层面的操作。 ###Reset -在commit层面上,reset将一个分支的末端指向另一个commit。这可以用来移除当前branch的一些commit。比如,下面这两条命令让hotfix分支向后回退了两个commit。 +在commit层面上,reset将一个分支的末端指向另一个commit。这可以用来移除当前分支的一些commit。比如,下面这两条命令让hotfix分支向后回退了两个commit。 ``` git checkout hotfix git reset HEAD~2 @@ -49,7 +49,7 @@ hotfix分支末端的两个commit现在变成了悬挂commit。也就是说, ``` git checkout hotfix ``` -上面这个命令做的不过是将HEAD移到一个新的分支,然后更新下工作目录。因为这可能会覆盖本地的修改,Git强制你commit或者stash工作目录中的所有更改,不如在checkout的时候这些更改都会丢失。不像`git reset`,`git checkout`没有移动这些分支。 +上面这个命令做的不过是将HEAD移到一个新的分支,然后更新工作目录。因为这可能会覆盖本地的修改,Git强制你commit或者stash工作目录中的所有更改,不如在checkout的时候这些更改都会丢失。不像`git reset`,`git checkout`没有移动这些分支。 ![将 HEAD 从 master 移到 hotfix](https://www.atlassian.com/git/images/tutorials/advanced/resetting-checking-out-and-reverting/04.svg) 除了分支之外,你还可以传入commit的引用来checkout到任意的commit。这和checkout到另一个分支是完全一样的:把HEAD移动到特定的commit。比如,下面这个命令会checkout到当前commit的祖父commit。 @@ -112,7 +112,7 @@ git checkout HEAD~2 foo.py ------- 你现在已经掌握了Git仓库中撤销更改的所有工具。`git reset`、`git checkout`、和 `git revert` 命令比较容易混淆,但当你想起它们工作目录、stage缓存和commit历史分别的影响,就会容易判断现在的情况下应该用那个命令。 -下面这个表格总结了这些命令最常用的使用场景。记得经常对照这个表格,毫无疑问在你的Git历程中你会用到好多次。 +下面这个表格总结了这些命令最常用的使用场景。记得经常对照这个表格,你使用Git时一定会经常用到。 |命令|作用域|常用情景| |---|---|---| diff --git a/wiki/about.md b/wiki/about.md new file mode 100644 index 0000000..b5ca5f4 --- /dev/null +++ b/wiki/about.md @@ -0,0 +1,19 @@ +git-recipes +==== +高质量的Git中文教程,来自国外社区的优秀文章和个人实践 + +目录 +--- +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中提出。 + +欢迎通过issue或者pr推荐你认为合适的资料,让这份菜单更充实一些。 diff --git a/wiki/catagory.md b/wiki/catagory.md new file mode 100644 index 0000000..5a7a580 --- /dev/null +++ b/wiki/catagory.md @@ -0,0 +1,69 @@ +**第1篇 Git** + + +**第2篇 从零搭建本地代码仓库** + + - **第1章** [快速指南](https://github.com/geeeeeeeeek/git-recipes/blob/master/Git%E7%AE%80%E6%98%93%E6%8C%87%E5%8D%97(%E4%B8%8A).md) + + 这节完全面向入门者。我假设你从零开始创建一个项目并且想用Git来进行版本控制,我们会讨论如何在你的个人项目中使用Git,比如如何初始化你的项目,如何管理新的或者已有的文件,如何在远端仓库中储存你的代码。 + + - **第2章** 创建代码仓库 + + - **第3章** 保存你的更改 + + - **第4章** 查看仓库状态 + + - **第5章** 查看以前的提交 + + - **第6章** 回滚错误的更改 + + - **第7章** 重写项目历史 + +**第3章 远程团队协作和管理** + + - **第1章** 快速指南 + + - **第2章** 同步代码 + + - **第3章** 创建Pull Request + + - **第4章** 使用分支 + + - **第5章** 几种工作流 + +**第4篇 Git命令详解** + + - 第1章 [图解Git命令](https://github.com/geeeeeeeeek/git-recipes/blob/master/Git%E5%9B%BE%E8%A7%A3.md) + + 如果你稍微理解git的工作原理,这篇文章能够让你理解的更透彻。 + +**第5篇 Git实用贴士** + + - **第1章** [代码合并:Merge、Rebase的选择](https://github.com/geeeeeeeeek/git-recipes/blob/master/%E4%BB%A3%E7%A0%81%E5%90%88%E5%B9%B6:Merge%E8%BF%98%E6%98%AFRebase.md) + + `git rebase` 和`git merge` 都是用来合并分支,只不过方式不太相同。`git rebase` 经常被人认为是一种Git巫术,初学者应该避而远之。但如果使用得当,它能省去太多烦恼。在这篇文章中,我们会通过比较找到Git工作流中所有可以使用rebase的机会。 + + - **第2章** [代码回滚:Reset、Checkout、Revert的选择](https://github.com/geeeeeeeeek/git-recipes/blob/master/%E5%9B%9E%E6%BB%9A%E5%91%BD%E4%BB%A4Reset%E3%80%81Checkout%E3%80%81Revert%E8%BE%A8%E6%9E%90.md) + + git reset、git checkout和git revert都是用来撤销代码仓库中的某些更改,所以我们经常弄混。在这篇文章中,我们比较最常见的用法,分析在什么场景下该用哪个命令。 + + - **第3章** [Git log高级用法](https://github.com/geeeeeeeeek/git-recipes/blob/master/Git_log%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95.md) + + 任何一个版本控制系统设计的目的都是为了记录你代码的变化——谁贡献了什么,找出bug是什么时候引入的,以及撤回一些有问题的更改。`git log` 可以格式化commit输出的形式,或过滤输出的commit从而找到项目中你需要的任何信息。 + + - **第4章** [Git钩子:自定义你的工作流](https://github.com/geeeeeeeeek/git-recipes/blob/master/Git%E9%92%A9%E5%AD%90.md) + + Git钩子是在Git仓库中特定事件发生时自动运行的脚本。它可以让你自定义Git内部的行为,在开始周期中的关键点触发自定义的行为,自动化或者优化你开发工作流中任意部分。 + + - **第5章** Git ref引用 + +**第6篇 Git应用实践:用GitLab搭建一个课程教学仓库** + + - **第1章** 教师和学生的最佳实践指南 + + GitLab本身的权限管理和组织结构已经满足了教学中课程创建、学生管理、收发作业、通知统计等需求。不过,在实践中我们要尤其注意各处的权限和命名规范。因此,我总结了一份教师和学生的最佳实践指南,保证各门课程能够顺畅地进行。 + - **第2章** 在上层搭建一个Classroom应用 + + 在实践中,我们要手动地导入大量学生、创建分支以及在Gitlab复杂的页面中穿梭。显然我们可以做得更好,那就是在GitLab上再搭建一层Classroom应用。在这章中,我会介绍我们是如何抽取需求,以及构建这个应用的。 + +