【问题标题】:Git rebase instead of merge, the correct way to do it?Git rebase而不是merge,正确的方法是什么?
【发布时间】:2016-02-25 14:34:54
【问题描述】:

我想通过使用rebase 而不是merge 来避免远程存储库上的重复分支交叉点。

为了让您更好地理解我想要实现的目标,请考虑以下情况:

$ git lg
* 2345678 hotfix (HEAD -> master)
* 1234567 foo (origin/master, origin/HEAD)

$ git push 
! [rejected]  master -> master (fetch first)

$ git fetch
$ git lg 
* 2345678 hotfix (HEAD -> master)
| * 3456789 other change (origin/master, origin/HEAD)
|/
* 1234567 foo

通常,解决此问题的标准方法是 merge 后跟 push。

$ git merge origin/master
$ git lg
* 4567890 Merge remote-tracking branch 'origin/master'
|\
* |  2345678 hotfix (HEAD -> master)
| * 3456789 other change (origin/master, origin/HEAD)
|/
* 1234567 foo
$ git push

我不喜欢这种解决方案,因为在这种特殊情况下我可以轻松避免分支。所以,让我们用git reset --hard head~1 恢复更改并尝试另一种解决方案:

$ git rebase origin/master
First, rewinding head to replay your work on top of it...
Applying: hotfix

$ git lg
* 2345678 hotfix (master)
| * 5678901 hotfix (HEAD)
| * 3456789 other change (origin/master, origin/HEAD)
|/
* 1234567 foo

现在是令人不快的部分,我必须将我的 master 移回其 HEAD:

$ git branch -D master
$ git checkout -b master
$ git push
$ git branch --set-upstram-to=origin/master master
Branch master set up to track remote branch master from origin.
$ git lg 
* 5678901 hotfix (HEAD -> master, origin/master, origin/HEAD)
* 3456789 other change
* 1234567 foo

我的问题是如何简化我的rebase 并避免不愉快的部分?

【问题讨论】:

    标签: git merge rebase


    【解决方案1】:

    我想对接受的答案提出一种稍微不同的方法。无论如何,我很少使用pull 命令,但是当我这样做时,我的偏好是不要在没有我指定我希望变基的情况下自动变基。此外,也许它更罕见,但如果我真的希望进行合并提交怎么办?相反,我的偏好是设置我的配置,以便在无法进行快进时拉取失败,使用以下配置设置:

    [pull]
      ff = only
    

    这样我知道我总是可以安全地pull 并且它会快进,或者我会因为我的分支已经发散而收到错误。如果我收到错误,我可以决定是否要变基或合并(甚至重置到远程!),并相应地这样做。

    【讨论】:

      【解决方案2】:

      我认为最简单的方法是更改​​拉取工作流程。这里有几个选项。

      首先,您可以使用--rebase 标志拉动

      git pull --rebase
      

      根据文档,git pull 在其默认配置中执行fetch,后跟merge。使用--rebase 标志会将merge 替换为rebase :)

      其次,您可以使用git pull 设置默认值以始终执行此操作

      git config --global pull.rebase true
      

      我会推荐第一种方法,因为设置 rebase 的默认值会让我感到紧张。我为git pull --rebase 创建了一个别名git pr 以使其更容易。这样我就可以在每次拉取时做出决定。

      【讨论】:

        【解决方案3】:

        问题是你直接在本地的 master 分支上工作。当您对主分支进行一些本地更改并且在您开始之后还有上游更改时,您将遇到问题中描述的冲突。因此,避免这种情况的解决方案就是不直接在 master 分支上工作,而是在一个或多个其他本地分支上工作。

        因此,您将修补程序更改放在单独的分支上,例如 hotfix_branch,然后正常获取/拉取主分支(没有任何冲突!)。当您想要交付您的修补程序更改时,您可以重新设置 botfix 分支以保持在新拉出的主分支之上,将修补程序分支合并到主分支并推送。

        示例命令:

        $ git pull master
        $ git checkout -b hotfix_branch master
        $ $EDITOR some.file
        # Time passes and changes are made on origin/master
        $ git add some.file
        $ git commit -m "hotfix"
        $ git pull master                           # No conflicts sine master is "clean"
        $ git rebase master hotfix_branch      # This step might have merge conflicts but
                                               # if so those will come no matter what you
                                               # do with regards to branching
        $ git checkout master
        $ git merge hotfix_branch
        $ git push
        

        有一个很小的窗口,在您拉动和尝试推送主控之间可能会在原点/主控上发生新的变化,但如果是这样,您只需要这样做

        $ git checkout master                   # if not already on the master branch
        $ git reset origin/master
        

        然后从上面列表中的第二个pull master 命令重新开始。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-06-06
          • 2019-11-30
          • 2016-11-18
          • 2013-05-15
          • 2013-05-05
          • 2018-06-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多