git: merge 分支但保留提交历史

标签 git version-control branch history rebase

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

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

现在我想 merge 分支,这是我需要的:

  1. 在我的本地 master 分支中没有 merge 提交。
  2. 我的 new_feature 分支中的所有提交都 merge 到 master 中,就像我在 master 中所做的一样。
  3. 所有 merge 的提交都将 merge 到我的本地远程头指针之上的某处。

我最关心的是第 3 项,何时需要以便我可以安全地推送更改。如果 merge 的提交与 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 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,这将进行快进 merge 。现在 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: merge 分支但保留提交历史,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28550602/

相关文章:

git-svn:什么相当于 `svn switch --relocate` ?

Git checkout 'virtual'分支

git - Git 如何获取分支的数据?

git - 在不同的 GIT-Repos 中同步 2 个文件夹

version-control - Sourcesafe 从 Visual Studio 按标签获取

mercurial - 我可以将分支标记为 'not going to push'吗?

git - 将 .gitignore 的一部分保留在版本控制下,但将另一部分保留在版本控制之下

git - 在 ubuntu 12.04 服务器上为 gitolite 设置公钥的错误

git - 使 zsh 自动更正与自定义 git 别名一起工作

git - 如何在 RubyMine 中更改过去的 git commit+push 消息?