简体   繁体   中英

Git: rebasing a branch

I'm trying to make sense of rebasing in Git and have a question whether or not it's good practice to use rebasing in this scenario:

I have a branch called 'feature' which is branched off from another branch called 'develop'. I have made several commits in 'feature' but haven't merged with 'develop' yet because the feature is still in being developed, nor have the commits in 'feature' been pushed to the remote repository.

If I now checkout 'develop' to make a few amends, is it wise to rebase it to the 'feature' branch so that 'develop' is in sync with 'feature'?

I would rebase 'feature' on 'develop' (assuming, of course, that 'feature' is a local branch)

Merging 'develop' into 'feature' would create a redundant merge commit. But doing the rebase integrates all changes from master and lets you resolve all conflicts before 'feature' is ready to be merged with 'develop', without creating any extra commit.

There are certainly those who disagree . But I like a clean, readable history. What I often do is that when I'm finished with the feature, I rebase , and then I merge --no-ff . That way the history still clearly shows that there has been a feature branch:

- * - * - - - - - - - * - * -
       \             /
        * - * - * - *

The thing is that I like to resolve conflicts "continuously". Whenever there is a conflict I want to know about it early so I can resolve it before it gets cumbersome to do so (analogous to the reasons for continuous integration). If I would follow that strategy that using frequent merging, I would have a lot of merge commits. With frequent rebases I can avoid them.

There is an alternative strategy that lets you use merging but without merge commits - you can turn on git rerere:

git config --global rerere.enabled true

As described in this article , you can then do intermediate merges, resolve conflicts, and then reset the merge commit. The rerere feature will make Git remember the conflict resolution when you do the final merge of the 'feature' branch.

Adding all the commits to feature

The following will result in all the commits made on the develop branch since the split being applied to the feature branch, without affecting develop .

Current state:

M1---M2---D1--D2--T1--T2  develop
      \
       F1--F2  feature

Option 1: merge develop into feature
git checkout feature; git merge develop

M1---M2---D1--D2--T1--T2  develop
      \                \
       F1--F2-----------F3  feature

Option 2 (originally suggested by Klas Mellbourn): rebase feature onto develop
git checkout feature; git rebase develop

M1---M2---D1--D2--T1--T2  develop
                       \
                        F1'--F2'  feature

The rebase creates a nicer history but it is problematic if there are other commits based on feature . In your case there aren't, so it is not a problem.

Adding some commits to feature

If you cannot do the above (maybe the commits D1 and D2 are not ready to make their way into feature yet) you can use git cherry-pick to copy the commits over to feature :

M1---M2---D1--D2--T1--T2  develop
      \
       F1--F2--T1'--T2'  feature

A git rebase would move the commits, not copy them.

Separate topic branch

An alternative workflow is to make the new commits in a new topic branch based on an early common ancestor:

       T1--T2  topic
      /
M1---M2---D1--D2  develop
      \
       F1--F2  feature

With such a graph topic could me merged into both develop and feature without introducing unwanted or duplicate commits.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM