【问题标题】:What is the correct way to merge upstream without losing changes?在不丢失更改的情况下合并上游的正确方法是什么?
【发布时间】:2013-01-07 15:48:55
【问题描述】:

我有点吃不消。

几个月前,我开始在 repo 的一个分支上进行开发。我做了一些改变。我正准备将我的代码作为拉取请求推送回主服务器,但我意识到在此期间发生了很多变化......

所以,following the instructions at Github 在“拉入上游更改”下我试过了:

$ git remote add upstream ...  # savon/httpi
$ git fetch upstream
$ git merge upstream/master
$ git push origin/master       # coldnebo/httpi

但是,现在我的叉子很乱。我仍然是 git 的新手,所以与其试图猜测术语是什么,我将简单地向您展示我得到了什么以及我所期望的:

这是我想要的差异。有什么方法可以在不丢失更改的情况下重新设置/还原并执行此操作?

真是一团糟。

也许git pull 会更好?

变化不多,所以如果无法恢复,我总是可以手动比较并重新制作它,但我正在寻找“正确的方法”来做这件事。

【问题讨论】:

    标签: git github


    【解决方案1】:

    您应该始终为您创建的每个 Pull Request 创建新分支。在将其推送到 github 以创建请求之前,您应该将您的分支重新设置为最新的上游分支。

    Github 说您为此使用 git merge,如果没有太多更改,我更喜欢使用 git rebase upstream/master,这将阻止 合并提交


    有时变基无法继续,因为您所做的更改已在上游分支中更改。例如,假设您有一个 text.txtfile,例如:

    Lorem ipsum
    

    您创建一个 PR 以将其更新为 Lorem ipsum! 并且上游分支已将其更改为 Hello World 如果您进行变基,以在创建请求之前使您的代码保持最新,您会遇到合并冲突。该文件使用冲突标记进行更新,您可以选择要使用的版本,甚至可以对其进行编辑,在我们的示例中,我们在text.txt 中得到了这个:

    <<<<<<< YOUR_PR_BRANCH
    Lorem Ipsum
    =======
    Hello World
    >>>>>>> THE_UPSTREAM_BRANCH
    

    在此之后,使用git add 添加更新的文件并执行git rebase --continue

    【讨论】:

    • 为什么要阻止合并提交?你让他们听起来像是错误的或邪恶的?
    • @CharlesBailey 合并提交并不邪恶,但它们是您工作流程中最无用和最模糊的提交。 rebase 的另一个特性是它保留历史记录,它不会将所有新的提交放在你的提交之前/之后,它会将那些放在它们需要的地方。
    • 我认为您可能误解了合并提交和历史记录。当您将两个(或更多)并行工作流合并在一起时,合并提交正确记录。 Rebase 掩盖了真实的历史,因为它将原始更改与合并相结合,并假装您在历史上的不同点进行了原始更改,而不是您实际所做的更改。 Rebase 除了保留历史之外什么都做。我不确定是什么让你说合并提交是模糊的或无用的;他们准确地准确记录了合并中所做的事情,绝对不是模糊的,并且可能非常有用。
    • 我真的很喜欢这个讨论,它触及了我从文档中得到的一些困惑。所以我提交拉取请求的主要目标是允许上游维护者只审查我的更改,因为他们已经知道他们的更改。我的问题是这是一个 git 进程问题(即使用 rebase)还是一个 diff 审查问题(使用合并提交,但是使用其他一些技术将新提交与审查中的其他提交分开)?我更愿意先用 git 做事,然后再考虑 github 进程的工件,但欢迎任何观点。
    【解决方案2】:

    好的,如果你的 repo 是 fubar,那么这里是恢复的步骤:

    $ git remote update     # make sure origin and upstream are up to date
    $ git checkout master
    $ git branch my_changes   # just to make sure my stuff isn't lost
    $ git reset --hard upstream/master
    $ git status
    # On branch master
    # Your branch is behind 'origin/master' by 8 commits, and can be fast-forwarded.
    #
    

    忽略那个快进废话,它对你没有帮助,只需重置主人。

    $ git push origin +master   # now, fork matches upstream/master
    

    现在,如何恢复之前的工作以便进行复习?

    $ git diff --no-ext-diff --no-prefix master..my_changes > patchfile
    $ patch -p0 < patchfile   # apply the patchfile to master
    $ git diff     # to verify patch visually.
    $ rm patchfile   # clean up
    $ rake spec      # verify that it really works.
    $ git add .
    $ git status     # double triple verify
    $ git commit .
    $ git push origin master
    

    这太糟糕了。我尝试做rebase,但它一直说“没有变化”并且没有要求我检查任何东西?我很确定我不明白这里发生了什么,这就是为什么我发布了我的斗争,以便有人可以解释我如何避免这种混乱并更优雅地从 A 到 B ,因为它已被完整记录。我愿意将此归咎于 git 缺乏经验,但我认为拉动更改应该是 git 中非常普遍的事情——我一定遗漏了一些东西。

    【讨论】:

      【解决方案3】:

      git pull --rebase 为我工作并保持历史整洁。

      【讨论】:

      • 错误:无法使用 rebase 拉取:您有未暂存的更改。
      • 在拉取之前添加git stash,在拉取之后添加git stash pop
      猜你喜欢
      • 2020-11-26
      • 2011-12-20
      • 2016-09-17
      • 1970-01-01
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多