我开始使用 git 一段时间后并没有完全理解其中的复杂性。我在这里的基本问题是找出 agit pull
和之间的区别git pull --rebase
,因为添加--rebase
选项似乎并没有做非常不同的事情:只是拉动。
请帮助我理解差异。
git pull
= git fetch
+git merge
反对跟踪上游分支
git pull --rebase
= git fetch
+git rebase
反对跟踪上游分支
如果您想知道如何git merge
和git rebase
不同,请阅读本文。
有时我们有一个上游来重新定位/重绕我们所依赖的分支。这可能是一个大问题——如果我们在下游,会给我们带来混乱的冲突。
神奇的是
git pull --rebase
一个普通的 git pull 大致是这样的(在所有这些示例中,我们将使用一个名为 origin 的远程分支和一个名为 foo 的分支):
# assume current checked out branch is "foo" git fetch origin git merge origin/foo
乍一看,您可能会认为 git pull --rebase 就是这样做的:
git fetch origin git rebase origin/foo
但是,如果上游 rebase 涉及任何“挤压”(这意味着提交的补丁 ID 发生了变化,而不仅仅是它们的顺序),那将无济于事。
这意味着 git pull --rebase 必须做更多的事情。这是对它的作用和方式的解释。
假设您的出发点是这样的:
a---b---c---d---e (origin/foo) (also your local "foo")
时间过去了,你已经在你自己的“foo”之上做了一些提交:
a---b---c---d---e---p---q---r (foo)
同时,出于反社会的愤怒,上游维护者不仅重新定义了他的“foo”,甚至还使用了一个或两个壁球。他的提交链现在看起来像这样:
a---b+c---d+e---f (origin/foo)
此时的 git pull 会导致混乱。甚至是 git fetch;git rebase origin/foo 不会削减它,因为在一侧提交“b”和“c”,而在另一侧提交“b+c”会发生冲突。(与 d、e 和 d+e 类似)。
git pull --rebase
在这种情况下,什么是:git fetch origin git rebase --onto origin/foo e foo
这给了你:
a---b+c---d+e---f---p'---q'---r' (foo)
您可能仍然会遇到冲突,但它们将是真正的冲突(在 p/q/r 和 a/b+c/d+e/f 之间),而不是由 b/c 与 b+c 冲突等引起的冲突。
答案取自(并稍作修改): http:
//gitolite.com/git-pull--rebase
假设您在本地分支中有两个提交:
D---E master
/
A---B---C---F origin/master
在“git pull”之后,将是:
D--------E
/ \
A---B---C---F----G master, origin/master
“git pull --rebase”之后,不会有合并点G。注意D和E变成不同的commits:
A---B---C---F---D'---E' master, origin/master
在最简单的没有碰撞的情况下
也可以看看:
man git-pull
更准确地说, git pull 使用给定的参数运行 git fetch 并调用 git merge 以将检索到的分支头合并到当前分支中。使用 --rebase,它运行 git rebase 而不是 git merge。
另请参阅:
我应该何时使用 git pull --rebase?
http://git-scm.com/book/en/Git-Branching-Rebase
为此,了解 Merge 和 Rebase 之间的区别很重要。
变基是更改应该如何从层次结构的顶部向下传递,合并是它们如何向上流动。
有关详细信息,请参阅 - http://www.derekgourlay.com/archives/428