Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
git rebase奇怪的行为_Git_Rebase - Fatal编程技术网

git rebase奇怪的行为

git rebase奇怪的行为,git,rebase,Git,Rebase,对于下一个示例,我有一个奇怪的git重基行为。 假设我有一棵本地树: ∨ b1--b2--b3 / a1--a2--a3 那棵遥远的树呢 b1--b2--b3 / a1--a2--a3--a4--a5--a6 分支是主分支的位置 目前,我在b3。 我调用下面的命令: git pull origin master maste

对于下一个示例,我有一个奇怪的git重基行为。 假设我有一棵本地树:

                     ∨
           b1--b2--b3                      
          /
a1--a2--a3
那棵遥远的树呢

            b1--b2--b3
          /
a1--a2--a3--a4--a5--a6
分支是主分支的位置

目前,我在b3。 我调用下面的命令:

git pull origin master master // fixed typo
git rebase master
完成此操作后,我得到了一棵树,它看起来像:

          a4'--a5'--a6'--b1--b2--b3                
         /
a1--a2--a3--a4--a5--a6
反而

                       b1--b2--b3
                      / 
a1--a2--a3--a4--a5--a6

为什么会出现这种情况?

我总是建议人们在非常熟悉git之前避免使用git pull,因为git的功能太多了,有点神秘,这很难解释。它通常(相当准确地)被描述为等同于运行
git fetch
,然后运行
git merge
git rebase
,但棘手的是,它传递给
git merge
git rebase
的参数并不是您所期望的

也就是说,让我们将这些分解,并仔细查看每个步骤。我还将以稍微不同的方式绘制提交图。(您在上面称之为“树”,这不是最好的术语,原因有二。首先,提交图是一个图,特别是一个D定向a循环G图或DAG。所有树都是DAG,但并非所有DAG都是树。其次,Git使用术语树来指代“树对象”;每个提交都携带一个树对象。)

我相信,您的初始提交图如下所示:

           B1--B2--B3   <-- branch (HEAD)
          /
A1--A2--A3   <-- master, origin/master
FETCH\u HEAD
中的内容有点棘手。此文件的内容包括原始名称,即,
master
和可能的
mastert
,如另一个Git上所示,没有Git通常使用的任何
origin/
重命名。也可能有一些行用于标记。这些行中的某些行也可以用
注释,不用于合并
。所有行都包含特定Git对象(提交,有时是标记)的哈希ID。
git-fetch
程序将这些行专门留给
git-pull
程序检查

接下来,您的
git pull
命令从
FETCH\u HEAD
提取新获得的提交的散列ID。也就是说,它在
FETCH\u HEAD
中搜索未标记为
而不是合并的提交的哈希ID。(我假设您在这里执行的是合并样式的拉取,而不是rebase样式的拉取。)然后使用这些哈希ID运行
git merge

git merge
步骤进行合并提交 同样,现在不管您是运行
git pull origin master
还是
git pull origin master
,都很重要。如果您运行后者,并且有一个名为
mastert
的分支,那么将有两个匹配行,可能还有两个不同的哈希ID。在本例中,您的
git pull
命令将执行这两个哈希的八达通合并

否则,您将得到一个散列的正常合并。我假设你得到一个正常的合并。结果是:

           B1--B2--B3------M   <-- branch (HEAD)
          /               /
A1--A2--A3   <-- master  /
          \             /
           A4--A5-----A6   <-- origin/master, FETCH_HEAD
您正在告诉Git复制当前分支上的任何提交(即,
分支
),这些提交无法从名为
master
的分支访问,并且不是合并提交(您将复制可从合并访问的提交,但不会复制合并本身)。请注意,这不是使用
origin/master
,而是使用
master
。因此,您要求Git复制的提交是
B1
B2
、和
B3
、和
A4
A5
、和
A6
。。。以某种顺序(实际顺序有点难以预测,尽管A组和B组将一起复制,因为Git在收集要复制的提交的ID时使用
--topoorder

您要求Git复制它们的位置是“在
master
的提示之后”,即
A3
之后

如果Git首先复制
B1
,它通常会保持
B1
不变,因为
Git-rebase
会尽可能做到这一点。如果它首先复制
A4
,出于同样的原因,它还可以尝试保持
A4
不变;但这一机制却被这一特殊的再基础所阻碍(见下面的评论)。一旦Git通过
A6
复制了
A4
,它必须将
B1
复制到一个新的提交中,该提交的父项是
A6
的副本(此提交与原始的
B1
不同,因为
B1
的父项是
A3

(但是,您可以强制
git-rebase
进行复制,例如,使用
--no-ff
--force

您的结果表明您的Git选择先复制
A4
。这将为您提供:

           A4'-A5'-A6'-B1'-B2'-B3'  <-- branch
          /
A1--A2--A3   <-- master
          \
           A4--A5--A6   <-- origin/master
或者(可以而且有时确实)产生:


B1--B2--B3--A4'-A5'-A6'我总是建议人们在对git非常熟悉之前避免使用git pull
,因为它做得太多了,有点神秘,这很难解释。它通常(相当准确地)被描述为等同于运行
git fetch
,然后运行
git merge
git rebase
,但棘手的是,它传递给
git merge
git rebase
的参数并不是您所期望的

也就是说,让我们将这些分解,并仔细查看每个步骤。我还将以稍微不同的方式绘制提交图。(您在上面称之为“树”,这不是最好的术语,原因有二。首先,提交图是一个图,特别是一个D定向a循环G图或DAG。所有树都是DAG,但并非所有DAG都是树。其次,Git使用术语树来指代“树对象”;每个提交都携带一个树对象。)

我相信,您的初始提交图如下所示:

           B1--B2--B3   <-- branch (HEAD)
          /
A1--A2--A3   <-- master, origin/master
FETCH\u HEAD
中的内容有点棘手。该文件的内容包括原始名称,即,
master
和可能的
mastert
,如另一个Git上所示,没有任何
原始名称
           A4'-A5'-A6'-B1'-B2'-B3'  <-- branch
          /
A1--A2--A3   <-- master
          \
           A4--A5--A6   <-- origin/master
A1--A2--A3   <-- master
          \
           A4--A5--A6   <-- origin/master
                     \
                      B1'-B2'-B3'  <-- branch (HEAD)
           B1--B2--B3--A4'-A5'-A6'   <-- branch (HEAD)
          /
A1--A2--A3   <-- master
          \
           A4--A5--A6   <-- origin/master