为什么将“远程跟踪分支机构“起源/开发”合并为开发”?


125

我是组织中唯一使用以下消息进行提交的人:

将远程跟踪分支“起源/开发”合并为开发

不知道我在做什么导致他们,但我想停下来。

我正在发出什么命令来创建此提交,不应该产生该命令的正确命令是什么?


1
理查德·汉森(Richard Hansen)的回答很好。但是我认为这可能会使初学者感到困惑。我的解决方案是继续执行pull --rebase,但是为了避免危险,我在pull之前存储了更改。然后,在拉动之后,我将其应用。我解决冲突。最后,我可以提交并推送。
约翰·约翰'17

是否git pull --autostash --rebase为你工作@Johnjohn?
sourcedelica

Answers:


206

git pull可能正在创建提交。如果您进行本地提交然后运行git pull在其他人将提交推送到存储库,则Git将下载其他开发人员的提交,然后将其合并到本地分支中。

将来如何避免这些合并提交

您可以使用它git pull --rebase来防止将来发生这种情况,但是重新定级存在其危险,我建议pull完全避免使用

相反,我鼓励您遵循以下使用模式:

# download the latest commits
git remote update -p

# update the local branch
git merge --ff-only @{u}

# if the above fails with a complaint that the local branch has
# diverged:
git rebase -p @{u}

说明

  • git remote update -p下载远程存储库中的所有提交并更新远程跟踪分支(例如origin/master)。它不会碰到您的工作目录,索引或本地分支。

    所述-p参数梅干删除上游分支。因此,如果foo分支在origin存储库中git remote update -p删除,则会自动删除您的origin/foo引用。

  • git merge --ff-only @{u}告诉Git将上游分支(@{u}参数)合并到您的本地分支中,但前提是您的本地分支可以“快速转发”到上游分支(换句话说,如果没有分支)。

  • git rebase -p @{u}有效地移动了您已经提交但尚未推送到上游分支顶部的提交,从而消除了创建您要避免的愚蠢合并提交的需要。这改善了开发历史的线性度,使其更易于查看。

    -p选项告诉Git保留合并。这可以防止Git将重新提交的提交线性化。例如,如果您将功能分支合并到中,则这一点很重要master。如果没有-p,则特征分支上的每次提交都会被复制,master作为线性化的一部分git rebase。这将使开发历史更难以审核,而不是更容易。

    当心git rebase可能未达到预期的效果,因此请在推送前检查结果。例如:

    git log --graph --oneline --decorate --date-order --color --boundary @{u}..
    

git pull --rebase与以下原因相比,我更喜欢这种方法:

  • 它允许您在修改历史记录以合并它们之前查看传入的上游提交
  • 如果需要重新建立有意合并的基础(例如,将已经按下的要素分支合并到中),则可以使用-p--preserve-merges)选项。git rebasemaster

速记: git up代替git pull

为了简化上述操作,建议您创建一个别名up

git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'

现在,使分支保持最新状态所需要做的就是运行:

git up

代替git pull。如果由于本地分支机构与上游分支机构不同而出现错误,则可以根据需要进行调整。

为什么不git pull --rebase呢?

Running git pull --rebase等同于运行git fetch后跟git rebase。这将尝试快进到新的上游提交,但是如果这不可能,那么它将把本地提交重新建立到新的上游提交上。通常可以,但是请注意:

  • 变基是一个高级主题,变基之前您应该了解其含义。
  • git pull --rebase并没有给您机会在合并之前检查提交。根据什么改变后的上行,这很可能是重订是错误的操作,一rebase --ontomergereset,或者push -f可能比普通的更合适rebase
  • 无法(当前)传递--preserve-merges给rebase操作,因此要素分支的任何有意合并将被线性化,从而重放(并因此重复)所有要素分支的提交。

“修复”由...创建的现有合并提交 git pull

如果尚未推送由创建的合并提交git pull,则可以使合并提交变基。假设您没有进行任何有意的合并(例如,将已经按下的功能分支合并到当前分支中),则应执行以下操作:

git rebase @{u}

上面的命令告诉Git选择从HEAD(当前提交)可以到达的所有非合并提交,减去从@{u}(可以是“上游分支”的简写,即,origin/master如果HEADmaster)的所有提交,重播(cherry-pick )将它们放在上游分支的顶部,然后将当前分支引用移至指向重播提交的结果。这有效地将非合并提交移动到最新的上游提交,从而消除了由创建的合并git pull

如果您有意进行合并提交,则您不想运行git rebase @{u}它,因为它会重播另一个分支中的所有内容。处理这种情况实际上要复杂得多,这就是为什么最好使用git upgit pull完全避免使用它的原因。您可能必须使用reset撤消由创建的合并pull,然后再执行git rebase -p @{u}。该-p给的说法git rebase并没有可靠地为我工作,所以你可能最终不得不使用reset撤消故意合并,更新您的本地分支@{u},然后重做故意合并(这是一个痛苦,如果有很多毛茸茸的合并冲突)。


+1用于讨论--preserve-merges,除非您实际上没有在告诉他运行的命令中记录该内容,因此是-1。
塞斯·罗伯逊

@Seth:感谢您的评论;我更新了建议的答案-p。我避免过推荐它,因为它不是很经常需要使用,并且其行为也没有得到很好的记录。
理查德·汉森

3
git remote update -p和之间的区别是git fetch什么?
eckes 2013年

3
@eckes: git remote update -p与相同git fetch --all -pgit remote update -pfetch没有-p选择时,我习惯于使用回来。
理查德·汉森

1
@ user1914692:合并完成后,Git将更新本地分支以指向新创建的合并提交,而不是与远程分支相同的提交。这个新的合并提交是问题所在,尤其是在推送时。
理查德·汉森

18
git fetch
git rebase origin/master

那应该做。或者,如果您想继续使用拉

git pull --rebase

您还可以在配置中将该分支设置为自动变基,或者为以后创建的任何其他跟踪分支自动进行该设置。然后,您可以返回到仅使用

git pull

可以在本页的“使用rebase而不是merge进行合并”部分中进一步了解此内容:

http://mislav.uniqpath.com/2010/07/git-tips/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.