开发者

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 a feature-tmp branch (that you create where feature is), you will still have the feature branch in place!
    (because the features HEAD would still reference those "old" commits before and rebase or squash)
  • then you would git checkout feature (which is still there), and git merge -s ours master back to feature (that way and subsequent merge or rebase will only consider features commits from after that first rebase or merge)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜