繁体   English   中英

列出分支中的所有提交,直到标记(包括)

[英]List all commits in a branch until a tag (including)

在一个分支中,我在4个不同的单独提交中添加了4个文件。 每个提交都有一个文件。 以下是示例提交消息

例如:

  Adding file 1 
  Adding file 2  ---test-tag
  Adding file 3
  Adding file 4

我使用名为“test-tag”的标记标记了第二次提交。 我想列出此分支中的所有提交,从标记(包括包含标记的提交)开始到分支中的最新提交。 提交列表应包括标记的提交。 通过以下提交,我从标记中获取提交但不包括它。

git log --pretty=oneline test-tag..

对于大多数Git命令,双点..表示法意味着排除左侧命名的提交,如您所见。 (所有提交的枚举都从右侧命名的提交开始,省略名称意味着“当前提交”,即HEAD@ 。)因此,有两种方法可以解决这个问题:

  • 此提交之前使用commit(s)开始排除,或者
  • 使用一个标志告诉命令我想要通常被排除的提交

后者似乎更简单,在大多数情况下实际上工作正常:

git log --boundary --pretty=oneline test-tag..

但是, - --boundary在一些更复杂的情况下表现得很糟糕,所以我更喜欢用commit的父代开始排除。

使用后缀^或后缀~表示法很容易找到任何提交的第一个父级:

git log --pretty=oneline test-tag^..
git log --pretty=oneline test-tag~..

对于这种特殊情况,两者都会做你想要的,但它们也有轻微的缺陷。 尽管存在轻微缺陷,您可能希望熟悉这种表示法,因为它非常方便。 后缀代字号表示一个可选的数字(默认为1),它会计算出许多第一父母。

您没有显示您的四个提交的实际提交哈希ID,所以让我使用我自己的随机旧存储库:

$ git log --oneline -n 4
11ae6ca (HEAD -> master) add run-checks script
d1574b8 mxgroup.py: sort-of-mutual-exclusive-groups
b9491ea gerrit-review.sh: push to refs/for/
676699a wacky.py - replacing class-member functions

这些提交都没有被标记,所以让我们从HEAD / master / @向后计数:

  • @~1表示提交d1574b8 ,退一步
  • @~2 b9491ea表示提交b9491ea ,后退两步
  • @~3 676699a表示提交676699a ,退回三步

等等。

更多细节(准备好后阅读,上面的内容已经足够一段时间了)

hat或caret( ^ )后缀也可以使用数字,但这仅在有问题的提交是合并提交时才有意义。 合并提交是具有多个父级的任何提交,通常是两次使用git merge来合并两个分支:

          I--J   <-- branch1
         /
...--G--H
         \
          K--L   <-- branch2

这里,名称branch1branch2分别表示提交JL (这里JL依次代表实际的丑陋哈希ID。)

假设我们运行git checkout branch1然后git merge branch2 Git将从两个分支提交向后移动,首先是一步到IK ,然后是两步到H Commit H两个分支上,并且是两个分支提示之前的最佳共享提交,因此它是合并操作的合并基础。

然后,Git会将提交H中的所有文件与提交J所有文件进行比较,以查看某人在branch1branch1 另外,Git会将H所有文件与L的文件进行比较,以查看某人在branch2上所做的工作。 然后,合并操作这些更改组合在一起 ,将组合的更改应用于H的文件。 如果一切顺利,Git会使用应用两组更改的文件进行新的提交,即合并了两行开发。 新提交看起来像这样:

          I--J
         /    \
...--G--H      M   <-- ??? (what name points to M?)
         \    /
          K--L

新提交M获取新的哈希ID,不同于每个现有和将来的提交。 现在必须更新某些分支名称以记住新提交M 更新的实际分支名称取决于您是否执行了git checkout branch1; git merge branch2 git checkout branch1; git merge branch2 ,或git checkout branch2; git merge branch1 git checkout branch2; git merge branch1 无论您检出哪个分支, 名称都会被移动,而另一个分支会保留在原位。 我们上面说过,我们假设你做了一个git checkout branch1所以让我们将名称branch1移动到指向新的提交M

          I--J
         /    \
...--G--H      M   <-- branch1
         \    /
          K--L   <-- branch2

由于新提交M记得两个先前的提交,而不仅仅是一个,我们现在有一些有趣的案例。 其中一个是M第一个父类:在这种情况下,它是提交J因为名称branch1曾经指向J 1所以M~1M^1表示提交JM的两个父母中的第一个

要查找提交LM第二个父项,则不能使用~后缀。 您必须改为使用^后缀,并写入M^2 这告诉Git: 找到提交M,然后找到它的第二个父级。

所以这就是^后缀比~后缀更有用的地方。 否则, ~后缀是不是更有益~后缀,因为你可以指望了。 但请注意,你可以组合后缀: M^2让你提交L ,而M^2~让你L的父K M^2~2得到K的父H ,你也可以使用M^1~2 ,或者只是M~3 :从M开始并返回三步,使用第一个父,只要有一个选择。


1如果我们以相反的方式进行合并,那么branch2指向M ,其第一个父级为L ,第二个父级为J 除了父项是第一个以及哪个分支名称发生更改之外,合并过程通常是完全对称的。


包含带有双点表示法的合并提交

假设我们继续使用此时的branch1设置,要么写下M的哈希ID,要么为我们设置标记以记住M

          I--J   ..... tag: test-merge
         /    \ .
...--G--H      M   <-- branch1
         \    /
          K--L   <-- branch2

然后我们继续做一些提交:

          I--J   ..... tag: test-merge
         /    \ .
...--G--H      M--N--O   <-- branch1
         \    /
          K--L   <-- branch2

如果我们现在想要git log提交MO包含该怎么办? 我们通常的写作技巧:

git log test-merge^..

不起作用,因为test-merge^意味着找到提交M ,然后退回到它的第一个父J ,并排除J (和更早) 结果是你看到KLMNO :五个提交,你预期三个。

如果你试试:

git log test-merge^2..

你告诉Git 找到提交M ,然后退回到它的第二个父L ,并排除L (和更早) 结果就是你看到了HIMNO :再次提交了五次提交。

要在视觉上看到这一点,请绘制上面的图表。 使用红色荧光笔标记排除的提交。 让你的红色继续前进,标记你可以通过向后工作获得的所有早期提交。 然后,用绿色荧光笔标记第一个包含的提交。 保持绿色,标记您可以通过向后工作获得的所有早期提交,但在达到红色标记提交时停止。

获得你想要的三个提交的方法 - 除了--boundary ,有时可以工作,但有时不工作 - 告诉Git: 排除提交J排除提交L 您可以通过不使用双点表示法来执行此操作:

git log ^M^1 ^M^2 HEAD

这里的前缀 ^告诉Git: 不是 所以git log是从HEAD开始并向后工作,但是排除 M^1M^2

正确的答案

当然,这只能起作用,因为M只有两个父母。 我们列出他们为“不显示此承诺,也没有任何更早”,我们得到了我们想要的东西。 但是如果我们选择非合并提交,则^<commit>^2失败,因为没有第二个父级。 我们这里需要的是一个表示提交M所有父母的符号。

事实证明只有这样的符号。 它(和许多其他的)列在gitrevisions文档中 ,这个特殊的拼写有后缀^@ 所以我们得到了我们想要的东西:

git log test-merge^@..

无论所选提交的父项有多少,这都有效:我们排除所有提交,同时保留提交本身。

(还有一个相对较新的^-后缀,也在Git 2.11中引入。这些文档页面偶尔值得重新阅读。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM