I often use git rebase -i
to clean up my history before publishing it. Usually I want to edit commits back to wherever the current branch forked off, without changing its fork point. I do it something like this: git rebase -i $(git show-branch --merge-base $PARENT_BRANCH HEAD)
It's an ugly command and I'm trying to find a better way. As long as I'm at it, I'd like to have git automatically figure out the right parent.
I think what I want is an alias for git rebase -i --fork-point $(something)
, where something
finds the branch with the most recent common ancestor of the current branch. It doesn't need to be bulletproof. If it works for a linear topic branch, that's good enough for my purposes.
If you use pull requests as part of your code review process, you need to avoid using git rebase after creating the pull request. As soon as you make the pull request, other developers will be looking at your commits, which means that it's a public branch.
Never rebase a commit that somebody else might have based their work on. Only change your own local history. Don't rebase anything that you've already pushed to an upstream branch.
With Git 2.24 (Q4 2019), no more git rebase -i --onto @{upstream}...HEAD
The new "git rebase --keep-base <upstream>
" tries to find the original base of the topic being rebased and rebase on top of that same base, which is useful when running the "git rebase -i
" (and its limited variant "git rebase -x
").
The command also has learned to fast-forward in more cases where it can instead of replaying to recreate identical commits.
See commit 414d924, commit 4effc5b, commit c0efb4c, commit 2b318aa (27 Aug 2019), and commit 793ac7e, commit 359eceb (25 Aug 2019) by Denton Liu (Denton-L
).
Helped-by: Eric Sunshine (sunshineco
), Junio C Hamano (gitster
), Ævar Arnfjörð Bjarmason (avar
), and Johannes Schindelin (dscho
).
See commit 6330209, commit c9efc21 (27 Aug 2019), and commit 4336d36 (25 Aug 2019) by Ævar Arnfjörð Bjarmason (avar
).
Helped-by: Eric Sunshine (sunshineco
), Junio C Hamano (gitster
), Ævar Arnfjörð Bjarmason (avar
), and Johannes Schindelin (dscho
).
(Merged by Junio C Hamano -- gitster
-- in commit 640f9cd, 30 Sep 2019)
rebase: teach rebase
--keep-base
A common scenario is if a user is working on a topic branch and they wish to make some changes to intermediate commits or autosquash, they would run something such as
git rebase -i --onto master... master
in order to preserve the merge base.
This is useful when contributing a patch series to the Git mailing list, one often starts on top of the current 'master
'.
While developing the patches, 'master
' is also developed further and it is sometimes not the best idea to keep rebasing on top of 'master', but to keep the base commit as-is.In addition to this, a user wishing to test individual commits in a topic branch without changing anything may run
git rebase -x ./test.sh master... master
Since rebasing onto the merge base of the branch and the upstream is such a common case, introduce the
--keep-base
option as a shortcut.This allows us to rewrite the above as
git rebase -i --keep-base master
and:
git rebase -x ./test.sh --keep-base master
respectively.
git rebase
man page now includes:
--keep-base
:
Set the starting point at which to create the new commits to the merge base of
<upstream> <branch>
.
Running 'git rebase --keep-base <upstream> <branch>
' is equivalent to running 'git rebase --onto <upstream>... <upstream>
'.This option is useful in the case where one is developing a feature on top of an upstream branch.
While the feature is being worked on, the upstream branch may advance and it may not be the best idea to keep rebasing on top of the upstream but to keep the base commit as-is.Although both this option and
--fork-point
find the merge base between<upstream> and <branch>
, this option uses the merge base as the starting point on which new commits will be created, whereas--fork-point
uses the merge base to determine the set of commits which will be rebased.
mvds suggests in the comments combining this with git rebase --reapply-cherry-picks
In my workflow, to develop a minimal binary patch for firmware written in C, I need to go back to a certain commit hash, make a branch, perform modifications and find differences in the resulting binary.
In the time since that certain commit, our compiler was upgraded and became smarter, turning the codebase into non-compiling code.
To remedy this, I cherry-pick any commits needed to be able to compile again.
Those cherry-picked commits will mess up the magic done by--keep-base
, unless--reapply-cherry-picks
is used.
The debate is on the Git mailing-list
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