git:合并分支但保持提交历史记录

时间:2015-02-16 21:23:32

标签: git version-control branch history rebase

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

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

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

  1. 我的本地主分支中没有合并提交。
  2. 我的new_feature分支中的所有提交都合并为master,就好像我是在master中一样。
  3. 所有合并提交将合并到我的本地远程头指针顶部。
  4. 我最关心的是第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的顶部,即为什么不执行相反的操作呢?

2 个答案:

答案 0 :(得分:24)

答案

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

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将在new_feature之上重播master。同样,您的本地提交仍然位于“本地远程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.

答案 1 :(得分:6)

在new_feature分支上运行git rebase new_feature后,在主分支上运行git rebase master是不必要的。在new_feature分支上运行git rebase master之后,您可以将new_feature合并到master中 - 它将是一个快进合并,并且不会引入合并提交。

git rebase new-feature没有在主人之上播放所有新功能提交的原因是因为git识别master已经位于新功能的基础上 - 我们使用{{1}执行了该步骤 - 而且它本身就是变基础。因此,它只是快速转发到新功能。

此外,您不必担心推送位于您的遥控器/主机提示下方的提交 - 如果您尝试,遥控器将拒绝您的推送(除非您提供-f选项,其中,不要&#39 ; T)。并且,如果您的本地主人正在跟踪您的远程主人,git rebase master将告知您的本地人是否与您的远程分支分道扬。