Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I rebase master onto a branch that's been pushed?

We use the feature branch workflow in our small team of developers. We're currently working on a large project, so one of the developers has pushed their feature branch to origin, where everyone else can checkout their own local copy.

[leonard@dev public]$ git branch -avv
  master                        9d53b40 [origin/master] Fix reviews
* responsive                    0c04643 [origin/responsive] Add media queries
  remotes/origin/HEAD           -> origin/master
  remotes/origin/master         9d53b40 Fix reviews
  remotes/origin/responsive     0c04643 Add media queries

When developing on master, we create feature branches (i.e. master_hotfix), then when we're ready to merge it in we first rebase master on to it before doing so. This gives us a nice linear history that we prefer. We thought this would be the best way to do this with our responsive project too, so we would create a new branch (i.e. responsive_some-feature) based on the responsive branch. The same git pull, git rebase responsive responsive_some-feature can then be used here, too.

But we're a bit confused as to whether we should (and if so, at what point) rebase master on to responsive? Before the responsive branch was pushed to origin, rebasing master on to it was simple, but is rebasing master to responsive then responsive to responsive_some-feature correct? When I do, I see (along with a few conflicts) this:

# On branch responsive
# Your branch and 'origin/responsive' have diverged,
# and have 112 and 109 different commit(s) each, respectively.
#
nothing to commit (working directory clean)

Usually at this point I see a clean working directory, where I can then checkout master and merge my feature branch in. Alas, after this rebase the commits from master are in there, with the new commits in responsive coming after them, correctly, but is this the right method? How should I proceed, or should I use a different method to keep responsive up to date with master?

Edit: I've made a graphic to illustrate my workflow better:

like image 650
LeonardChallis Avatar asked Jan 21 '16 08:01

LeonardChallis


People also ask

Should I merge master into my branch or rebase?

Merging is a safe option that preserves the entire history of your repository, while rebasing creates a linear history by moving your feature branch onto the tip of main .

Can I rebase master into branch?

One way to integrate branch updates and changes into the master is through a merge. Another way is to perform a master to branch rebase. The benefit of the latter is the clean, linear, non-branched commit history that elutes.

When should you avoid rebasing a branch?

1 Answer. Show activity on this post. Case 1: We should not do Rebase on branch that is public, i.e. if you are not alone working on that branch and branch exists locally as well as remotely rebasing is not a good choice on such branches and it can cause bubble commits.


1 Answers

TLDR

Should I rebase master onto a branch that's been pushed?

No, you should follow the general rule - never rewrite the public history (= never rebase branch that's been pushed).

In the case of simple feature branches, you are able to rebase them (rewrite history) before the push. Or, at least, you can be sure that only one developer works with the feature branch and do forced push if you have branches have diverged situation.

In the case of the responsive branch, it is public and used by many developers. So you can not rebase it on top of master, do the regular merge for this branch.

Note: as mentioned in the comments, you have a bit confusing terminology in your post. So I assume that ...we first rebase master on to it [feature branch]... actually means the opposite and you rebase feature branches on top of master.

Explanation

The "normal" (no history rewrite) flow with feature branches look like this:

1) we have a feature branch 

... O ---- O ---- A ---- B  master
                   \
                    C       feature-branch

2) we do the merge, usually with merge commit (D)
   sometimes it can be fast-forward without the merge commit

... O ---- O ---- A -- B -- D -  master
                   \       /
                    -- C --      feature-branch

The flow with re-base:

1) we have a feature branch 

... O ---- O ---- A ---- B  master
                   \
                    C       feature-branch

2) we rebase feature branch on top of master
   note, that we changed the history and have new C' commit on 
   the feature branch

... O ---- O ---- A ---- B  master
                          \
                           C'  branch_xxx (feature branch)

3) we do the merge, master is fast-forwarded since there is nothing new
   on master

... O ---- O ---- A -- B -- C' -  master (fast forwarded)
                        \  /
                         C'      feature-branch

It works good if there is only one developer who works on the feature branch. So the history rewrite is safe.

But when you add your responsive branch in, the flow, as I understand, is this:

1) we have a feature branch 

... O ---- O ---- A ---- B       master
                   \
                    R1 -- R2     responsive
                           \
                            F1   responsive-feature-branch

2) now see what happens if `responsive-feature-branch` is still active (someone works on it) and we rebase the `responsive` on top of `master`:

... O ---- O ---- A ---- B                master
                  \       \
                   \       R1' -- R2'     responsive'
                    \
                     R1 -- R2             responsive
                            \
                             F1           responsive-feature-branch

Do you see the problem? Now you have two responsive branches which are diverged (see also explanation in my post).

You can push the rebased responsive' using '-f' (force) flag, but what will the developer who works on the responsive-feature-branch do? He'll just have the new upstream history and will have to rewrite his-own local history accordingly.

You can do this forced update if you are sure that nobody have active branches derived from responsive and everyone will need then update their local repos.

But I don't recommend this, because you can't guarantee that there are no active sub-branches and someday you'll definitely find that your repository has messed up. I think that pretty linear history not worth the time you'll need to spend on resolving these issues.

like image 66
Boris Serebrov Avatar answered Sep 20 '22 19:09

Boris Serebrov