git rebase 'magic' needed to keep commit history
How do I do get from:
master: A - B - C - D -------------- F - G - H
\ / \
feature: A' - B' - C' D' - F' - G'
to:
master: A - B - C - D -------------- F - G - H
\ / \
feature: A' - B' - C' D' - F' - G'
? Basically removing the A'-C'-F history, doing a rebase of D'-G' from F to H, then adding it back. It would be SO USEFUL.
Here are more details on why I want this. I use a feature branch when I work. My workflow:
master: A - B - C - D
\
feature: A' - B' - C'
When I'm done with my feature, i do git rebase master
then either git rebase -i master
, or from master git merge --squash feature
and then push it to master as one nice commit.
I get:
master: A - B - C - D - F
\
feature: A' - B' - C'
Where F is just A', B', and C' squashed together. All is good. But then I want to continue working on the same feature branch. I haven't figured out how to do it. I could do:
feature2: D' - E' - 开发者_Python百科F'
/
master: A - B - C - D - F
\
feature(archive): A' - B' - C'
Which is annoying. Doing merge --squash then merging master and feature would get:
master: A - B - C - D -------------- F - G - H
\ / \
feature: A' - B' - C' D' - F' - G'
Help me get to this:
master: A - B - C - D -------------- F - G - H
\ / \
feature: A' - B' - C' D' - F' - G'
So then I could push to master like:
master: A - B - C - D -------------- F - G - H ------------ I
\ / \ /
feature: A' - B' - C' D' - F' - G'
and repeat the cycle.
Last figure, for a comment.
master: A - B - C - D -------------- merge - F - G - H
\ / \
feature: A' - B' - C' ---- merge - D' - F' - G'`
I think you're overthinking things. Your first example is easily done simply by doing git rebase master
on the feature branch. The A' B' C'
bit is common history, so rebase ignores it.
The problem may be that you're squashing to create F
. If you want to keep A' - B' - C'
in the history, don't squash - just git merge
. If you want to get rid of the intermediate commits, well, go ahead and squash, but then you have to throw away those commits and git reset --hard master
on the feature branch to get back to a history that can be merged with the master.
The OP Mihai comments:
Is there any way to have it go both ways? It would be awesome for master to have stable & logical commits, but to be able to keep the details for myself.
Why yes, there is in theory (Even though Blair Holloway already gave compelling reason to not to ;) ).
You need to remember that Git never change/erase/override the history of commits. It only make new ones.
So if:
- instead to rebase/merge squashing your
feature
branch, you rebase or merge afeature-tmp
branch (that you create wherefeature
is), you will still have thefeature
branch in place!
(because thefeatures
HEAD would still reference those "old" commits before and rebase or squash) - then you would
git checkout feature
(which is still there), andgit merge -s ours master
back tofeature
(that way and subsequent merge or rebase will only consider features commits from after that first rebase or merge)
精彩评论