【问题标题】:Overwriting and Pushing a Git Branch覆盖和推送 Git 分支
【发布时间】:2011-06-12 01:50:31
【问题描述】:

在将我的更改与上游 master 合并时,我经常发现自己在执行以下操作:

git checkout somefeature
git checkout -b integration
git rebase master # resolving conflicts along the way
git checkout somefeature
git merge integration # or rebase, doesn't matter in this example

我经常会发现将集成分支合并回我的功能分支会导致一些冲突。我的第一个问题是,“如果我的集成分支是某个功能的后代并且我已经解决了与上游主服务器的冲突,为什么会发生这种情况?”

如果您想知道我为什么一开始就使用集成分支,这是为了防止由于合并失败而污染当前分支。

我目前的解决方法是这样做:

git checkout integration
git branch -f somefeature # overwrite the branch

现在的问题是我无法将更改推送回远程分支:

git push origin somefeature
! [rejected]        somefeature -> somefeature (non-fast forward)

所以现在我必须删除远程分支并重新推送我的更改。这不是执行此操作的最佳方式,所以我想知道,“覆盖分支并将更改推送到远程分支的最佳方式是什么?”

【问题讨论】:

    标签: git


    【解决方案1】:

    问题是因为git rebase 生成了一系列新的提交,这些提交不是来自somefeature 分支,然后当您尝试将它们合并回somefeature 时,rebase 期间完成的冲突解决不会' t 申请。如果你只是合并而不是变基,那么这将作为合并提交somefeature分支下降。

    就推送到远程分支而言,您只需使用--force 即可使推送成功,但这会给拥有它副本的其他任何人带来问题。

    【讨论】:

    • 请注意,尽管您永远不应该更改已发布的提交,因为与您一起工作的其他人会遇到与您相同的问题,即他们已经在其存储库中重复但不兼容的提交。变基只要是本地的就很好,但是变基提交和重新发布它们是邪恶的——因此 Git 的 “rejected” 错误(它很聪明,并且注意到你可能做错了什么)。
    • 啊,我使用合并是为了方便逐步解决冲突,而不考虑提交不会是 somefeature 分支的后代。接受这是我问题的真实答案。非常感谢!
    【解决方案2】:

    您可以使用git merge -s recursive -Xtheirs,它将自动解决冲突以支持集成分支。但是,这仍然会进行合并,并且可能无法很好地处理移动的文件等。

    但是,由于您的分支已被推送,因此您有理由希望保留其历史记录。要获得您想要的理想行为,您可以在集成分支中使用“我们的”策略。

    git checkout somefeature
    git checkout -b integration
    git rebase master # resolving conflicts along the way
    git merge -s ours somefeature # mark integration as superseding the somefeature branch
    git checkout somefeature
    git merge integration # this is now a fast-forward, no conflicts
    

    【讨论】:

    • 但是,一般来说,Nemo157 的解决方案更好——对于在非本地 repo 中发布的功能分支,只需从一开始就使用合并而不是 rebase。这就是 git 的工作原理。
    • 我不知道“我们的”合并策略。这看起来像我一直在寻找的解决方案。谢谢!
    【解决方案3】:

    您可以确保您的最终合并使用合并驱动程序覆盖目标分支:
    例如,请参见“Can I tell git pull to overwrite instead of merge?”。

    这个想法是有一个custom merge driver with a "keepTheir" script

    【讨论】:

      【解决方案4】:

      你的第一个操作很奇怪。您制作了某个功能的副本。您将其重新设置为针对大师。然后你回到那个特性,把它和它自己的rebased equivelant 合并。这不是做事的方式。

      不要把事情弄得太复杂。如果您希望功能分支从其他地方开始(例如最新的 master),只需重新设置它。

      然后用--force(或-f)推动它。告诉正在使用该功能分支的其他任何人,他们必须获取更改并调整他们在本地尚未推送的任何内容。

      在其他人一直在努力的情况下,合并会更好。

      希望这会有所帮助。

      【讨论】:

      • 呃,我的印象是,复制一些功能,然后将其与 master 合并是一种简单的方法,可以合并两个分支,而不会与任何一个原始分支混为一谈。我想最好只做一个标准的变基。谢谢。
      • 你可以合并它。你试图同时做这两件事。这就是问题所在。如果您想合并到 master 或 rebase 到 master,这取决于您。一个产生线性历史,另一个保留您分支的点。你的选择。如果您采用变基路线,除了可能“移动某人的奶酪”之外,您可能还有更多的冲突需要解决。
      猜你喜欢
      • 1970-01-01
      • 2019-08-10
      • 2010-11-07
      • 1970-01-01
      • 2012-01-11
      • 2015-02-08
      • 1970-01-01
      • 1970-01-01
      • 2011-09-10
      相关资源
      最近更新 更多