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:
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 .
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With