如何在主分支上更新话题分支与上游更改?

10

我在一个专题分支上开始一些工作

    •-•-• < topic
   /
•-•       < master

我推送了主题分支

$ git push origin topic

有其他人向主干提交更改

    •-•-• < origin/topic
   /
•-•-•—•   < origin/master

如何更新本地主分支并将我的话题(topic)进行变基(rebase)?

历史记录应该是这样的

        •-•-• < topic
       /
•-•-•—•       < master

我所尝试的事情

; update master
$ git checkout master
$ git fetch origin
$ git merge --ff-only origin/master

; rebase topic
$ git checkout topic
$ git rebase master

问题

我在topic上的所有提交都被视为未提交。因此,当我尝试执行git push origin topic时,会得到以下提示:

 ! [rejected]        topic -> topic (non-fast-forward)
error: failed to push some refs to '/path/to/repo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

解决方案?

请注意,我不想将我的topic分支与master合并。我只想在不必要地合并分支的情况下更新我的本地存储库。

3个回答

16

让我重新编写你的例子以增加清晰度。

    C-D-E < topic, origin/topic
   /
A-B < master, origin/master

接着有人开始工作。

    C-D-E < topic, origin/topic
   /
A-B-F-G < origin/master
  ^
master

你从源代码中获取了F和G,然后将topic(分支)基于master(主分支)进行了变基。现在你的仓库看起来像这样。

    C-D-E < origin/topic
   /
A-B-F-G < master, origin/master
       \
        C'-D'-E' < topic

这就是问题所在。无法将源/话题从E快进到E'。重新设置基础实际上只适用于尚未推送到源的提交。由于您已经将C、D和E推送到了源/话题,您将不得不重写远程仓库的历史记录。因此出现了错误。因此,您真正有三个选择:

  1. 停止推送主题分支。如果只有您在处理主题,则没有必要将其推送。只需将主题与主干进行重新设置,并在完成后将主干合并到主题并推送主干。删除本地主题分支。大功告成!

  2. 合并主题和主干。如果您需要在主题分支上进行协作,则应该将其合并。

  3. 强制远程重新设置基础:

    git push origin topic -f

    这将强制 origin/topic 到 E'。但是通过修改远程仓库中的历史记录,您将可能引发祸端,甚至会导致严重问题。您的同事可能也不会喜欢你。绝对不建议这样做。


1
终于有些东西让人感到有意义了。非常感谢您的时间 <3 - Mulan
2
主题分支被重新设置并强制推送是相当常见的。您需要确保人们了解您的主题分支是您的私有历史记录,这在GitHub分支中通常是如此。 - febeling
1
我认为#1可能需要一些微调。针对@febeling的观点,我认为现在大多数公司的代码库都希望开发人员不断推送他们的WIP分支,因为这提供了自动备份,并且使得团队成员可以提出拉取请求协作建议。因此,在工作环境中重新设置个人分支并强制推送是非常标准的做法。 - TTT

5
; update master
git checkout master
git pull --rebase origin master  

; rebase topic
git rebase master topic

; push topic (force)
git push -f origin topic

请提供一下说明吗? - Mulan
我的pull命令与你的fetch和merge序列完全相同。然后我只需用一个命令进行变基。由于历史记录将被重写,因此您必须提供-f标志。 - the.malkolm
我只是很难想象将主分支(master)在origin/master上进行变基(rebase)会是什么样子... 我猜我只是不理解,而且我不想在没有完全理解它们的情况下运行可能危险的命令来操作我的代码库 :S - Mulan
如果您的本地主分支没有任何更改,那么将主分支在 origin/master 之上进行变基操作只会是一个快进式操作。 - the.malkolm
似乎您的本地主分支尚未推送更改。 - the.malkolm
显示剩余2条评论

0

你的问题存在一些问题。

  1. 当你推送时,不会出现合并冲突。这只会在合并、变基、樱桃拣选或隐藏弹出/应用时发生。
  2. 如果其他人与你同时更改相同的内容(即使只是你在另一个副本上工作),则无法避免冲突
  3. “我的所有主题提交都被视为未提交”没有意义。你可能想说的是,“我的主题分支提交引入的所有更改”由于在尝试变基时出现冲突而尚未提交。

你的步骤是正确的,除了你忽略了你的变基已停止在冲突上,而你只是忽略了它。你必须解决你的冲突,然后:

git add confilctedfile1.txt conflictedfile2.txt
git rebase --continue

你可能需要对主题分支中的所有提交都执行此操作。只有在重新设置完成后才应该推送。

另一个注意点:因此,重新设置不是日常工作的首选工作流程。合并更容易且更准确地了解代码库中正在发生的情况。有许多理由支持合并而不是重新设置。


1). 我的错误;当我尝试推送时,出现了快进错误。 2) 我不是在谈论解决开发人员更改相同内容的冲突。我只想要我的存储库更新...这太令人沮丧了:S - Mulan
无论是你还是其他开发者,对于代码仓库来说,它看起来就像是同时进行的更改。请了解有向无环图(DAG)以了解git的工作原理。 - Adam Dymitruk
这并不是同时更改...我甚至使用了两个虚拟代码库进行测试,结果也相同。 - Mulan
如果没有同时更改,那么您根本不需要重新基于。在更改代码之前,请使用git pull --ff-only。 - Adam Dymitruk
当您进行推送操作时,您将不会遇到合并冲突。只有在合并、变基、挑选或弹出/应用存储时才可能发生这种情况。我认为这是因为主题和源/主题已经分歧所致。 - Mike Monkiewicz

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