Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does `git rebase` skip the commit which its change already has in upstream?

Tags:

git

git-rebase

git-rebase document says:

If the upstream branch already contains a change you have made (e.g., because you mailed a patch which was applied upstream), then that commit will be skipped.

But how does Git do that?

Assume any commit X is the parent of commit Y, and diffXY is the result of git diff X Y command. And I have following commits:

o---o---o        <- master
 \
  o---o---o---o  <- test <- HEAD

If I do a git rebase master. Then I guess Git does the skipping commit already have in master by skipping any commit Y in test that diffXY already have in master.

I've ran some examples and they were like what I guessed.

This is just my guess, am I right?

Plus, does Git do this skipping task before Git do the reapplying test's commits onto the master?

like image 846
Phuc Avatar asked Dec 13 '22 14:12

Phuc


1 Answers

The first versions of git rebase (1.4.4, Oct. 2006) were using git format --ignore-if-in-upstream

This will examine all patches reachable from <since> but not from <until> and compare them with the patches being generated, and any patch that matches is ignored.

So it was looking at the patch ids: See commit 9c6efa3 for the implementation.

 if (ignore_if_in_upstream &&
    !get_patch_id(commit, &patch_id_opts, sha1) &&
     lookup_object(sha1))
     continue;

A "patch ID" is nothing but a sum of SHA-1 of the file diffs associated with a patch, with whitespace and line numbers ignored.
As such, it's "reasonably stable", but at the same time also reasonably unique, i.e., two patches that have the same "patch ID" are almost guaranteed to be the same thing.

That was later delegated to git rebase-am (Git 1.7.6, Feb. 2011)

And commit b6266dc, Git 2.1.0, Jul. 2014 used --cherry-pick instead of --ignore-if-in-upstream

When using git format-patch --ignore-if-in-upstream we are only allowed to give a single revision range.
In the next commit we will want to add an additional exclusion revision in order to handle fork points correctly, so convert git-rebase--am to use a symmetric difference with --cherry-pick --right-only.

(Further improved in Git 2.18)

That does not change the "skip identical commit" mechanism.


As explained above, "git rebase"(man) by default skips changes that are equivalent to commits that are already in the history the branch is rebased onto;

But with Git 2.34, this is now clearer, as it gives messages when this happens to let the users be aware of skipped commits, and also teach them how to tell "rebase" to keep duplicated changes.

See commit 767a4ca (30 Aug 2021) by Josh Steadmon (steadmon).
(Merged by Junio C Hamano -- gitster -- in commit 6c083b7, 10 Sep 2021)

sequencer: advise if skipping cherry-picked commit

Signed-off-by: Josh Steadmon

Silently skipping commits when rebasing with --no-reapply-cherry-picks (currently the default behavior) can cause user confusion.
Issue warnings when this happens, as well as advice on how to preserve the skipped commits.

These warnings and advice are displayed only when using the (default) "merge" rebase backend.

Update the git-rebase(man) docs to mention the warnings and advice.

git config now includes in its man page:

skippedCherryPicks

Shown when git rebase skips a commit that has already been cherry-picked onto the upstream branch.

git rebase now includes in its man page:

will be skipped and warnings will be issued (if the merge backend is used).
For example, running git rebase master on the following history (in which A' and A introduce the same set of changes, but have different committer information):

git rebase now includes in its man page:

When using the merge backend, warnings will be issued for each dropped commit (unless --quiet is given).
Advice will also be issued unless advice.skippedCherryPicks is set to false (see git config).

So you will now see:

skipped previously applied commit xxx
use --reapply-cherry-picks to include skipped commits
like image 105
VonC Avatar answered Dec 17 '22 22:12

VonC