Update copyright notes.

This commit is contained in:
ZhongyiTong
2015-12-05 01:52:21 +08:00
parent 74c9b0dc59
commit 2903d8d614
11 changed files with 243 additions and 192 deletions

View File

@ -1,9 +1,8 @@
Git log高级用法
===
# Git log高级用法
> BY 童仲毅(geeeeeeeeek@github)
> BY 童仲毅([geeeeeeeeek@github](https://github.com/geeeeeeeeek/git-recipes/))
>
> 这是一篇在[原文](https://www.atlassian.com/git/tutorials/git-log)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。
> 这是一篇在[原文(BY atlassian)](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` 这个命令。
@ -11,8 +10,8 @@ Git log高级用法
`git log` 有两个高级用法一是自定义commit的输出格式二是过滤哪些commit要输出。这两个用法合二为一你就可以找到你项目中你需要的任何信息。
格式化Log输出
---
## 格式化Log输出
首先,这篇文章会展示几种`git log` 格式化输出的例子。大多数例子只是通过标记来向`git log` 请求或多或少的信息。
如果你不喜欢默认的`git log` 格式,你可以用`git config` 的别名功能来给你想要的格式创建一个快捷方式。
@ -21,12 +20,13 @@ Git log高级用法
`--oneline` 标记把每一个commit压缩到了一行中。它默认只显示commit ID和commit信息的第一行。一般来说`git log --oneline` 的输出是这样的:
```
```
0e25143 Merge branch 'feature'
ad8621a Fix a bug in the feature
16b36c6 Add a new feature
23ad9ad Add the initial code base
```
它对于获得你项目的大致情况很有帮助。
### Decorate
@ -35,7 +35,7 @@ ad8621a Fix a bug in the feature
这可以和另一个配置项一起使用。比如,执行`git log --oneline --decorate` 会将commit历史格式化成这样
```
```
0e25143 (HEAD, master) Merge branch 'feature'
ad8621a (feature) Fix a bug in the feature
16b36c6 Add a new feature
@ -52,7 +52,7 @@ ad8621a (feature) Fix a bug in the feature
`--stat` 选项显示每次commit的文件增删数量注意修改一行记作增加一行且删去一行当你想要查看commit引入的变化时这会非常有用。比如说下面这个commit在hello.py文件中增加了67行删去了38行。
```
```
commit f2a238924e89ca1d4947662928218a06d39068c3
Author: John <john@example.com>
Date: Fri Jun 25 17:30:28 2014 -0500
@ -62,10 +62,10 @@ Date: Fri Jun 25 17:30:28 2014 -0500
hello.py | 105 ++++++++++++++++++++++++-----------------
1 file changed, 67 insertion(+), 38 deletions(-)
```
文件名后面+和-的数量是这个commit造成的更改中增删的相对比例。它给你一个直观的感觉关于这次commit有多少改动。如果你想知道每次commit删改的绝对数量你可以将`-p` 选项传入`git log` 。这样commit所有的删改都会被输出
```
```
commit 16b36c697eb2d24302f89aa22d9170dfe609855b
Author: Mary <mary@example.com>
Date: Fri Jun 25 17:31:57 2014 -0500
@ -84,11 +84,12 @@ index 18ca709..c673b40 100644
对于改动很多的commit来说这个输出会变得又长又大。一般来说当你输出所有删改的时候你应该是想要查找某一具体的改动这时你就要用到`pickaxe` 选项。
### Shortlog
`git shortlog` 是一种特别的`git log` 它是为创建发布声明设计的。它把每个commit按作者分类显示commit信息的第一行。这样可以容易地看到谁做了什么。
比如说两个开发者为项目贡献了5个commit那么`git shortlog` 输出会是这样的:
```
```
Mary (2):
Fix a bug in the feature
Fix a serious security hole in our framework
@ -98,12 +99,14 @@ John (3):
Add a new feature
Merge branch 'feature'
```
默认情况下,`git shortlog` 把输出按作者名字排序,但你可以传入`-n` 选项来按每个作者commit数量排序。
### Graph
`--graph` 选项绘制一个ASCII图像来展示commit历史的分支结构。它经常和 `--oneline` 和 `--decorate` 两个命令一起使用这样会更容易查看哪个commit属于哪个分支
```
```
git log --graph --oneline --decorate
For a simple repository with just 2 branches, this will produce the following:
@ -127,7 +130,7 @@ For a simple repository with just 2 branches, this will produce the following:
比如,下面命令中的`%cn`、`%h` 和`%cd` 这三种占位符会被分别替换为作者名字、缩略标识和提交日期。
```
```
git log --pretty=format:"%cn committed %h on %cd"
This results in the following format for each commit:
@ -141,43 +144,47 @@ John committed f12ca28 on Wed Jun 22 13:50:31 2014 -0500
除了让你只看到关注的信息,这个`--pretty=format:"<string>"` 选项在你想要在另一个命令中使用日志内容是尤为有用的。
过滤提交历史
---
## 过滤提交历史
格式化commit输出只是`git log` 其中的一个用途。另一半是理解如何浏览整个提交历史。接下来的文章会介绍如何用`git log` 选择项目历史中的特定的commit。所有的用法都可以和上面讨论过的格式化选项结合起来。
### 按数量
`git log` 最基础的过滤选项是限制显示的commit数量。当你只对最近几次commit感兴趣时它可以节省你一页一页查看的时间。
你可以在后面加上`-<n>`选项。比如说下面这个命令会显示最新的3次commit
```
```
git log -3
```
### 按日期
如果你想要查看某一特定时间段内的commit你可以使用`--after` 或 `--before` 标记来按日期筛选。它们都接受好几种日期格式作为参数。比如说下面的命令会显示2014年7月1日后的commit
```
```
git log --after="2014-7-1"
```
你也可以传入相对的日期,比如一周前("`1 week ago`")或者昨天("`yesterday`"
```
```
get log --after="yesterday"
```
你可以同时提供`--before` 和 `--after` 来检索两个日期之间的commit。比如为了显示2014年7月1日到2014年7月4日之间的commit你可以这么写
```
```
git log --after="2014-7-1" --before="2014-7-4"
```
注意`--since` 、`--until` 标记和`--after` 、`--before` 标记分别是等价的。
### 按作者
当你只想看某一特定作者的commit的时候你可以使用`--author` 标记。它接受正则表达式返回所有作者名字满足这个规则的commit。如果你知道那个作者的确切名字你可以直接传入文本字符串
```
```
git log --author="John"
```
@ -185,7 +192,7 @@ git log --author="John"
你也可以用正则表达式来创建更复杂的检索。比如下面这个命令检索名叫Mary或John的作者的commit。
```
```
git log --author="John\|Mary"
```
@ -199,7 +206,7 @@ git log --author="John\|Mary"
比如说你的团队规范要求在提交信息中包括相关的issue编号你可以用下面这个命令来显示这个issue相关的所有commit
```
```
git log --grep="JRA-224:"
```
@ -209,7 +216,7 @@ git log --grep="JRA-224:"
很多时候,你只对某个特定文件的更改感兴趣。为了显示某个特定文件的历史,你只需要传入文件路径。比如说,下面这个命令返回所有和`foo.py` 和`bar.py` 文件相关的commit
```
```
git log -- foo.py bar.py
```
@ -219,7 +226,7 @@ git log -- foo.py bar.py
我们还可以根据源代码中某一行的增加和删除来搜索commit。这被称为pickaxe它接受形如`-S"<string>"` 的参数。比如说,当你想要知道`Hello, World!` 字符串是什么时候加到项目中哪个文件中去的,你可以使用下面这个命令:
```
```
git log -S "Hello, World!"
```
@ -231,13 +238,13 @@ git log -S "Hello, World!"
你可以传入范围来筛选commit。这个范围由下面这样的格式指定其中< since > 和< until >是commit的引用
```
```
git log <since>..<until>
```
这个命令在你使用分支引用作为参数时特别有用。这是一个显示两个分支之间区别最简单的方式。看看下面这个命令:
```
```
git log master..feature
```
@ -253,21 +260,20 @@ git log master..feature
你可以通过`--no-merges` 标记来排除这些commit
```
```
git log --no-merges
```
另一方面如果你只对merge commit感兴趣你可以使用`--merges` 标记:
```
```
git log --merges
```
它会返回所有有两个父节点的commit。
总结
---
## 总结
你现在应该对使用`git log` 来格式化输出和选择你要显示的commit的用法比较熟悉了。它允许你查看你项目历史中任何需要的内容。
这些技巧是你Git工具箱中重要的部分不过注意`git log` 往往和其他Git命令连着使用。当你找到了你要的commit你把它传给`git checkout``git revert` 或是其他控制你提交历史的工具。所以请继续坚持Git高级用法的学习。
这些技巧是你Git工具箱中重要的部分不过注意`git log` 往往和其他Git命令连着使用。当你找到了你要的commit你把它传给`git checkout` 、`git revert` 或是其他控制你提交历史的工具。所以请继续坚持Git高级用法的学习。

View File

@ -1,43 +1,48 @@
Git图解
========
# Git图解
> BY 童仲毅(geeeeeeeeek@github)
> BY 童仲毅([geeeeeeeeek@github](https://github.com/geeeeeeeeek/git-recipes/))
>
> 这是一篇在[原文](http://marklodato.github.io/visual-git-guide/index-zh-cn.html)基础上演绎的文章。原作者[Mark Lodato](lodatom@gmail.com),译者[wych](ellrywych@gmail.com)。原文采用[创用CC 姓名标示-非商业性-相同方式分享3.0 美国授权条款](https://creativecommons.org/licenses/by-nc-sa/3.0/us/)授权。
此页图解git中的最常用命令。如果你稍微理解git的工作原理这篇文章能够让你理解的更透彻。
基本用法
---------
## 基本用法
![enter image description here](http://marklodato.github.io/visual-git-guide/basic-usage.svg)
上面的四条命令在工作目录、stage缓存(也叫做索引)和commit历史之间复制文件。
* `git add files` 把工作目录中的文件加入stage缓存
* `git commit` 把stage缓存生成一次commit并加入commit历史
* `git reset -- files` 撤销最后一次`git add files`,你也可以用`git reset` 撤销所有stage缓存文件
* `git checkout -- files` 把文件从stage缓存复制到工作目录用来丢弃本地修改
* `git add files` 把工作目录中的文件加入stage缓存
* `git commit` 把stage缓存生成一次commit并加入commit历史
* `git reset -- files` 撤销最后一次`git add files`,你也可以用`git reset` 撤销所有stage缓存文件
* `git checkout -- files` 把文件从stage缓存复制到工作目录用来丢弃本地修改
你可以用 `git reset -p``git checkout -p``git add -p`进入交互模式也可以跳过stage缓存直接从commit历史取出文件或者直接提交代码。
![enter image description here](http://marklodato.github.io/visual-git-guide/basic-usage-2.svg)
* `git commit -a ` 相当于运行`git add`把所有当前目录下的文件加入stage缓存再运行`git commit`
* `git commit files` 进行一次包含最后一次提交加上工作目录中文件快照的提交并且文件被添加到stage缓存。
* `git checkout HEAD -- files` 回滚到复制最后一次提交。
* `git commit -a ` 相当于运行`git add`把所有当前目录下的文件加入stage缓存再运行`git commit`
* `git commit files` 进行一次包含最后一次提交加上工作目录中文件快照的提交并且文件被添加到stage缓存。
* `git checkout HEAD -- files` 回滚到复制最后一次提交。
## 约定
约定
--------
后文中以下面的形式使用图片:
![enter image description here](http://marklodato.github.io/visual-git-guide/conventions.svg)
绿色的5位字符表示提交的ID分别指向父节点。分支用橙色显示分别指向特定的提交。当前分支由附在其上的_HEAD_标识。
这张图片里显示最后5次提交_ed489_是最新提交。 _master_分支指向此次提交另一个_maint_分支指向祖父提交节点。
命令详解
---------
## 命令详解
### Diff
有许多种方法查看两次提交之间的变动,下面是其中一些例子。
![enter image description here](http://marklodato.github.io/visual-git-guide/diff.svg)
### Commit
@ -45,13 +50,19 @@ Git图解
提交时git用stage缓存中的文件创建一个新的提交并把此时的节点设为父节点。然后把当前分支指向新的提交节点。下图中当前分支是_master_。
在运行命令之前_master_指向_ed489_提交后_master_指向新的节点_f0cec_并以_ed489_作为父节点。
![enter image description here](http://marklodato.github.io/visual-git-guide/commit-master.svg)
即便当前分支是某次提交的祖父节点git会同样操作。下图中在_master_分支的祖父节点_maint_分支进行一次提交生成了_1800b_。
这样_maint_分支就不再是_master_分支的祖父节点。此时[merge](#merge) 或者 [rebase](#rebase) 是必须的。
![enter image description here](http://marklodato.github.io/visual-git-guide/commit-maint.svg)
如果想更改一次提交,使用 `git commit --amend`。git会使用与当前提交相同的父节点进行一次新提交旧的提交会被取消。
![enter image description here](http://marklodato.github.io/visual-git-guide/commit-amend.svg)
另一个例子是[分离HEAD提交](#detached),在后面的章节中介绍。
### Checkout
@ -59,19 +70,29 @@ Git图解
checkout命令用于从历史提交或者stage缓存中拷贝文件到工作目录也可用于切换分支。
当给定某个文件名(或者打开-p选项或者文件名和-p选项同时打开git会从指定的提交中拷贝文件到stage缓存和工作目录。比如`git checkout HEAD~ foo.c`会将提交节点_HEAD~_即当前提交节点的父节点中的`foo.c`复制到工作目录并且加到stage缓存中。如果命令中没有指定提交节点则会从stage缓存中拷贝内容。注意当前分支不会发生变化。
![enter image description here](http://marklodato.github.io/visual-git-guide/checkout-files.svg)
当不指定文件名而是给出一个本地分支时那么_HEAD_标识会移动到那个分支也就是说我们“切换”到那个分支了然后stage缓存和工作目录中的内容会和_HEAD_对应的提交节点一致。新提交节点下图中的a47c3中的所有文件都会被复制到stage缓存和工作目录中只存在于老的提交节点ed489中的文件会被删除不属于上述两者的文件会被忽略不受影响。
![enter image description here](http://marklodato.github.io/visual-git-guide/checkout-branch.svg)
如果既没有指定文件名也没有指定分支名而是一个标签、远程分支、SHA-1值或者是像_master~3_类似的东西就得到一个匿名分支称作_detached HEAD_被分离的_HEAD_标识。这样可以很方便地在历史版本之间互相切换。比如说你想要编译1.6.6.1版本的git你可以运行`git checkout v1.6.6.1`(这是一个标签,而非分支名),编译,安装,然后切换回另一个分支,比如说`git checkout master`。然而当提交操作涉及到“分离的HEAD”时其行为会略有不同详情见在[下面](#detached)。
![enter image description here](http://marklodato.github.io/visual-git-guide/checkout-detached.svg)
### HEAD标识处于分离状态时的提交操作
当_HEAD_处于分离状态不依附于任一分支提交操作可以正常进行但是不会更新任何已命名的分支。你可以认为这是在更新一个匿名分支。
![enter image description here](http://marklodato.github.io/visual-git-guide/commit-detached.svg)
一旦此后你切换到别的分支比如说_master_那么这个提交节点可能再也不会被引用到然后就会被丢弃掉了。注意这个命令之后就不会有东西引用_2eecb_。
![enter image description here](http://marklodato.github.io/visual-git-guide/checkout-after-detached.svg)
但是,如果你想保存这个状态,可以用命令`git checkout -b name`来创建一个新的分支。
![enter image description here](http://marklodato.github.io/visual-git-guide/checkout-b-detached.svg)
### Reset
@ -79,10 +100,15 @@ checkout命令用于从历史提交或者stage缓存中拷贝文件到工
reset命令把当前分支指向另一个位置并且有选择的变动工作目录和索引。也用来在从历史commit历史中复制文件到索引而不动工作目录。
如果不给选项,那么当前分支指向到那个提交。如果用`--hard`选项,那么工作目录也更新,如果用`--soft`选项,那么都不变。
![enter image description here](http://marklodato.github.io/visual-git-guide/reset-commit.svg)
如果没有给出提交点的版本号那么默认用_HEAD_。这样分支指向不变但是索引会回滚到最后一次提交如果用`--hard`选项,工作目录也同样。
![enter image description here](http://marklodato.github.io/visual-git-guide/reset.svg)
如果给了文件名(或者 `-p`选项), 那么工作效果和带文件名的[checkout](#checkout)差不多,除了索引被更新。
![enter image description here](http://marklodato.github.io/visual-git-guide/reset-files.svg)
### Merge
@ -90,13 +116,17 @@ reset命令把当前分支指向另一个位置并且有选择的变动工作
merge 命令把不同分支合并起来。合并前,索引必须和当前提交相同。如果另一个分支是当前提交的祖父节点,那么合并命令将什么也不做。
另一种情况是如果当前提交是另一个分支的祖父节点就导致_fast-forward_合并。指向只是简单的移动并生成一个新的提交。
![enter image description here](http://marklodato.github.io/visual-git-guide/merge-ff.svg)
否则就是一次真正的合并。默认把当前提交(_ed489_ 如下所示)和另一个提交(_33104_)以及他们的共同祖父节点(_b325c_)进行一次[三方合并](http://en.wikipedia.org/wiki/Three-way_merge)。结果是先保存当前目录和索引然后和父节点_33104_一起做一次新提交。
![enter image description here](http://marklodato.github.io/visual-git-guide/merge.svg)
### Cherry Pick
cherry-pick命令"复制"一个提交节点并在当前分支做一次完全一样的新提交。
![enter image description here](http://marklodato.github.io/visual-git-guide/cherry-pick.svg)
### Rebase
@ -104,10 +134,13 @@ cherry-pick命令"复制"一个提交节点并在当前分支做一次完全一
rebase是合并命令的另一种选择。合并把两个父分支合并进行一次提交提交历史不是线性的。rebase在当前分支上重演另一个分支的历史提交历史是线性的。
本质上,这是线性化的自动的 [cherry-pick](#cherry-pick)。
![enter image description here](http://marklodato.github.io/visual-git-guide/rebase.svg)
上面的命令都在_topic_分支中进行而不是_master_分支在_master_分支上重演并且把分支指向新的节点。注意旧提交没有被引用将被回收。
要限制回滚范围,使用`--onto`选项。下面的命令在_master_分支上重演当前分支从_169a6_以来的最近几个提交即_2c33a_。
![enter image description here](http://marklodato.github.io/visual-git-guide/rebase-onto.svg)
同样有`git rebase --interactive`让你更方便的完成一些复杂操作,比如丢弃、重排、修改、合并提交。
同样有`git rebase --interactive`让你更方便的完成一些复杂操作,比如丢弃、重排、修改、合并提交。

View File

@ -1,9 +1,8 @@
Git提交引用和引用日志
===
# Git提交引用和引用日志
> BY 童仲毅(geeeeeeeeek@github)
> BY 童仲毅([geeeeeeeeek@github](https://github.com/geeeeeeeeek/git-recipes/))
>
> 这是一篇在[原文](https://www.atlassian.com/git/tutorials/refs-and-the-reflog)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。
> 这是一篇在[原文(BY atlassian)](https://www.atlassian.com/git/tutorials/refs-and-the-reflog)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。
提交(commit)是Git的精髓所在你无时不刻不在创建和缓存提交、查看以前的提交或者用各种Git命令在仓库间转移你的提交。大多数的命令都对同一个提交操作而有些会接受提交的引用作为参数。比如你可以给`git checkout` 传入一个引用来查看以前的提交,或者传入一个分支名来切换到对于的分支。
@ -13,12 +12,11 @@ Git提交引用和引用日志
我们还会学到如何使用Git的引用日志查看看似已经删除的提交。
哈希字串
---
## 哈希字串
引用一个提交最直接的方式是通过SHA-1的哈希字串这是每个提交唯一的ID。你可以在`git log`的输出中找到提交的哈希字串。
```
```
commit 0c708fdec272bc4446c6cabea4f0022c2b616eba
Author: Mary Johnson <mary@example.com>
Date: Wed Jul 9 16:37:42 2014 -0500
@ -28,26 +26,25 @@ Date: Wed Jul 9 16:37:42 2014 -0500
在Git命令中传递时你只需要提供足以确定那个提交的哈希子串即可。比如你可以这样用`git show`的命令显示上面的提交:
```
```
git show 0c708f
```
有时,我们需要把分支、标签或者其他间接的引用转变成对应提交的哈希。`git rev-parse`命令正是你需要的。下面这个命令返回master分支提交的哈希字串
```
```
git rev-parse master
```
当你写的自定义脚本中需要将提交引用作为参数时,这个命令非常有用。你可以让`git rev-parse`帮你处理转换,而不用手动做这件事。
引用
---
## 引用
ref是提交的间接引用。你可以把它当做哈希字串的别名但对用户更友好。这就是Git内部表示分支和标签的机制。
引用以一段普通的文本存在于`.git/refs`目录中,就是我们平时说的那个`.git`。你要去`.git/refs`文件夹查看仓库中的引用。你可以看到下面这样的结构,但具体的文件取决于你的仓库中有什么分支和标签,以及你的远程仓库。
```
```
.git/refs/
heads/
master
@ -61,7 +58,7 @@ ref是提交的间接引用。你可以把它当做哈希字串的别名
`heads`目录定义了你本地仓库中的所有分支。每一个文件名和你的分支名一一对应文件中包含一个提交的哈希字串。这个就是分支顶端的所在位置。为了验证这一点试试在Git根目录运行下面这两个命令
```
```
# Output the contents of `refs/heads/master` file:
cat .git/refs/heads/master
@ -77,16 +74,17 @@ git log -1 master
`tags`目录也是以相同的方式存储,只不过其中存的是标签而不是分支。`remotes`目录将你之前用`git remote`命令创建的所有远程仓库以子目录的形式一一列出。在每个文件夹中你可以找到所有fetch到本地仓库的远程分支。
###指定引用
### 指定引用
当你向Git命令传入引用的时候你既可以指定引用完整的名称也可以使用缩写然后让Git来寻找匹配。你应该已经对引用的缩写很熟悉了每次你通过名称引用分支的时候都会这么做。
```
```
git show some-feature
```
这里的`some-feature`参数其实是分支名的缩写。Git在使用前将它解析成`refs/heads/some-feature`。你也可以在命令行中指定引用的全称,就像这样:
```
```
git show refs/heads/some-feature
```
@ -94,18 +92,17 @@ git show refs/heads/some-feature
我们会在refspec一节见到更多引用名称。
打包引用目录
---
## 打包引用目录
对于大型仓库Git会周期性地执行垃圾回收来移除不需要的对象将所有引用文件压缩成单个文件来获得更好的性能。你可以使用这个命令强制垃圾回收来执行压缩
```
```
git gc
```
这个命令把`refs`文件夹中所有单独的分支和标签移动到了`.git`根目录下的`packed-refs`文件中。如果你打开这个文件,你会发现提交的哈希字串和引用之间的映射关系:
```
```
00f54250cf4e549fdfcafe2cf9a2c90bc3800285 refs/heads/feature
0e25143693cfe9d5c2e83944bbaf6d3c4505eb17 refs/heads/master
bb883e4c91c870b5fed88fd36696e752fb6cf8e6 refs/tags/v0.9
@ -113,22 +110,21 @@ bb883e4c91c870b5fed88fd36696e752fb6cf8e6 refs/tags/v0.9
另一方面正常的Git功能不会受到任何影响。但如果你好奇你的`.git/refs`文件夹为什么是空的,这一节告诉你了答案。
特殊的引用
---
## 特殊的引用
除了`refs`文件夹外,`.git`根目录还有一些特殊的引用。如下所示:
- HEAD 当前所在的提交或分支。
- FETCH_HEAD 远程仓库中fetch到的最新一次提交。
- ORIG_HEAD HEAD的备份引用避免损坏。
- MERGE_HEAD 你通过`git merge`并入当前分支的引用(们)。
- CHERRY_PICK_HEAD `cherry pick`使用的引用。
- HEAD 当前所在的提交或分支。
- FETCH_HEAD 远程仓库中fetch到的最新一次提交。
- ORIG_HEAD HEAD的备份引用避免损坏。
- MERGE_HEAD 你通过`git merge`并入当前分支的引用(们)。
- CHERRY_PICK_HEAD 你`cherry pick`使用的引用。
这些引用s由Git在需要时创建和更新。比如说`git pull`命令首先运行`git fetch`,而`FETCH_HEAD `引用随之改变。然后,它运行`git merge FETCH_HEAD`来将fetch到的分支最终并入仓库。当然你也可以使用其他任何引用因为我相信你已经对`HEAD`很熟悉了。
这些文件包含的内容取决于它们的类型和你的仓库状态。`HEAD` 引用可以包含符号链接指向另一个引用而不是哈希字串或是提交的哈希字串。比如说看看当你在master分支上时`HEAD`的内容:
```
```
git checkout master
cat .git/HEAD
```
@ -138,36 +134,38 @@ cat .git/HEAD
在大多数情况下,`HEAD`是你唯一用得到的引用。其它引用一般只在写底层脚本接触到Git内部的工作机制时才会用到。
refspec
---
## refspec
refspec将本地分支和远程分支对应起来。我们可以通过它用本地的Git命令管理远程分支设置一些高级的`git push`和`git fetch`行为。
refspec的定义是这样的`[+]<src>:<dst>`。`<src>`参数是本地的源分支,`<dst>`是远程的目标分支。可选的`+`号强制远程仓库采用非快速向前的更新策略。
refspec可以和`git push`一起使用用来指定远程的分支的名称。比如下面这个命令将master分支push到远程origin就像一般的`git push`一样但它使用qa-master作为远程仓库中的分支名。对于QA团队来说这个方法非常有用。
```
```
git push origin master:refs/heads/qa-master
```
你也可以用refspec来删除远程分支。feature分支的工作流经常会遇到这种情况将feature分支push到远程仓库中比如说为了备份。你删除本地的feature分支之后远程的feature分支依然存在虽然现在我们已经不再需要它。你可以push一个`<src>`参数为空的refspec来删除它们就像这样
```
```
git push origin :some-feature
```
这非常方便因为你不需要登陆到你的远程仓库然后手动删除这些远程分支。注意在Git v1.7.0之后你可以用`--delete`标记代替上面这个方法。下面这个命令和上面的命令作用相同:
```
```
git push origin --delete some-feature
```
在Git配置文件中增加几行你就可以更改`git fetch`的行为。默认地,`git fetch`会fetch远程仓库中所有分支。原因就是因为`.git/config`文件的这段配置:
```
```
[remote "origin"]
url = https://git@github.com:mary/example-repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
@ -175,7 +173,7 @@ git push origin --delete some-feature
fetch这一行告诉`git fetch`从origin仓库中下载所有分支。但是一些工作流不需要所有分支。比如很多持续集成工作流只关心master分支。为了做到这一点我们需要将fetch这行改成下面这样
```
```
[remote "origin"]
url = https://git@github.com:mary/example-repo.git
fetch = +refs/heads/master:refs/remotes/origin/master
@ -183,7 +181,7 @@ fetch这一行告诉`git fetch`从origin仓库中下载所有分支。但是
你还可以类似地修改`git push`的配置。比如如果你总是将master分支push到origin仓库的qa-master分支就像我们之前做的一样你要把配置文件改成这样
```
```
[remote "origin"]
url = https://git@github.com:mary/example-repo.git
fetch = +refs/heads/master:refs/remotes/origin/master
@ -192,12 +190,11 @@ fetch这一行告诉`git fetch`从origin仓库中下载所有分支。但是
refspec给了你完全的掌控权可以定制Git命令如何在仓库之间转移分支。你可以重命名或是删除你的本地分支fetch或是push不同的分支名修改`git push`和`git fetch`的设置,只对你想要的分支进行操作。
相对引用
---
## 相对引用
你还可以通过提交之间的相对关系来引用。`~`符号让你访问父节点的提交。比如说,下面这个命令显示`HEAD`祖父节点的提交:
```
```
git show HEAD~2
```
@ -205,13 +202,13 @@ git show HEAD~2
`~`符号总是选择合并提交的第一个父节点。如果你想选择其他父节点,你需要用`^`符号来指定。比如说,`HEAD`是一个合并提交,下面这个命令返回`HEAD`的第二个父节点:
```
```
git show HEAD^2
```
你可以使用不止一个`^`来查看超过一层的节点。比如,下面的命令显示的是`HEAD`的祖父节点,也就是`HEAD`第二个父节点的父节点。
```
```
git show HEAD^2^1
```
@ -222,7 +219,8 @@ git show HEAD^2^1
相对引用在命令中的用法和普通的引用相同。比如,下面所有命令中使用的都是相对引用:
```
```
# Only list commits that are parent of the second parent of a merge commit
git log HEAD^2
@ -233,12 +231,11 @@ git reset HEAD~3
git rebase -i HEAD~3
```
引用日志
---
## 引用日志
引用日志是Git的安全网。它记录了你在仓库中做的所有更改不管你有没有提交。你也可以认为这是你本地更改的完整历史记录。运行`git reflog`命令查看引用日志。它应该会打印出像下面这样的信息:
```
```
400e4b7 HEAD@{0}: checkout: moving from master to HEAD~2
0e25143 HEAD@{1}: commit (amend): Integrate some awesome feature into `master`
00f5425 HEAD@{2}: commit (merge): Merge branch ';feature';
@ -247,16 +244,16 @@ ad8621a HEAD@{3}: commit: Finish the feature
说人话就是:
- 你刚刚切换到`HEAD~2`
- 你刚刚修改了一个提交信息
- 你刚刚把feature分支合并到了master分支
- 你刚刚提交了一份缓存
- 你刚刚切换到`HEAD~2`
- 你刚刚修改了一个提交信息
- 你刚刚把feature分支合并到了master分支
- 你刚刚提交了一份缓存
`HEAD{<n>}`语法允许你引用保存在日志中的提交。这和上一节的`HEAD~<n>`引用差不多,不过`<n> `指的是引用日志中的对象,而不是提交历史。
你可以用办法回到之前可能已经丢失的状态。比如,你刚刚用`git reset`方法粉碎了新的feature分支。你的引用日志看上去可能会是这样的
```
```
ad8621a HEAD@{0}: reset: moving to HEAD~3
298eb9f HEAD@{1}: commit: Some other commit message
bbe9012 HEAD@{2}: commit: Continue the feature
@ -265,14 +262,13 @@ bbe9012 HEAD@{2}: commit: Continue the feature
`git reset`前的三个提交现在都成了悬挂的了,也就是说除了引用日志之外没有办法再引用到它们。现在,假设你意识到了你不应该丢掉你全部的工作。你只需要切换到`HEAD@{1}`这个提交就能回到你运行`git reset`之前仓库的状态。
```
```
git checkout HEAD@{1}
```
这会让你处于`HEAD`分离的状态。你可以从这里开始,创建新的分支,继续你的工作。
总结
---
## 总结
你现在对Git提交的引用应该已经相当熟悉了。我们知道了分支和标签是如何存在于`.git`的子文件夹refs中如何读取打包的引用文件如何使用refspec来进行更高级的push和fetch操作如何使用`~`和`^`符号来遍历分支结构。

View File

@ -1,7 +1,6 @@
Git简易指南(上)
===========
# Git简易指南(上)
> BY 童仲毅(geeeeeeeeek@github)
> BY 童仲毅([geeeeeeeeek@github](https://github.com/geeeeeeeeek/git-recipes/))
>
> 除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。[git-guide](https://github.com/rogerdudler/git-guide/) 项目对本文亦有贡献。
@ -9,68 +8,86 @@ Git简易指南(上)
在这节中我会介绍如何在你的个人项目中使用Git我们会讨论Git最基本的操作——如何初始化你的项目如何管理新的或者已有的文件如何在远端仓库中储存你的代码。
安装Git
---------
- Mac用户Xcode Command Line Tools自带Git (`xcode-select --install` )
- Linux用户`sudo apt-get install git`
- Windows用户下载[Git SCM](git-for-windows.github.io)
- 对于Windows用户安装后如果希望在全局的cmd中使用git需要把git.exe加入PATH环境变量中或在Git Bash中使用Git。
## 安装Git
- Mac用户Xcode Command Line Tools自带Git (`xcode-select --install` )
- Linux用户`sudo apt-get install git`
- Windows用户下载[Git SCM](git-for-windows.github.io)
```
- 对于Windows用户安装后如果希望在全局的cmd中使用git需要把git.exe加入PATH环境变量中或在Git Bash中使用Git。
```
## 检出仓库
检出仓库
----
执行如下命令以创建一个本地仓库的克隆版本:
`git clone /path/to/repository`
如果是远端服务器上的仓库,你的命令会是这个样子:
`git clone username@host:/path/to/repository` 通过SSH
或者:
`git clone https:/path/to/repository.git` 通过https
比如说`git clone https://github.com/geeeeeeeeek/git-recipes.git`可以将git教程clone到你指定的目录。
创建新仓库
--------
## 创建新仓库
创建新文件夹,打开,然后执行 `git init`以创建新的 git 仓库。
> 下面每一步中,你都可以通过`git status`来查看你的git仓库状态。
工作流
---
## 工作流
你的本地仓库由 git 维护的三棵“树”组成。第一个是你的 `工作目录`,它持有实际文件;第二个是 `缓存区(Index)`,它像个缓存区域,临时保存你的改动;最后是 `HEAD`,指向你最近一次提交后的结果。
![enter image description here](http://www.bootcss.com/p/git-guide/img/trees.png)
> 事实上第三个阶段是commit history的图。HEAD一般是指向最新一次commit的引用。现在暂时不必究其细节。
添加与提交
----
## 添加与提交
你可以计划改动(把它们添加到缓存区),使用如下命令:
```
```
git add < filename >
git add *
```
这是 git 基本工作流程的第一步。使用如下命令以实际提交改动:
```
```
git commit -m "代码提交信息"
```
现在,你的改动已经提交到了 HEAD但是还没到你的远端仓库。
> 在开发时良好的习惯是根据工作进度及时commit并务必注意附上有意义的commit message。创建完项目目录后第一次提交的commit message一般为"Initial commit."。
推送改动
---
## 推送改动
你的改动现在已经在本地仓库的 HEAD 中了。执行如下命令以将这些改动提交到远端仓库:
```
```
git push origin master
```
可以把 master 换成你想要推送的任何分支。
如果你还没有克隆现有仓库,并欲将你的仓库连接到某个远程服务器,你可以使用如下命令添加:
```
```
git remote add origin <server>
```
如此你就能够将你的改动推送到所添加的服务器上去了。
> - 这里origin是< server >的别名取什么名字都可以你也可以在push时将< server >替换为origin。但为了以后push方便我们第一次一般都会先remote add。
> - 如果你还没有git仓库可以在Github等代码托管平台上创建一个空(不要自动生成README.md)的repository然后将代码push到远端仓库。
> - 这里origin是< server >的别名取什么名字都可以你也可以在push时将< server >替换为origin。但为了以后push方便我们第一次一般都会先remote add。
> - 如果你还没有git仓库可以在Github等代码托管平台上创建一个空(不要自动生成README.md)的repository然后将代码push到远端仓库。
##### 至此,你应该可以顺利地提交你的项目了。在下一节中,我们将涉及更多的命令,来完成更有用的操作。比如从远端的仓库拉取更新并且合并到你的本地,如何通过分支多人协作,如何处理不同分支的冲突等等。
##### 至此,你应该可以顺利地提交你的项目了。在下一节中,我们将涉及更多的命令,来完成更有用的操作。比如从远端的仓库拉取更新并且合并到你的本地,如何通过分支多人协作,如何处理不同分支的冲突等等。

View File

@ -1,9 +1,8 @@
Git钩子
===
# Git钩子
> BY 童仲毅(geeeeeeeeek@github)
> BY 童仲毅([geeeeeeeeek@github](https://github.com/geeeeeeeeek/git-recipes/))
>
> 这是一篇在[原文](https://www.atlassian.com/git/tutorials/git-hooks)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。
> 这是一篇在[原文(BY atlassian)](https://www.atlassian.com/git/tutorials/git-hooks)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。
Git钩子是在Git仓库中特定事件发生时自动运行的脚本。它可以让你自定义Git内部的行为在开始周期中的关键点触发自定义的行为。
@ -13,8 +12,7 @@ Git钩子最常见的使用场景包括了推行提交规范根据仓库状
在这篇文章中我们会先简要介绍Git钩子是如何工作的。然后我们会审视一些本地和远端仓库使用最流行的钩子。
概述
===
# 概述
所有Git钩子都是仓库中特定事件发生时Git自动运行的普通脚本。因此Git钩子安装和配置也非常容易。
@ -24,7 +22,7 @@ Git钩子最常见的使用场景包括了推行提交规范根据仓库状
钩子存在于每个Git仓库的`.git/hooks` 目录中。当你初始化仓库时Git自动生成这个目录和一些示例脚本。当你观察`.git/hooks` 时,你会看到下面这些文件:
```
```
applypatch-msg.sample pre-push.sample
commit-msg.sample pre-rebase.sample
post-update.sample prepare-commit-msg.sample
@ -36,15 +34,15 @@ pre-commit.sample
比如说,试试安装一个`prepare-commit-msg` 钩子。去掉脚本的`.sample` 拓展名,在文件中加上下面这两行:
```
```
#!/bin/sh
echo "# Please include a useful commit message!" > $1
```
钩子需要能被执行,所以如果你创建了一个新的脚本文件,你需要修改它的文件权限。比如说,为了确保`prepare-commit-msg` 可执行,运行下面这个命令:
```
```
chmod +x prepare-commit-msg
```
@ -57,9 +55,10 @@ chmod +x prepare-commit-msg
内置的脚本大多是shell和PERL语言的但你可以使用任何脚本语言只要它们最后能编译到可执行文件。每次脚本中的`#!/bin/sh` 定义了你的文件将被如何解释。比如使用其他语言时你只需要将path改为你的解释器的路径。
比如说,你可以在`prepare-commit-msg` 中写一个可执行的Python脚本。下面这个钩子和上一节的shell脚本做的事完全一样。
```
```
#!/usr/bin/env python
import sys, os
@ -89,19 +88,18 @@ with open(commit_msg_filepath, 'w') as f:
也就是说,用服务端钩子来拒绝没有遵守规范的提交是完全可行的。后面我们会再讨论这个问题。
本地钩子
---
## 本地钩子
本地钩子只影响它们所在的仓库。当你在读这一节的时候,记住开发者可以修改他们本地的钩子,所以不要用它们来推行强制的提交规范。不过,它们确实可以让开发者更易于接受这些规范。
在这一节中我们会探讨6个最有用的本地钩子
- pre-commit
- prepare-commit-msg
- commit-msg
- post-commit
- post-checkout
- pre-rebase
- pre-commit
- prepare-commit-msg
- commit-msg
- post-commit
- post-checkout
- pre-rebase
前4个钩子让你介入完整的提交生命周期后2个允许你执行一些额外的操作分别为`git checkout` 和`git rebase` 的安全检查。
@ -115,7 +113,7 @@ with open(commit_msg_filepath, 'w') as f:
`pre-commit` 不需要任何参数以非0状态退出时将放弃整个提交。让我们看一个简化了的和更详细的内置`pre-commit` 钩子。只要检测到不一致时脚本就放弃这个提交,就像`git diff-index` 命令定义的那样只要词尾有空白字符、只有空白字符的行、行首一个tab后紧接一个空格就被认为错误
```
```
#!/bin/sh
# Check if this is the initial commit
@ -147,20 +145,22 @@ fi
这只是`pre-commit` 的其中一个例子。它恰好使用了已有的Git命令来根据提交带来的更改进行测试但你可以在`pre-commit` 中做任何你想做的事比如执行其它脚本、运行第三方测试集、用Lint检查代码风格。
### prepare-commit-msg
`prepare-commit-msg` 钩子在`pre-commit` 钩子在文本编辑器中生成提交信息之后被调用。这被用来方便地修改自动生成的squash或merge提交。
`prepare-commit-msg` 脚本的参数可以是下列三个:
- 包含提交信息的文件名。你可以在原地更改提交信息。
- 提交类型。可以是信息(`-m``-F` 选项),模板(`-t` 选项merge如果是个merge提交或squash如果这个提交插入了其他提交
- 相关提交的SHA1哈希值。只有当`-c`, `-C`, or `--amend` 选项出现时才会出现。
- 包含提交信息的文件名。你可以在原地更改提交信息。
- 提交类型。可以是信息(`-m` 或 `-F` 选项),模板(`-t` 选项merge如果是个merge提交或squash如果这个提交插入了其他提交
- 相关提交的SHA1哈希值。只有当`-c`, `-C`, or `--amend` 选项出现时才会出现。
和`pre-commit` 一样以非0状态退出会放弃提交。
我们已经看过一个修改提交信息的简单例子现在我们来看一个更有用的脚本。使用issue跟踪器时我们通常在单独的分支上处理issue。如果你在分支名中包含了issue编号你可以使用`prepare-commit-msg` 钩子来自动地将它包括在那个分支的每个提交信息中。
```
```
#!/usr/bin/env python
import sys, os, re
@ -197,7 +197,7 @@ if branch.startswith('issue-'):
首先,上面的`prepare-commit-msg` 钩子告诉你如何收集传入脚本的所有参数。接下来,它调用了`git symbolic-ref --short HEAD` 来获取对应HEAD的分支名。如果分支名以`issue-` 开头它会重写提交信息文件在第一行加上issue编号。比如你的分支名`issue-224` ,下面的提交信息将会生成:
```
```
ISSUE-224
# Please enter the commit message for your changes. Lines starting
@ -219,7 +219,7 @@ ISSUE-224
比如说,下面这个脚本确认用户没有删除`prepare-commit-msg` 脚本自动生成的`ISSUE-[#]` 字符串。
```
```
#!/usr/bin/env python
import sys, os, re
@ -256,7 +256,7 @@ if branch.startswith('issue-'):
比如说,如果你需要每次提交快照时向老板发封邮件(也许对于大多数工作流来事不是个好的想法),你可以加上下面这个`post-commit` 钩子。
```
```
#!/usr/bin/env python
import smtplib
@ -289,20 +289,21 @@ session.quit()
你虽然可以用`post-commit` 来触发本地的持续集成系统,但大多数时候你想用的是`post-receive` 这个钩子。它运行在服务端而不是用户的本地机器,它同样在任何开发者推送代码时运行。那里更适合你进行持续集成。
### post-checkout
### post-checkout
`post-checkout` 钩子和`post-commit` 钩子很像,但它是在你用`git checkout` 查看引用的时候被调用的。这是用来清理你的工作目录中可能会令人困惑的生成文件。This is nice for clearing out your working directory of generated files that would otherwise cause confusion.
这个钩子接受三个参数,它的返回状态不影响`git checkout` 命令。
- HEAD前一次提交的引用
- 新的HEAD的引用
- 1或0分别代表是分支checkout还是文件checkout。
- HEAD前一次提交的引用
- 新的HEAD的引用
- 1或0分别代表是分支checkout还是文件checkout。
Python程序员经常遇到的问题是切换分支后那些之前生成的`.pyc` 文件。解释器有时使用`.pyc` 而不是`.py` 文件。为了避免歧义,你可以在每次用`post-checkout` 切换到新的分支的时候,删除所有`.pyc` 文件。
```
```
#!/usr/bin/env python
import sys, os, re
@ -337,7 +338,7 @@ for root, dirs, files in os.walk('.'):
比如说如果你想彻底禁用rebase操作你可以使用下面的`pre-rebase` 脚本:
```
```
#!/bin/sh
# Disallow all rebasing
@ -347,23 +348,22 @@ exit 1
每次运行`git rebase` ,你都会看到下面的信息:
```
```
pre-rebase: Rebasing is dangerous. Don't do it.
The pre-rebase hook refused to rebase.
```
内置的`pre-rebase.sample` 脚本是一个更复杂的例子。它在什么时候阻止rebase这方面更加智能。它会检查你当前的分支是否已经合并到了下一个分支中去也就是主分支。如果是的话rebase可能会遇到问题脚本会放弃这次rebase。
服务端钩子
===
# 服务端钩子
服务端钩子和本地钩子几乎一样,只不过它们存在于服务端的仓库中(比如说中心仓库,或者开发者的公共仓库)。当和官方仓库连接时,其中一些可以用来拒绝一些不符合规范的提交。
这节中我们要讨论下面三个服务端钩子:
- pre-receive
- update
- post-receive
- pre-receive
- update
- post-receive
这些钩子都允许你对`git push` 的不同阶段做出响应。
@ -377,13 +377,13 @@ The pre-rebase hook refused to rebase.
这个脚本没有参数,但每一个推送上来的引用都会以下面的格式传入脚本的单独一行:
```
```
<old-value> <new-value> <ref-name>
```
你可以看到这个钩子做了非常简单的事,就是读取推送上来的引用并且把它们打印出来。
```
```
#!/usr/bin/env python
import sys
@ -399,28 +399,28 @@ for line in fileinput.input():
这和其它钩子相比略微有些不同,因为信息是通过标准输入而不是命令行传入的。在远端仓库的`.git/hooks` 中加上这个脚本推送到master分支你会看到下面这些信息打印出来
```
```
b6b36c697eb2d24302f89aa22d9170dfe609855b 85baa88c22b52ddd24d71f05db31f4e46d579095 refs/heads/master
```
你可以用SHA1哈希值或者底层的Git命令来检查将要引入的更改。一些常见的使用包括
- 拒绝将上游分支rebase的更改
- 防止错综复杂的合并(非快速向前,会造成项目历史非线性)
- 检查用户是否有正确的权限来做这些更改大多用于中心化的Git工作流中
- 如果多个引用被推送,在`pre-receive` 中返回非0状态拒绝所有提交。如果你想一个个接受或拒绝分支你需要使用`update` 钩子
- 拒绝将上游分支rebase的更改
- 防止错综复杂的合并(非快速向前,会造成项目历史非线性)
- 检查用户是否有正确的权限来做这些更改大多用于中心化的Git工作流中
- 如果多个引用被推送,在`pre-receive` 中返回非0状态拒绝所有提交。如果你想一个个接受或拒绝分支你需要使用`update` 钩子
### update
`update` 钩子在`pre-receive` 之后被调用用法也差不多。它也是在实际更新前被调用的但它可以分别被每个推送上来的引用分别调用。也就是说如果用户尝试推送到4个分支`update` 会被执行4次。和`pre-receive` 不一样,这个钩子不需要读取标准输入。事实上,它接受三个参数:
- 更新的引用名称
- 引用中存放的旧的对象名称
- 引用中存放的新的对象名称
- 更新的引用名称
- 引用中存放的旧的对象名称
- 引用中存放的新的对象名称
这些信息和`pre-receive` 相同,但因为每次引用都会分别触发更新,你可以拒绝一些引用而接受另一些。
```
```
#!/usr/bin/env python
import sys
@ -443,9 +443,8 @@ print "Moving '%s' from %s to %s" % (branch, old_commit, new_commit)
这个脚本没有参数,但和`pre-receive` 一样通过标准输入读取。
总结
---
## 总结
在这篇文章中我们学习了如果用Git钩子来修改内部行为当仓库中特定的事件发生时接受消息。钩子是存在于`git/hooks` 仓库中的普通脚本,因此也非常容易安装和定制。
我们还看了一些常用的本地和服务端的钩子。这使得我们能够介入到整个开发生命周期中去。我们现在知道了如何在创建提交或推送的每个阶段执行自定义的操作。有了这些简单的脚本知识你就可以对Git仓库为所欲为了 : )
我们还看了一些常用的本地和服务端的钩子。这使得我们能够介入到整个开发生命周期中去。我们现在知道了如何在创建提交或推送的每个阶段执行自定义的操作。有了这些简单的脚本知识你就可以对Git仓库为所欲为了 : )

View File

@ -1,8 +1,8 @@
# 代码合并Merge还是Rebase
> BY 童仲毅(geeeeeeeeek@github)
> BY 童仲毅([geeeeeeeeek@github](https://github.com/geeeeeeeeek/git-recipes/))
>
> 这是一篇在[原文](https://www.atlassian.com/git/tutorials/merging-vs-rebasing)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。
> 这是一篇在[原文(BY atlassian)](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的所有用法。

View File

@ -1,8 +1,8 @@
# 保存你的更改
> BY 童仲毅(geeeeeeeeek@github)
> BY 童仲毅([geeeeeeeeek@github](https://github.com/geeeeeeeeek/git-recipes/))
>
> 这是一篇在[原文](https://www.atlassian.com/git/tutorials/saving-changes)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。
> 这是一篇在[原文(BY atlassian)](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

View File

@ -1,8 +1,8 @@
# 创建代码仓库
> BY 童仲毅(geeeeeeeeek@github)
> BY 童仲毅([geeeeeeeeek@github](https://github.com/geeeeeeeeek/git-recipes/))
>
> 这是一篇在[Bitbucket教程](https://www.atlassian.com/git/tutorials/setting-up-a-repository)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。
> 这是一篇在[原文(BY atlassian)](https://www.atlassian.com/git/tutorials/setting-up-a-repository)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。

View File

@ -1,8 +1,8 @@
# Reset、Checkout和Revert
> BY 童仲毅(geeeeeeeeek@github)
> BY 童仲毅([geeeeeeeeek@github](https://github.com/geeeeeeeeek/git-recipes/))
>
> 这是一篇在[原文](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))协议共享。
> 这是一篇在[原文(BY atlassian)](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还可以作用于特定文件。

View File

@ -1,8 +1,8 @@
# 检查仓库状态
> BY 童仲毅(geeeeeeeeek@github)
> BY 童仲毅([geeeeeeeeek@github](https://github.com/geeeeeeeeek/git-recipes/))
>
> 这是一篇在[原文](https://www.atlassian.com/git/tutorials/inspecting-a-repository/git-log)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。
> 这是一篇在[原文(BY atlassian)](https://www.atlassian.com/git/tutorials/inspecting-a-repository/git-log)基础上演绎的译文。除非另行注明,页面上所有内容采用知识共享-署名([CC BY 2.5 AU](http://creativecommons.org/licenses/by/2.5/au/deed.zh))协议共享。
## git status

View File

@ -7,7 +7,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章** [仓库状态](https://github.com/geeeeeeeeek/git-recipes/wiki/2.4-%E6%A3%80%E6%9F%A5%E4%BB%93%E5%BA%93%E7%8A%B6%E6%80%81)
- **第4章** [查仓库状态](https://github.com/geeeeeeeeek/git-recipes/wiki/2.4-%E6%A3%80%E6%9F%A5%E4%BB%93%E5%BA%93%E7%8A%B6%E6%80%81)
- **第5章** [检出之前的提交](https://github.com/geeeeeeeeek/git-recipes/wiki/2.5-%E6%A3%80%E5%87%BA%E4%B9%8B%E5%89%8D%E7%9A%84%E6%8F%90%E4%BA%A4)
- **第6章** 回滚错误的更改 **第7章** 重写项目历史