1

I recently switched to a new employer where we work in much larger teams and we work with multiple developers on features. Following the workflow as described in Vincent Driessen's A successful Git branching model I'm a bit confused as to how to deal with merge/rebase when working on these shared features.

At my previous employer I would create my own (local) feature branches which I'd rebase daily from the master. Over here it is common practice to publish the feature branch and pull in the changes from the others. Most All of my colleagues use the default git pull settings (which results in a merge, polluting the branch history with pull-merges). I personally prefer to use the pull.rebase = preserve setting to keep the history clean but this might not work well with their method.

I'm quite confused as to what is the proper method of dealing with this. I am aware that I shouldn't rebase published branches so I'm looking for some feedback.

What is the proper way of doing this? I was thinking about creating a single branch per feature (feature-XXX) and then have each developer create their own (local) branch from the feature branch(local-XXX). They can do their work normally and then using --ff-only merge their changes back into the feature-XXX branch (after rebasing local-XXX).

This leaves me wondering: how can I keep the feature-XXX from going stale? Do I merge the master back into it on a regular basis? Or do I rebase it from time to time? And what effect would that have on the branches of my colleagues?

Another Stackoverflow post mentions merge master on a regular basis into feature-XXX and only before the merge rebase it.

Community
  • 1
  • 1
Toolmaker
  • 554
  • 6
  • 22

1 Answers1

2

I'm not sure your local branches are adding any real value. I'm assuming the reason you want them is so that you can adhere to the letter of a team policy that says "push your feature branches"; but if you're moving work that they expect will be on those feature branches to a "local" branch, then you aren't adhering to the spirit of the policy. On the other hand, if you aren't actually required to push your feature branch work, then there's no need for the local branch at all. (I'll explain why in a minute.)

As the "new guy" joining an environment where the characteristics of the project that drive workflow are different from your past experience, I would encourage you to spend some time working within this group's established procedures. If nothing else, this will give you experience with the down-sides of their approach (from which to build a case if you want to convince the team to change). (I have to say, though, that if "merge commits are pollution" is the whole crux of your argument, I would at best be in the "don't care" camp for that debate. But I digress...)

Anyway, you said something about not rebasing branches that have been pushed, and that's almost right. (It's a decent rule of thumb, and it will keep you out of trouble.) A more refined rule would be, "don't rebase in a way that removes a commit that's been pushed". Or "don't rebase in a way that moves a remote ref to a commit from which its previous commit isn't reachable".

So if you're on a shared branch, but you don't push your local work, then you would be safe using rebase-based pulls because the only commits being rewritten are your local ones (to place them "after" the fetched remote ones). The down side to this is that if you have multiple local commits that you don't want to squash, and you don't want to risk pushing an intermediate state that would break the build, then you have to test each such intermediate commit. (And IMO "broken commits" - even if intermediate - are worse "pollution" than merge commits.)

Logically, if you created your "local" branches, work wouldn't get shared until you rebased them onto the main feature branch anyway, so it's really six of one and half dozen of the other. Once you've pushed a commit, you can no longer rebase it, but if you've consistently done rebase-based pulls, then it won't matter.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • Recapping what you said: I can continue to do rebase-based pulls without too much issues. Once I pushed my commits they become part of the upstream branch's history graph and rebasing won't do anything since its part of the graph. How about merging in work from say, the master? Would we continually merge work from the master into our (published) feature branches or would we rebase? Or, as said in the second link from my post, continually merge in the master and right before merging our changes into the master rebase the feature branch? – Toolmaker Mar 14 '17 at 07:59
  • 1
    If a branch is long-lived, I periodically merge master to it. There's really not a great way to do this with rebase. You could do "squash merges", but then when you finally merge the feature branch back to master you'll get a lot of pointless conflicts. Some people don't like "uselessly repeated" merges from master, and if you're in that camp you could look at git rerere (which allows you to do the merge, test things, back the merge out, then later redo the merge without manually re-resolving conflicts). The problem IMO is this again makes you prone to broken commits, but it's an option. – Mark Adelsberger Mar 14 '17 at 12:48