git:合并分支但保留提交历史
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28550602/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
git: Merge Branches but Keep Commit History
提问by Samuel
In my git workflow we have one main repository and one branch, master. Everyone pulls from remote master and everyone pushes to remote master. I want to work in my own branch while I prepare a feature. So far my history is something like this:
在我的 git 工作流程中,我们有一个主存储库和一个分支 master。每个人都从远程主人拉,每个人都推到远程主人。我想在准备功能的同时在自己的分支中工作。到目前为止,我的历史是这样的:
git pull --rebase
git checkout -b new_feature
<make some commits>
git checkout master
git pull --rebase
Now I want to merge the branch and here's what I need:
现在我想合并分支,这是我需要的:
- No merge commits in my local master branch.
- All commits made into my new_feature branch merged into master as if I had made them in master.
- All merged commits to be merged somewhere on top of my local remote head pointer.
- 我的本地主分支中没有合并提交。
- 在我的 new_feature 分支中所做的所有提交都合并到 master 中,就像我在 master 中所做的一样。
- 所有合并的提交都将合并到我本地远程头指针之上的某处。
My biggest concern is item 3, when is needed so that I can safely push the changes. If the merged commits are intertwined with commits before head then I will have problems pushing, see related problem I had: git: Pushing Single Commits, Reordering with rebase, Duplicate Commits.
我最关心的是第 3 项,什么时候需要,以便我可以安全地推送更改。如果合并的提交在 head 之前与提交交织在一起,那么我将遇到推送问题,请参阅我遇到的相关问题:git: Pushing Single Commits, Reordering with rebase, Duplicate Comits。
I've read the following:
我已阅读以下内容:
- http://mettadore.com/2011/05/06/a-simple-git-rebase-workflow-explained/
- Keep commits history after a 'git merge'
- How do you rebase the current branch's changes on top of changes being merged in?
- http://mettadore.com/2011/05/06/a-simple-git-rebase-workflow-explained/
- 在“git合并”后保留提交历史
- 您如何在合并的更改之上重新设置当前分支的更改?
And I think I need to do:
我认为我需要这样做:
git checkout master
git pull --rebase
git checkout new_feature
git rebase master
git checkout master
git rebase new_feature
git push
My understanding is that
我的理解是
git checkout new_feature
git rebase master
will make new_feature appear as if it was branched off from the new current head. Is that true? And that
将使 new_feature 看起来好像它是从新的当前头部分支出来的。真的吗?然后
git checkout master
git rebase new_feature
will place new_feature on top of master. Is that correct? If so, this is the main point of my confusion. If "git rebase master" places master commits at the bottom of new_feature, then why does "git rebase new_feature" place new_feature commits at the top of master, i.e. why doesn't it do the opposite?
将 new_feature 放在 master 之上。那是对的吗?如果是这样,这就是我的主要困惑点。如果“git rebase master”将 master 提交放在 new_feature 的底部,那么为什么“git rebase new_feature”将 new_feature 提交放在 master 的顶部,即为什么不做相反的事情?
回答by Shaun Luttin
Answer
回答
Here is a workflow that you can use that does just what you need it to do.
这是一个您可以使用的工作流程,它可以满足您的需求。
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)
Explanation
解释
(1) git pull --rebase
will first fetch origin/master
and then replay your local master
on top of it. Note in the example log that your local commits are on top of your "local remote HEAD pointer."
(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.
You can now checkout
and work on your new_feature
branch for a while. When you're done...
您现在checkout
可以在您的new_feature
分支上工作一段时间。当你完成...
(2) git rebase master
will replay new_feature
on top of master
. Again, your local commits remain on top of your "local remote HEAD pointer."
(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.
The rebase
command just put new_feature
ahead of master, and to align them you need to run...
该rebase
命令只是放在new_feature
master 之前,要对齐它们,您需要运行...
(3) git merge new_feature
, which will do a fast-forward merge. Now HEAD
, new_feature
, and master
all point to the same commit.
(3) git merge new_feature
,这将进行快进合并。现在HEAD
、new_feature
和master
都指向同一个提交。
> 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) After that, you can safely delete the new_feature
branch. Your final log before pushing will look like this:
(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.
回答by Dan Fischer
It's unnecessary to run git rebase new_feature
on the master branch after you've run git rebase master
on the new_feature branch. After you've run git rebase master
on the new_feature branch, you can then merge new_feature into master - it will be a fast-forward merge and won't introduce a merge commit.
在 new_feature 分支上git rebase new_feature
运行后,没有必要在 master 分支上运行git rebase master
。在git rebase master
new_feature 分支上运行后,您可以将 new_feature 合并到 master - 这将是一个快进合并,不会引入合并提交。
The reason why git rebase new-feature
isn't playing all the new-feature commits on top of master is because git recognizes master already is at the base of new feature - we performed that step with git rebase master
- and that it would just be rebasing on itself. So instead it just fast-forwards to new-feature.
之所以git rebase new-feature
不在 master 之上播放所有新功能提交的原因是因为 git 识别 master 已经在新功能的基础上 - 我们执行了这一步git rebase master
- 并且它只会重新建立在自己的基础上。因此,它只是快进到新功能。
Also, you don't need to worry about pushing commits that reside below your remote/master tip -- the remote will reject your push should you try (unless you provide the -f option, which, don't). And, if your local master is tracking your remote master, git status
will tell if your local has diverged from you remote branch.
此外,您无需担心推送驻留在远程/主提示下方的提交——如果您尝试,远程将拒绝您的推送(除非您提供 -f 选项,否则)。并且,如果您的本地 master 正在跟踪您的远程 master,git status
将判断您的本地是否与您的远程分支分开。