Git rebase - 在分叉点模式下提交选择 [英] Git rebase - commit select in fork-point mode
问题描述
阅读git rebase
和git merge-base
man 文档:
Reading the git rebase
and git merge-base
man documentation:
在git checkout -b topic origin/master创建的topic分支上工作后,远程跟踪分支origin/master的历史可能已经被倒带重建,导致了这个历史形状:
After working on the topic branch created with git checkout -b topic origin/master, the history of remote-tracking branch origin/master may have been rewound and rebuilt, leading to a history of this shape:
o---B1
/
---o---o---B2--o---o---o---B (origin/master)
B3
Derived (topic)
origin/master 曾经指向提交 B3、B2、B1,现在它指向 B,当 origin/master 位于 B3 时,您的主题分支在它之上启动.此模式使用 reflogorigin/master 找到 B3 作为分叉点,以便可以通过以下方式在更新的 origin/master 之上重新建立主题:
where origin/master used to point at commits B3, B2, B1 and now it points at B, and your topic branch was started on top of it back when origin/master was at B3. This mode uses the reflog of origin/master to find B3 as the fork point, so that the topic can be rebased on top of the updated origin/master by:
$ fork_point=$(git merge-base --fork-point origin/master topic)
$ git rebase --onto origin/master $fork_point topic
$fork_point
将(如果我理解正确的话)成为提交对象 B3
,因此提交 B3..topic
将重新定位到 origin/master
分支.
$fork_point
will ( if I understand it correctly ) be the commit object B3
, and, thus the commits B3..topic
will be rebased onto to origin/master
branch.
Q1 为什么省略 B3
提交很有用?topic
分支的提交建立在 B3
提交之上,所以省略它意味着它的修改将在 origin 的故事中丢失/master
分支.对 B3
提交 和 topic
分支进行变基会导致更清晰的历史记录,不是吗?
Q1 Why is it useful to omit the B3
commit? The commits of the topic
branch are built on top of the B3
commit, so omitting it would mean that its modifications would then be missing in the story of the origin/master
branch. Rebasing the B3
commit and the topic
branch would lead to a cleaner history, wouldn't it?
Q2 有人可以链接/简要描述一下 git 工作流程中 --fork-point
选项的实际用例吗?
Q2 Can someone link / briefly describe practical use cases of the --fork-point
option in the git workflow?
推荐答案
你是对的,$fork_point
将是 B3
.
我相信这里的目的是将 B3
省略为不是你的提交".
I believe the intent here is to omit B3
as "not your commit".
我认为 Git 的人在这里画的图不太好.这是我如何重绘和重写它而不对其进行太多更改(尽管无论如何我可能只是重新写下每个提交).
I think the diagram the Git folks drew here is not so good. Here's how I would redraw and rewrite it without changing it too much (though I'd probably just re-letter each commit anyway).
您首先克隆(或以其他方式更新到)一些(origin
)存储库,其图以提交 B3
结束,然后创建一个主题分支并进行一些提交(s):
You begin by cloning (or otherwise updating to) some (origin
) repository whose graph ends in commit B3
, and you create a topic branch and make some commit(s):
...--o---F---B3 <-- origin/master
G <-- topic
随着时间的推移,使用额外的 git fetch
-es 和 git commit
s,你的提交图现在看起来像这样:
Over time, with additional git fetch
-es and git commit
s, your commit graph now looks like this:
...--o---F---B3--B2--B1 <-- origin/master
G---H---I <-- topic
但是,突然之间,在另一个 git fetch
之后,你自己的提交图现在看起来像这样:
But, suddenly, after another git fetch
, your own commit graph now looks like this:
o---B1' <-- origin/foo
/
...o---F---B2'-o---o---o---B <-- origin/master
B3--G---H---I <-- topic
也就是说,Git 现在会认为提交 B3 属于您的主题分支,而实际上,您的工作是从提交 G
开始的.拥有名为 origin
的存储库的人实际上已经宣布提交 B3
很糟糕,应该扔掉.(他们将 B2
的副本作为 B2'
保存在他们的 master
上,将 B1
的一个副本保存为 B1'
在他们的 foo
上.)
That is, Git would now think that commit B3 belongs on your topic branch, when in fact, your work begins with commit G
. The people who own the repository named origin
have, in effect, declared that commit B3
is terrible and should be thrown away. (They kept a copy of B2
as B2'
on their master
, and one of B1
as B1'
on their foo
.)
如果你只是git rebase
,你会将原始提交B3
复制到新的副本B3'
(同时也复制GHI
):
If you simply git rebase
, you will copy original commit B3
to new copy B3'
(while also copying G-H-I
):
o---B1' <-- origin/foo
/
...o---F---B2'-o---o---o---B <-- origin/master
B3'-G'--H'--I' <-- topic
但你更喜欢:
o---B1' <-- origin/foo
/
...o---F---B2'-o---o---o---B <-- origin/master
G'--H'--I <-- topic
要使 git rebase
执行此操作,您必须指示 Git 定位提交 B3
.origin/master
的 reflog 包含 F
、B3
、B2
和 B1
code> 在其中(在至少一个 reflog 条目下,在这种情况下包括 origin/master@{1}
),而您自己的 topic
有 F
和 B3
,但不包括 B2
和 B1
,也在其中.因此 --fork-point
选择 B3
作为最新(最尖端)的共享提交,而不是 F
.
For git rebase
to do this, you must instruct Git to locate commit B3
. Your reflog for origin/master
has all of F
, B3
, B2
, and B1
in it (under at least one reflog entry, including in this case origin/master@{1}
), while your own topic
has F
and B3
, but not B2
nor B1
, in it as well. Therefore --fork-point
chooses B3
as the newest (tip-most) shared commit, rather than F
.
这里的关键句子/想法是上游存储库作者打算完全放弃提交B3
.
The key sentence / idea in here is that the upstream repository writers intended to discard commit B3
entirely.
(您应该如何确定知道这一点有点神秘.B2'
和 B1'
是副本可能并不明显,如果需要rebase,例如,丢弃一个不应该提交的文件——并且在B1
中,这就是为什么B1
也被丢弃.这个文件现在被省略的事实在 B2'
和 B3'
中使它们不是补丁等效的,因此不是明显的副本.)
(How you are supposed to know this for certain is a bit of a mystery. It may not be obvious that B2'
and B1'
are copies, if the rebasing required, e.g., discarding a file that should never have been committed—and was in B1
, which is why B1
was also discarded. The fact that this file is now omitted in B2'
and B3'
makes them not-patch-equivalent, hence not obviously copies.)
(注意你自己的master
也仍然指向B3
!)
(Note that your own master
also still points to B3
!)
这篇关于Git rebase - 在分叉点模式下提交选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!