vijay
vijay

Reputation: 177

merge from commit to commit

I have a commits in my branch MASTER

1.commit 4930da17d8dd23d650ed38435d8b421816a0c451
  Date:   Sat Dec 5 14:34:18 2015 +0530

2.commit e1ebbbb599ee20ebec3ca92c26266d9fd16e7ccc
  Date:   Sat Dec 5 13:22:20 2015 +0530

3.commit e1721686be4be1eaf1618e199c70477c1383068f
  Merge: b1fdca0 51c7c21
  Date:   Sat Dec 5 12:11:50 2015 +0530

4.commit b4ab3c164a3a8d93e0a71a94b5c561cb5e20ebf6
  Date:   Sat Dec 5 12:09:56 2015 +0530

5.commit 167b1d10258381f09663ce61fa88ce3bbcd404c4
  Merge: 88f01ad 5ed302b
  Date:   Sat Dec 5 12:09:21 2015 +0530

6.commit c61bcadac673e1c83f4c14b66d56e23b12fa3198
  Date:   Sat Dec 5 12:07:58 2015 +0530

I have another branch called TEST_MASTER

Now I want to merge from 3rd commit to 6th commit, from the branch MASTER to TEST_MASTER. Means

3.commit e1721686be4be1eaf1618e199c70477c1383068f
  Merge: b1fdca0 51c7c21
  Date:   Sat Dec 5 12:11:50 2015 +0530

4.commit b4ab3c164a3a8d93e0a71a94b5c561cb5e20ebf6
  Date:   Sat Dec 5 12:09:56 2015 +0530

5.commit 167b1d10258381f09663ce61fa88ce3bbcd404c4
  Merge: 88f01ad 5ed302b
  Date:   Sat Dec 5 12:09:21 2015 +0530

6.commit c61bcadac673e1c83f4c14b66d56e23b12fa3198
  Date:   Sat Dec 5 12:07:58 2015 +0530

Cherry-pick I tried, It is working.

In my case I have nearly 100 commits, Is there any other way to do merge like

from <commit-id> to to <commit-id>

Upvotes: 1

Views: 854

Answers (1)

VonC
VonC

Reputation: 1323115

As I explained in "How to cherry pick a range of commits and merge into another branch", you can use git cherry-pick to merge a range of commits, not just commit by commit.

If you want to pick the range B through D (inclusive) that would be git cherry-pick B^..D

That does allow you to merge "from <commit-id> to <commit-id>"


The OP reports that a range revert fails with:

Commit xxx is a merge but no -m option was given. fatal: cherry-pick failed.

And when trying to chose a non-merge commit:

git cherry-pick -m 1 <non-merge-commit>^..<sha1> 
  error: Mainline was specified but commit <xxx> is not a merge.  
  fatal: cherry-pick failed

That last message won't be there with Git 2.21 (Q1 2019):

See commit 1c32013, commit 4d67b4e, commit 37897bf, commit c812bd4 (14 Dec 2018) by Sergey Organov (sorganov).
(Merged by Junio C Hamano -- gitster -- in commit 77fbd96, 18 Jan 2019)

"git cherry-pick -m1" was forbidden when picking a non-merge commit, even though there is parent number 1 for such a commit.

This was done to avoid mistakes back when "cherry-pick" was about picking a single commit, but is no longer useful with "cherry-pick" that can pick a range of commits.

Now the "-m$num" option is allowed when picking any commit, as long as $num names an existing parent of the commit.

Technically this is a backward incompatible change; hopefully nobody is relying on the error-checking behaviour.


You can see the discussion leading to allowing 'cherry-pick -m 1' for non-merge commits in this thread:

From Junio C. Hamano, main maintainer of Git:

When cherry-picking multiple commits, it's impossible to have both merge- and non-merge commits on the same command-line.
Not specifying '-m 1' results in cherry-pick refusing to handle merge commits, while specifying '-m 1' fails on non-merge commits.

Allowing "-m1" even when picking a single parent commit, because the 1-st parent is defined for such a commit, makes sense, especially when running a cherry-pick on a range, exactly for the above reason.
It is slightly less so when cherry-picking a single commit, but not by a large margin.

I think the original reasoning for requiring "-m $n" not present, especially because cherry-pick was originally for replaying only a single commit, was because it would lead somebody to propose that the command should behave as if -m1 is always given (and when trying to cherry-pick a merge relative to its second parent, give -m2 to override it), which in turn encourage the 'first-parent is special' world-view from the tool-side.

IOW, "The worldview to treat the first-parent chain specially is correct, because Git has many features to work with that worldview conveniently" was something we wanted to avoid.
Rather: "Such and such workflows benefit from treating the first-parent chain specially, so let's add features to do so" was we wanted to do.
And of course, back then cherry-pick that allows mixture of merges and single-parent commits to be picked, which would have made the need to do something like this patch does felt greater, did not exist.

Now, it appears, at least to me, that the world pretty much accepted that the first-parent worldview is often very convenient and worth supporting by the tool, so the next logical step might be to set opts->mainline to 1 by default (and allow an explicit "-m $n" from the command line to override it).
But that should happen after this patch lands---it is logically a separate step, I would think.

And:

The feature to give a range to cherry-pick came much much later in 7e2bfd3f ("revert: allow cherry-picking more than one commit", 2010-06-02) that first appeared in v1.7.2-rc0.

(as I reported here)

The feature to allow picking a merge commit came in 7791ecbc ("revert/cherry-pick: work on merge commits as well", 2007-10-23), first appeared in v1.5.4-rc0.

In the original context to pick a single commit, it made perfect sense to avoid mistakes by blindly passing '-m 1' to non-merge commit.
It may be fair to say that we failed to reconsider what to do with '-m 1' when we did 7e2bfd3f, but it is utterly an unfair history revisionism to say that it made little sense to disable it in the first place.

The change to the code itself looks sane, but applying this patch alone will break existing tests whose expectations must be updated, and this new behaviour must be protected by a new test (or two) so that we won't accidentally stop accepting "-m 1" for a single-parent commit.

Upvotes: 2

Related Questions