Git 变基创建非线性历史
Git Rebase creating not linear history
Git 存储库只有 master,每个人都在使用它(不要评判我,到目前为止是一件小事),默认情况下启用了 Rebase。 AFAIK git-rebase 重写历史记录,根据日期逐一应用提交,并在此过程中需要时进入 MERGING 状态。但是有一件事让我和团队很恼火,历史有时不是线性的,请看一些例子:
这里会发生什么?或者我误解了 git-rebase 的工作原理?
历史不是基于日期,而是基于 Git 所基于的基础图表。例如,您的历史记录可能如下所示:
branchA
↓
* -- * -- * -- * -- *
\
* -- * -- *
↑
branchB
每个 *
代表您历史记录中的一次提交,但实际日期与图中的位置完全无关。让我们用数字替换星星,以显示它们创建的相对时间(稍后创建更大的数字):
branchA
↓
1 -- 2 -- 4 -- 5 -- 8
\
3 -- 6 -- 7
↑
branchB
这是每个分支上完美且“线性”(就时间而言)的历史记录。如果您记录 branchA
的历史记录,您会得到 8, 5, 4, 2, 1
; branchB
你会得到 7, 6, 3, 2, 1
.
现在,如果您将 branchB
变基到 branchA
,Git 将 重写 那些在 branchB
上的提交并应用它们到 branchA
。重写时,Git 默认 保持创作时间不变(但将提交时间重置为当前时间)。所以你会得到以下结果:
branchA
↓
1 -- 2 -- 4 -- 5 -- 8 -- 3' -- 6' -- 7'
↑
branchB
(这里的'
表示其实和原来的commit不同,但是内容和作者时间是一样的)
如果您现在查看 branchB
的日志,您将得到以下内容:7', 6', 3', 8, 5, 4, 2, 1
。这正是“时间悖论”的来源:你确实有一个完美的线性历史(本节的图表是线性的);但提交不一定按照它们最初创作的顺序。
这很好,完全是设计使然:变基不应该完全重置提交,所以原始作者信息(谁做的,他们什么时候做的)仍然存在。
Git 存储库只有 master,每个人都在使用它(不要评判我,到目前为止是一件小事),默认情况下启用了 Rebase。 AFAIK git-rebase 重写历史记录,根据日期逐一应用提交,并在此过程中需要时进入 MERGING 状态。但是有一件事让我和团队很恼火,历史有时不是线性的,请看一些例子:
这里会发生什么?或者我误解了 git-rebase 的工作原理?
历史不是基于日期,而是基于 Git 所基于的基础图表。例如,您的历史记录可能如下所示:
branchA
↓
* -- * -- * -- * -- *
\
* -- * -- *
↑
branchB
每个 *
代表您历史记录中的一次提交,但实际日期与图中的位置完全无关。让我们用数字替换星星,以显示它们创建的相对时间(稍后创建更大的数字):
branchA
↓
1 -- 2 -- 4 -- 5 -- 8
\
3 -- 6 -- 7
↑
branchB
这是每个分支上完美且“线性”(就时间而言)的历史记录。如果您记录 branchA
的历史记录,您会得到 8, 5, 4, 2, 1
; branchB
你会得到 7, 6, 3, 2, 1
.
现在,如果您将 branchB
变基到 branchA
,Git 将 重写 那些在 branchB
上的提交并应用它们到 branchA
。重写时,Git 默认 保持创作时间不变(但将提交时间重置为当前时间)。所以你会得到以下结果:
branchA
↓
1 -- 2 -- 4 -- 5 -- 8 -- 3' -- 6' -- 7'
↑
branchB
(这里的'
表示其实和原来的commit不同,但是内容和作者时间是一样的)
如果您现在查看 branchB
的日志,您将得到以下内容:7', 6', 3', 8, 5, 4, 2, 1
。这正是“时间悖论”的来源:你确实有一个完美的线性历史(本节的图表是线性的);但提交不一定按照它们最初创作的顺序。
这很好,完全是设计使然:变基不应该完全重置提交,所以原始作者信息(谁做的,他们什么时候做的)仍然存在。