git log和git rebase之间关系密切

这篇文章是2017年Fujitsu Advent Calendar活动第二阶段的第五天的文章。
这篇文章所表达的观点是个人观点,不代表所属公司或组织的立场。


因为第二个还有空位,所以非常抱歉地在此转载了之前在公司内部博客上发布的文章。
值得一提的是,之前在第一个里使用了敬语,但这里使用了常体的原因是时间关系。

1. Git log 的修订范围 (revision range)

在Git中,要查看从提交A到提交B的日志,可以执行以下命令。

git log A..B

A和B都可以是提交ID,分支或标签。
如果历史是这样一条直线,那么很容易理解。
尽管从A说到B时没有显示提交A可能会感到有些不自然。

o---o---A---o---o---B

当对这样分叉的历史使用 git log A..B 命令时,会显示什么范围的日志?

      o---o---A
     /
o---C---o---o---B

当执行”git log C..B”命令时的输出结果与之前相同。与前述方法类似,提交 C 将不会被显示。

     ---o---o---B

在开始使用Git的时候,可能不了解为什么会变成这样,即使理解了也无法记住,无法如自己所愿地生成日志。
其实,如果仔细阅读Git文档,上面会提到这一点。

git log A..B

嗯。

git log ^A B

与之同样的。也就是说,“包含从B 可达的提交,但不包含从A 可达的提交”的意思。
(在前面的文档中,更确切地说是” ^A B,也可以写作 A..B “的说法。)
让我用刚才的例子来解释一下。

      o---o---A
     /
o---C---o---o---B

在这个记录中,“可从B到达的提交”如下所示。

o---C---o---o---B

「可通过A到达的提交」是这样的。

      o---o---A
     /
o---C

因此,“能够从B到达,但无法从A到达”的提交,即通过git log A..B显示的提交,会变成这样。

     ---o---o---B

C 未显示的原因以及直接的历史

o---o---A---o---o---B

当进行 log A..B 操作时,如果 A 未显示出来,通过将其改写为 log ^A B,我觉得可以理解。

2. Git合并基地(git rebase)。

在git rebase文档中,写着如下内容。

git rebase [--onto <newbase>] [<upstream> [<branch>]]

这个真的很难理解。不知道包含哪些提交在,而且,到底是还是,很难记住。经常会错误地将master放在feature branch的前面。实际上,如果像之前提到的git log A^ B一样理解,问题就可以解决了。也就是说,

git log A..B

以同样的方式

git rebase A B

如果理解为从B可到达但从A不可到达的提交,将其重新基于A,则只需将A中的..和^省略。
用一个例子来解释。与之前相同的历史。

      o---o---A
     /
o---C---o---o---B

所以

git rebase A B

只需要一种选项,将以下内容用中文进行翻译:当执行“从B可达但从A不可达的提交”,也就是执行git log A..B时的结果相同。

     ---o---o---B

经过重组,就变成了这样。

      o---o---A---o---o---B
     /
o---C

3. 離題

git rebase --onto X A B

可以做到的是可以将除了 A 以外的提交 X 进行重新基础。
虽然看起来似乎没有太多用途,但实际上有一个方便的用途,记住会很有用。

我经常犯这样一个错误,就是本来应该放入特性分支中进行修改,但却忘记在检出之前进行提交,结果就开始在主分支上进行修正了。

git stash
git checkout feature
git stash pop

用中文自然地改述:
如果只是修正一下就能解决的话,但如果修改后还已经提交了,该怎么办呢?
即便如此也没有必要慌张。可以使用 git rebase –onto X 来解决。

我用一个例子来说明。

      o---o---A
     /
o---C---o---o---B

当有一个名为”というブランチ”的分支时,

      o---o---A---o---A'
     /
o---C---o---o---B

想把一系列的提交(commit)放入 A 中。

      o---o---A
     /
o---C---o---o---B---o---A'

就像是错误地放进了B一样。
(※ 因为解释的需要,原本的分支不应该是—元B—o—B那么,这个怨念请原谅…)
想要把本来属于A的提交移动过来。

                 ---o---A'

这个表达是“可以从A’而无法从B到达的提交”,换句话说,当查看日志时,与B..A’相同,因此在rebase参数中为B A’。只需要将其移动到A,所以–onto A。

git rebase --onto A B A'

做!

      o---o---A---o---A'
     /
o---C---o---o---B

这就是。太棒了,太棒了。

广告
将在 10 秒后关闭
bannerAds