3

I've been using git for a while, but still do not understand how to deal with feature branches.

When you develop in a feature branch in a strictly local manner everything makes sense. You commit, merge upstream, rebase on master and finally push everything.

Things change with feature branch being pushed to a remote early on. Now you can't squish, rebase, etc. You simply can't change history for other devs. Sure, that's a correct behaviour.

So no pushing to remote? Everything is just local? A filesystem dies and your branch goes with it? One random deletion of .git... This doesn't sound correct.

Any recommendations?

  • A feature branch implies a main branch, so you'd be dealing with two remote branches. – RandomUs1r Dec 5 '18 at 22:23
2

You can change public branches. You usually shouldn't because this makes life difficult for other people if they are also using that branch. They would have to rebase their work on top of your revised history. Many Git users would have no idea what to do if git pull stops because of a merge conflict.

Branches like master that are used as a starting point for other branches are holy, and rewriting their history is a big no-no. But feature branches are not meant to be used by other people. They are meant to be worked on, merged, and deleted.

So whether rewriting the history of a branch is acceptable depends on the social contract around that branch. Within an organization, nothing beats talking with coworkers if you try to collaborate on a branch. For a pull request based workflow, the expectation might actually be that you rewrite the branch history during the review process so that the history is always nice and compact, without many fixup commits.

This touches on the question what a Git log should represent: is it just a record of what changed when? Or is it a story that explains what was changed for which reason? No one creates a masterpiece on on first try: good stories need editing. When I review pull requests, I vastly prefer PRs that have an organized, readable history instead of PRs that show all the dead ends and problems that were encountered during development.

A force-push is not necessarily an anti-pattern. The need for a force push is merely a warning sign that you are trying to perform a destructive operation. In most cases git push --force-with-lease should be preferred as it ensures that you do not destroy commits that you did no know about.

  • Thanks for this detailed answer. It kinda helps to sort thoughts about the process. Also thanks for the git push --force-with-lease tip. – Yuri Jan 18 at 11:59
2

The golden rule of git rebase is to never use it on public branches. See merging-vs-rebasing

Briefly: git rebase change history of commits, so use it on your own branch which is not used by any other developer. Then you can push it to remote for backup purposes.

git merge introduces new commit combining history of two branches so it's ideal for branches shared among multiple developers.

  • Yea, this is written in every single git guide. The problem is defining [a branch] not used by any other developer. – Yuri Dec 6 '18 at 6:46
  • @Yuri So telling other developers not to touch your private branch? E.g. by convention [dev-yuri-private-mess]. Or does the problem appear if you rebase and push the private branch to the remote repo even the private branch isn't used by other developers? – Tomas Kulhanek Dec 6 '18 at 16:38
  • The problem originates from the distributed nature of git. It doesn't really track if any other dev checks out the private branch. – Yuri Dec 6 '18 at 17:16
2

The general recommendation is just to not use history-changing operations on public branches. However, feature branches are supposed to be short-lived. They are generally worked on by one person, or by two or three people working extremely closely, such that the occasional force push can be easily communicated and resolved. When I work in a team like that, I will usually just use merges, then if we think it's needed, do a squash or rebase just before submitting the pull request.

If you're really paranoid about someone merging your branch in an unfinished state and not communicating with you, you can always create a private fork in your profile area, and make it visible only to those you specifically designate.

  • Force pushes sound like an anti-pattern. So not sharing a remote branch with other devs means you have to develop it in a separate remote and push it to the upstream one when it is finished. That solves the merging an unfinished branch problem. However, you still have to force push stuff when rebasing, squishing, etc. Am I right? – Yuri Dec 6 '18 at 6:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.