When I’m working on a feature branch, I tend to want to cleanup the commits in the branch using an interactive rebase before my work is reviewed and integrated in the main branch.
During development of the feature, I want to push my intermediate work to the remote repository as a backup measure. I.e. when my hard-drive crashes, I don’t want my entire feature branch to be lost.
However, this leads to the fact that I often have to do a git push --force
to the remote repository after a rebase, an action which is generally frowned upon. Or as the linked github page says:
Because changing your commit history can make things
difficult for everyone else using the repository, it’s considered bad
practice to rebase commits when you’ve already pushed to a repository.
Is there a (generally accepted) policy that solves this conflict?
Why this is not a duplicate of Is the git “Golden Rule of Rebasing” so essential?
My question here asks for a policy to solve the conflict between wanting to backup your work in the remote repository and rebasing your work, while the other question tries to deny that there is a conflict and asks why some people think the conflict exists at all, and thus asks why “it is essential” not to push force rebases?
9
The key question to ask yourself:
- Do you keep your remote branch after merging back into master?
If you delete your remote feature branch after merging into master, you already are losing the history. Assuming you squash/rebase the branch prior to making your merge/PR you lose this history. All your force push is doing in this case is allowing you to use github as a backup.
The situation where you would want to keep the history and not force push is if your remote branch is persisting after being merged and not only existing for a temporary period of time.
I suppose you’re asking if I would keep the unrebased branch? No, AFAIC. Still, push forcing it might theoretically result in loss of commits from other users who pushed to the same branch
It sounds like you have multiple people pushing to that branch simultaneously. This means you do care about the history on the branch.
What you could do instead for your intermediate work is create a fork of that branch. You can push to this and then rebase all your commits into a single commit prior to merging, so when you merge them into your feature-branch, you only have 1 commit (with the rebased history of your entire branch).
5
I’m listing some possibilities here that cross my mind.
Always rebase on a new branch
When having a messy branch some-feature
, rebase it on a new branch. E.g.
$ git checkout -b some-feature-rebase
$ git rebase -i master # etc..
Then have some-feature-rebase
reviewed and integrated.
Problem: A big downside here is that, strictly speaking, you need a new branch for every rebase. (You could have multiple rebases if you make changes after a code review, for instance)
Use git push --force-with-lease
I just learned about the git push --force-with-lease
alternative to git push --force
, which
refuses to update a branch unless it is the state that we expect; i.e. nobody has updated the branch upstream.
Problem: This seems to improve directly upon the situation where we use just --force
, but still has some caveats, most notably when I do a git fetch
instead of a git pull
, which updates our local upstream branches, tricking --force-with-lease
into thinking that no unmerged changes were made on the remote branch.
2