Roughly speaking, this changes (assuming 3 upstream PRs)
git merge <upstream-commit1> <upstream-commit-2> <upstream-commit3>
into
git merge <upstream-commit3>
This is more intuitive. We're merging a single upstream revision, namely
<upstream-commit3>. The other two commits are simply parents of that one,
i.e., they're included anyway, and git merge ignores them.
(In fact, passing multiple refs looks like we're doing an octopus
merge. It's just that git recognizes the fact that everything is included
in the last ref anyway, and behaves as if only the last one had been passed.)
This commit also makes some further clean ups and improvements.
I believe it was introduced to cherry-pick upstream PRs, but that simply
doesn't work. Assume upstream is two PRs A and B ahead, and A has been
merged before B. Then trying to cherry-picking B by merging the state of
upstream's master after the merge-B commit won't do what we expect. In
particular, the merge result will *include A's changes* because A had
already been merged in upstream's master when B was merged.
(One could think that merging the PR branch of B instead works, but this
will yield the same result if B was rebased on master before it was
merged.)
The proper way to cherry-pick B is to create a PR that cherry-picks all
commits that had been included in B. This could be done automatically,
but the need to cherry-pick a PR is rare enough that we don't need tool
support for it. In fact, because we want to keep cherry-picking at a
minimum, there's a good chance that we'd anyway want to pick only a
subset of the commits in a upstream PR, and that would need manual work
anyway.
This makes it possible to use sync-upstream with uncommitted changes. (This
is in particular helpful when working on the script itself.)
Without this commit, git pull will fail due to the uncommitted changes.