git rebase origin/develop与git rebase develop的区别

22

假设当前的分支是MyFeatureX,本地的develop分支与远程仓库同步。下面两条语句是否等价? 建议使用哪种语法?

git rebase origin/develop 
git rebase develop 

请注意:这个问题与git rebase origin vs.git rebase origin/master不是同一个问题。


这似乎是与您链接的问题完全相同。第二个答案可能对您的情况最有帮助。 - Andy Ray
1
它们为什么相似?我没有名为“origin”的分支。在我的设置中,“origin”是一个别名,表示远程存储库(通过“git remote -v”查看)。在这里,我的问题是“develop”是一个本地分支,它正在跟踪远程的“origin/develop”分支。 - Polymerase
哦,你说得对,那个问题确实是一个不寻常的使用案例,我误读成了另一种情况。虽然在技术细节上基本上是相同的。 - Andy Ray
我刚刚在另一个问题上发表了评论,但这是Git过于棘手/狡猾的又一个地方。通常,“origin”是远程名称(因此缩写为URL),但在gitrevisions符号中,“origin”代表“origin/HEAD”,这就是Git称为符号引用的东西,即另一个名称的名称! - torek
3个回答

31

你的本地分支 develop 追踪 origin/develop,它们可能不总是包含相同的提交记录。

$ cat ~/.git/config

[remote "origin"]
    url = git@something.com/repo.git
    fetch = +refs/heads/*:refs/remotes/origin/*
这意味着我们有一个任意命名为“origin”的“远程”代码库(即存储在其他地方的代码库)。
您本地的develop分支正在跟踪该远程代码库中的分支,并且有一个称为origin/develop的本地引用指向该数据。在大多数情况下,我们认为这两件事始终包含相同的提交记录。然而,您需要明确地更新本地的develop分支以获取来自origin的最新数据。这通常通过拉取操作完成:
$ git status
    on branch develop
$ git pull
    ...pulls latest changes from origin

然而,git pull实际上包含两个步骤,fetchmerge。它在幕后执行的第一步是从源头获取最新的所有提交,这可以使用以下命令完成:

git fetch origin

这将更新分支origin/develop,但不会更新本地分支develop

最新的提交在你的本地.git目录中隐藏,你可以从名为“origin/develop”的分支引用它。

在一次fetch之后,要想使本地分支origin实际更新,需要执行git merge origin/develop。技术上来说,这不是一次合并,而是一个“快进”,意味着git足够智能,可以使本地的origin分支与origin/develop相匹配,而不必合并任何内容。出于这个原因和其他原因,在git中进行合并时让我感到很紧张。

因此,如果你基于develop进行rebase,有可能比origin/develop还要过期(旧)。

在进行rebase之前,我个人会按照以下工作流程操作:

git fetch --all
git rebase origin/branchname

这意味着我可以在不考虑自己处于哪个分支的情况下,将所有数据下载,并基于远程仓库中最新的代码进行变基。稍后,在develop分支上执行一个简单的git pull就可以确保你的代码是最新的。


关于本地和远程分支同步机制的学术解释很好。我很高兴你们确认 git rebase origin/develop 等价于 git rebase develop。只要我注意保持它们同步即可。我会遵循你们的建议,使用 origin/develop 引用。也许这是显而易见的,所以 git rebase 没有提到如何处理“baseBranch”的细节。但对于一个 rebase 新手来说,这相当令人困惑。 - Polymerase

4
如果develop指向与origin/develop相同的提交,则这两个命令完全相同。如果我忘记更新本地的develop(假设此分支最终将被推送到origin/develop),我倾向于使用origin/develop

1

正如我在回答你之前的另一个问题为什么"rebase --onto ABC"和"rebase ABC"不同?中所写的那样,这两个命令都关闭了--fork-point模式,因此——只要developorigin/develop解析到相同的提交哈希值,就像你的问题前提中一样——这两个命令将执行相同的操作。

省略<upstream>参数会默认打开--fork-point,并且分支配置的上游的引用日志可能包含大量数据。在这种情况下,它们可能会有很大的区别。通过添加显式的--no-fork-point,您可以防止git merge-base --fork-point删除已删除的上游提交。


非常酷,特别是你对我其他关于rebase --onto问题的回答。请给我一些时间来理解那个--fork-point的东西。 - Polymerase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接