如果在其他分支中提交并在给定日期/时间之后合并到master
,则该提交中的更改不应出现在快照中,即使提交是在给定日期/时间之前进行的
this answer中的选项2不能完成我需要的工作,因为它只是按时间顺序对提交进行排序,并在给定的日期/时间之前返回最新版本。
答案 0 :(得分:2)
你仍然可以从那个答案开始(我将在这里重复一遍,稍作修改,因为我要将它拆开):
git checkout `git rev-list -n 1 --before="yesterday" master`
您要避免的问题是git rev-list
找到从分支master
的提示可以访问的所有提交,包括合并到{{1}的其他分支例如:
master
让我们说你想要找到的提交是标有...-A--C---E <-- master
/ /
...--B---D <-- develop
的提交,但C
晚于D
(虽然仍然足够老,可以选择按C
选项)。 --before
发现所有可从git rev-list
(分支E
的尖端)到达的提交,其日期戳 1 足够早。 master
导致它在找到一个后立即停止:没有它,它将列出第一个提交-n 1
,然后提交D
,然后提交更多提交(C
,然后B
等。)
但是,您可以向A
传递更多选项。例如,git rev-list
会导致提交在拓扑排序的#34;订单:您获得--topo-order
,然后是D
,然后是B
,然后是C
。不完全是我们想要的,但它表明A
是一个复杂的小野兽。 : - )
我们真正需要的是一种告诉git rev-list
它不应该沿着从其他分支合并到 master中的提交路径的方法。事实证明,有两种方法可以做到这一点,有两个不同的缺陷。
git rev-list
第一种也是最简单的方法是使用--first-parent
(只需将其添加到--first-parent
的参数中)。在这种情况下,只要git rev-list
在向后工作时遇到分叉 - 例如,从git rev-list
到E
和C
- 这指示它只跟随 父母。当这工作时,它的工作原理是因为每个D
提交专门记录当前分支作为第一个父级,任何合并的提交/分支作为第二个父级(甚至第三个,第四个等) 。,父母,如果是&#34;章鱼合并&#34;)。
如果您的分支上的合并提交是由于某人使用(例如git merge
将其工作合并到分支行中)而导致此失败。请注意,git pull
只是git pull
后跟git fetch
,因此在分支git merge
上工作的人会进行私有提交branch
,其他人也在分支上工作私人提交K
,首先推动L
的人,推动L
的人推动但是#34}不是快进&#34;所以K
s然后pull
es。他们的push
合并了pull
与提交K
:
L
然后他们...-o--K---M <-- branch
\ /
--L- <-- origin/branch
成功,以便push
现在指向合并提交origin/branch
:
M
合并...-o--K---M <-- branch, origin/branch
\ /
--L-
的第一个父级是M
; K
由{em>其他人在L
上制作,是第二个父母。 branch
的{{1}}选项会跳过提交--first-parent
,因为它已被合并(由任何人制作并推送git rev-list
)。
如果你有一个严格的变基策略而不是合并,这种情况首先不会出现,所以你可以忽略它。如果没有,你可以忍受(删除这些提交)或尝试第二个选项。
L
排除K
等分支的另一种方法是排除--not ...
之类的分支。您希望从develop
可以访问的所有提交,但从任何其他分支的提示开始,不可以访问。
首先,您需要一个所有分支的列表,或者至少需要丢弃的所有分支。让我们获得所有分支(和仅分支)的完整列表,但develop
本身除外:
master
接下来,您只需向git询问所有可从master
到达的提交,不包括从上述分支列表中可以访问的所有提交:
git for-each-ref --format='%(refname:short)' refs/heads | grep -v '^master$'
这次,当git点击提交master
时,它被排除,因为它位于分支git rev-list --before=... -n 1 master --not $(git for-each-ref \
--format='%(refname:short)' refs/heads | grep -v '^master$')
上。 (它也在分支D
上:提交可以同时在许多分支上。)然而,提交develop
仅在分支master
上 ,所以当它符合C
限制时,会列出,然后master
使--before
停止(这样你就不会提交-n 1
)。
如果有人删除分支git rev-list
,则会出现此方法的缺陷。这使实际修订图保持不变,但A
标签不再存在以指向提交develop
。因此,develop
没有理由可以看到排除提交D
,因此您将看到修订版。
这是你应该尝试的练习。假设我只提供了这张提交图(剥离了部分或大部分标签):
git rev-list
我是如何制作此图表的?我是否检查了一个侧分支D
,并在那里做了一些提交,然后查看...--o--o--o---o--o <-- branch
\ /
o--o--o
和(也许在另一个用户名下)也在那里做了一些提交,然后最终feature
进入branch
然后删除git merge feature
?或者,是否有两个不同的人在branch
上工作,一个人提交了一些提交并且feature
首先编辑,而另一个提交了一些提交但是推了第二个并且从branch
得到了错误?如果第二个人然后做了push
然后合并并推送,那会产生相同的图吗?
1 根据来源,它似乎只查看提交者日期,而不是作者日期。我无法在任何地方找到这些文件(我一直想知道这个,关闭和开启,很长一段时间)。