【问题标题】:git: Merge Branches but Keep Commit Historygit:合并分支但保留提交历史
【发布时间】:2015-04-17 12:07:58
【问题描述】:

在我的 git 工作流程中,我们有一个主存储库和一个分支,master。每个人都从远程 master 拉取,每个人都向远程 master 推送。在准备功能时,我想在自己的分支中工作。到目前为止,我的历史是这样的:

git pull --rebase
git checkout -b new_feature
<make some commits>
git checkout master
git pull --rebase

现在我想合并分支,这就是我需要的:

  1. 我的本地 master 分支中没有合并提交。
  2. 在我的 new_feature 分支中所做的所有提交都合并到 master 中,就像我在 master 中所做的一样。
  3. 所有合并的提交都将在我的本地远程头指针顶部的某个地方合并。

我最关心的是第 3 项,何时需要我可以安全地推送更改。如果合并的提交与 head 之前的提交交织在一起,那么我将在推送时遇到问题,请参阅我遇到的相关问题:git: Pushing Single Commits, Reordering with rebase, Duplicate Commits

我已阅读以下内容:

我认为我需要这样做:

git checkout master
git pull --rebase
git checkout new_feature
git rebase master
git checkout master
git rebase new_feature
git push

我的理解是

git checkout new_feature
git rebase master

将使 new_feature 看起来好像它是从新的当前头部分支出来的。真的吗?还有那个

git checkout master
git rebase new_feature

将 new_feature 放在 master 之上。那是对的吗?如果是这样,这就是我困惑的重点。如果 "git rebase master" 将 master 提交放在 new_feature 的底部,那么为什么 "git rebase new_feature" 将 new_feature 提交放在 master 的顶部,即为什么它不做相反的事情?

【问题讨论】:

    标签: git version-control branch history rebase


    【解决方案1】:

    回答

    这是一个您可以使用的工作流程,它可以满足您的需要。

    git checkout master
    git pull --rebase                             (1)
    git checkout new_feature                      
    <do a bunch of commits>
    git rebase master                             (2)
    git checkout master
    git merge new_feature                         (3)
    git branch -D new_feature                     (4)
    

    说明

    (1) git pull --rebase 将首先获取origin/master,然后在其上重放您的本地master。请注意,在示例日志中,您的本地提交位于“本地远程 HEAD 指针”之上。

    > git log --oneline --all -10 --decorate
    
    d34d34c (HEAD, master) Local commit message.
    d3434r2 Local commit message.
    d234d4c Local commit message.
    er3ede3 (origin/master, origin/HEAD) Remote commit message.
    sfe3fd3 Remote commit message.
    

    您现在可以checkout 并在您的new_feature 分支上工作一段时间。完成后...

    (2) git rebase master 将在 master 之上重播 new_feature。同样,您的本地提交仍位于“本地远程 HEAD 指针”之上。

    > git log --oneline --all -10 --decorate
    
    fc5773d (new_feature) Local new_feature commit.
    9282838 Local new_feature commit.
    d34d34c (HEAD, master) Local commit.
    d3434r2 Local commit.
    d234d4c Local commit.
    er3ede3 (origin/master, origin/HEAD) Remote commit.
    sfe3fd3 Remote commit.
    

    rebase 命令只是将 new_feature 放在 master 之前,要对齐它们,您需要运行...

    (3) git merge new_feature,它将进行快进合并。现在HEADnew_featuremaster 都指向同一个提交。

    > git log --oneline --all -10 --decorate
    
    fc5773d (HEAD, new_feature, master) Local new_feature commit.
    9282838 Local new_feature commit.
    d34d34c Local commit.
    d3434r2 Local commit.
    d234d4c Local commit.
    er3ede3 (origin/master, origin/HEAD) Remote commit.
    sfe3fd3 Remote commit.
    

    (4) 之后,您可以安全地删除new_feature 分支。推送前的最终日志如下所示:

    > git log --oneline --all -10 --decorate
    
    fc5773d (HEAD, master) Local new_feature commit 2
    9282838 Local new_feature commit.
    d34d34c Local commit.
    d3434r2 Local commit.
    d234d4c Local commit.
    er3ede3 (origin/master, origin/HEAD) Remote commit.
    sfe3fd3 Remote commit.
    

    【讨论】:

    • 优秀的答案!我认为“git checkout new_feature”需要 -b 标志(除非分支已经存在)。您引用了我对“本地远程 HEAD 指针”的使用,正确的术语是什么?
    • @Samuel 是的。除非new_feature 分支已经存在,否则您将需要-b 选项。
    • @Samuel 我会使用“远程 HEAD 引用”而不是“本地远程 HEAD 指针”。请参阅页面底部附近的git-scm.com/book/en/v2/Git-Internals-Git-References
    【解决方案2】:

    在 new_feature 分支上运行 git rebase master 后,无需在 master 分支上运行 git rebase new_feature。在 new_feature 分支上运行 git rebase master 后,您可以将 new_feature 合并到 master - 这将是一个快进合并,不会引入合并提交。

    git rebase new-feature 没有在 master 之上执行所有新功能提交的原因是 git 识别 master 已经是新功能的基础 - 我们使用 git rebase master 执行了该步骤 - 它会只是重新建立自己的基础。因此,它只是快进到新功能。

    此外,您无需担心推送位于远程/主提示下方的提交——如果您尝试,远程将拒绝您的推送(除非您提供 -f 选项,否则不要)。而且,如果您的本地 master 正在跟踪您的远程 master,git status 将告诉您本地是否与您的远程分支分道扬镳。

    【讨论】:

    • 很好的答案,快进合并是关键。谢谢!
    猜你喜欢
    • 2014-06-29
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    • 2019-07-28
    • 2011-11-08
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多