git rebase and sharing a feature branch?

2020-07-26 06:05发布

问题:

Based on this: https://www.atlassian.com/git/tutorials/rewriting-history/git-rebase

git rebase will make it possible to maintain a linear history (a merge "always" results in a fast-forward)

But if I want to enforce a linear history and require developers to always rebase their feature branches on latest master will that not result in collaboration/sharing feature branches going out the window? See:

Don't rebase public history

so is it possible to enforce linear history using git rebase and at the same time allow multiple developers to contribute to the same feature branch?

Or will git rebase imply that there can only be one owner of a feature branch?

回答1:

"Don't rebase public history" is a good starter rule. More comprehensive advice is, if you're going to rebase a shared branch, you need the agreement/cooperation of everyone who has a copy of it.

(At this point usually someone likes to jump in and object that sometimes getting everyone's consent isn't practical. What they're trying to say is that the rule is too strict; but that's like saying the speed of light is too slow because I need to travel faster. The correct analysis is that yes, sometimes you can't get everyone on board; and in those cases you shouldn't rebase. Hence the simplified "don't rebase public history". If you don't have the cooperation of everyone who shares the branch, it's unsafe to rebase the branch and your attempt to do it could easily end up being accidentally undone. But I'm digressing...)

So, if it's a team norm that after people have collaborated on the branch, and you're ready to merge it, you're going to rebase it and everybody is going to throw away their local copy of the branch, then it's ok - you have everyone's cooperation with the rebase.

But that doesn't necessarily mean it's a good idea. The marketing literature for rebase likes to talk up linear histories as "simpler", but leaves out that your shiny new linear history is made mostly of code states that have never been tested (which can mess up attempts to bug-hunt with bisect). Some projects find value in preserving the commit topology, so e.g. they can look back on a feature branch as a unit rather than just having to figure out that commits K through N happen to have been a feature branch at one time.

But all that's up to you/your team. If you think a linear history is what suits you, then yes, it can be done even when feature branches are shared, so long as you'd discard them after merging anyway (which... why wouldn't you?).



回答2:

Yes, it is possible. Although a certain amount of caution is advised.

With the rebase, a feature branches changes are added to the main development line. This should happen after review (in GitLab/GitHub speak: after a Merge/Pull Request is accepted). Thus, the development before does not necessarily involve any earlier rebases; the feature branch may have been shared, worked on and commited to by multiple developers.

Don't rebase public history

This usually means that you should not rebase commits that other people may have based their work on (like master or develop branches of public repositories). Since no one should base their work on a finished-but-not-yet-merged feature branch, this does not apply in your case.



回答3:

I assume your question stems from the common workflow of having one central git repository instead of private forks. On that remote repository all the branches can be pushed form all the developers. And just because they can, each developer may feel empowered to just push and merge whatever they want. With such a workflow, git rebase can indeed become dangerous as developers might delete commits due force pushing accidentally deleting commits that already have been pushed.

If you have this cowboy git workflow going on, then it may be sensible to advise developers to use --force-with-lease instead of just --force.

I would argue that collaboration and sharing feature branches going out the window is a good thing.

In my team's main remote git repository (the source of truth) I have master branch protected against rebases.

I recommend these rules:

  • always derive a feature branch from master, no exceptions
  • again: never derive a feature branch of another feature branch
  • if you depend on another feature currently being developed by another dev, wait for them to merge those changes into the master
  • rebase your feature branch against master often (to include your dependencies, or to just keep the master up to date) as it helps to resolve merge conflicts as they happen
  • optional: squash your commits to one, if you use a git web-frontend (github, bitbucket, ...) they provide the feature to merge squash a Pull Request, you may want to use that as well

The developer creating the branch owns the branch. They can do whatever they want: deleting, rebasing, tango merging, working with others in pair programming on this branch (others might still commit on their branch but only with the owner's explicit consent and knowledge).

The main branches, e.g. master or develop, are the public ones. They are holy. You don't change their history and you protect them from being deleted and their history from being overwritten. If you need to undo a feature on the main branch, you'll use revert.



回答4:

I would suggest you can encourage (rather than enforce) a linear history by asking developers to rebase their feature branches as the final step before peer review.

This would allow developers to collaborate, cross-merge and be happy with the feature, before a final rewrite of the history that will make for easy reading by a reviewer.

Of course, this still carries the risk of rebasing public history, and can cause issues for developers who are less familiar with such practices. This is why I would encourage rebasing for those who are comfortable with it, but not enforce it.