git - 为什么这个 git rebase 认为无事可做?

标签 git

在这个例子中,git 认为它不需要 rebase,但它显然需要。

这是一个创建迷你测试 git 存储库的快速脚本

#!/bin/bash
rm -rf testgit
mkdir testgit
cd testgit
git init
echo -e "a\nb\nc" > file
git add file
git commit -am 'first'

git checkout -b lineA
echo -e "A\nb\nc" > file
git commit -am 'A'

git checkout -b lineB
echo -e "a\nB\nc" > file
git commit -am 'B'

git checkout -b lineC
echo -e "a\nb\nC" > file
git commit -am 'C'

运行后,这是每个分支中的 file 的样子

master | lineA | lineB | lineC
------------------------------

a        A       a       a
b        b       B       b
c        c       c       C

现在让我们将所有分支 merge 到 master 中,之后 file 中的每个字母都应该大写

$ git checkout master
$ git merge lineA

好的。

$ git checkout lineB
$ git rebase master
Current branch lineB is up to date.

什么?不,主人换了。

$ git checkout master
$ cat file
A
b
c

$ git checkout lineB
$ cat file
a
B
c

在我看来,分支 lineB 需要 rebase 以 merge 通过 merge lineA 对 master 所做的更改。

为什么 git 认为不需要这样做?

此外,如果你这样做

$ git checkout master
$ git merge lineA
Already up-to-date.
$ git merge lineB
...
 1 file changed, 2 insertions(+), 2 deletions(-)
$ cat file
a
B
c
$ git merge lineC
...
 1 file changed, 2 insertions(+), 2 deletions(-)
$ cat file
a
b
C

这里的 merge 应该是冲突的,但是 git 正在悄悄地破坏它们。我不知道这是否相关,但看起来很奇怪。

最佳答案

第一条命令的结果

在我们的脚本之后(缩写行分支名称...):

master   lA   lB   lC
  ↓      ↓    ↓    ↓
first----A----B----C

这些命令:

$ git checkout master
$ git merge lineA

导致快进 merge ,它只是将 master 移动到与 lineA 相同的提交。

给予:

        master 
         lA   lB   lC
         ↓    ↓    ↓
first----A----B----C

Rebase 没有工作

所以这个命令序列:

$ git checkout lineB
$ git rebase master

是说将 lineB 分支移动到 master 之上。

...但它已经在 master 之上。

master 必须在其历史记录中有一些 lineB 没有的提交,rebase 命令才能执行任何工作。

没有 merge 冲突

当 Git 创建 merge 提交时,它会考虑将要 merge 的父项的历史记录。在这种情况下,两个分支都指向公共(public)提交链上的提交。 Git 可以看到 A 提交在 B 提交之前,而 B 提交在 C 提交之前。因此,Git 认为较晚的提交是在较早的提交之上添加的,因此它们不会冲突。

如果你有这样的历史:

       master
         ↓
      ---A
     /
     |   lB
     |   ↓
first----B

那么 Git 会将它们视为平行的开发线。在那种情况下,将 lB merge 到 master 中,反之亦然会发生冲突。这是因为 B 不是历史上 A 之上的添加,因此 Git 需要用户输入以了解要保留哪些更改。

关于git - 为什么这个 git rebase 认为无事可做?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40613102/

相关文章:

git - 如何 git cherry-pick commit 声明我们的历史包含它

c# - 使用 libgit2sharp 推送到 bitbucket

git - 如何将具有提交历史记录的特定文件从 Mercurial 迁移到 gitlab?

gitignore 不会忽略文件

git - 从 master 分支恢复 merge 的 pull 请求

git - 为什么我不能推送到非裸仓库的已 checkout 分支?

git - 更改未推送的先前 git 提交消息

git - 如何从git stash中进行cherry-pick ?

git - 如何设置 CODEOWNERS 文件以排除特定用户?

git - 错误 : Cannot Spawn C:\Path To\TortoiseGit\Bin: No such file or directory