1

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>
vijay
  • 117
  • 1
  • 1
  • 7
  • 1
    What does `from 3rd commit to 6th commit` mean? Can you show us a diagram of what you want to do? – Tim Biegeleisen Jan 14 '16 at 05:33
  • 1
    Possible duplicate of [How to cherry pick a range of commits and merge into another branch](http://stackoverflow.com/questions/1994463/how-to-cherry-pick-a-range-of-commits-and-merge-into-another-branch) – Andrew C Jan 14 '16 at 08:04

1 Answers1

2

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.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • @ksvijay413 Be sure to replace B by the SHA1 of the oldest commit you want to merge, and D by the SHA1 of the newest commit. – VonC Jan 14 '16 at 08:45
  • D:\GitHub\hexgen\src>git cherry-pick 17eb265a5be195382ddb92dfdba3f4c264345a83^..b1fdca06aa187f3f525e993cc0681251b2df09ae [range_2.0.primary bbcf9cd] For grids made a export button and put pdf,csv etc under it - just to avoid the clutter Author: Mallick 1 file changed, 8 insertions(+), 3 deletions(-) error: Commit 699aa7121ff4f6bdd1480d004ab68fb95f6e7ba3 is a merge but no -m option was given. fatal: cherry-pick failed – vijay Jan 14 '16 at 08:49
  • @ksvijay413 it is best if your commits don't include merge commits. If they do include a merge commit, try at least to add `-m 1` to your cherry-pick command. – VonC Jan 14 '16 at 08:51
  • D:\GitHub\hexgen\src>git cherry-pick -m 1 17eb265a5be195382ddb92dfdba3f4c264345a83^..b1fdca06aa187f3f525e993cc0681251b2df09ae error: Mainline was specified but commit 8d0e9d27f5fd3cb9934349b00efa060ddbd63bf1 is not a merge. fatal: cherry-pick failed – vijay Jan 14 '16 at 09:56
  • @vijay three years latter, your cherry-pick (the one which returned "is not a merge. fatal: cherry-pick failed") will actually work lwith Git 2.21 (Q1 2019). See my edited answer above. – VonC Jan 27 '19 at 20:38
  • This new 2.21 behavior (allowing `-m1` for non-merge commits) is probably a good thing. Time will tell! :-) – torek Feb 08 '19 at 07:23
  • @torek I have edited the answer to add the discussion (from the Git mailing-list) leading to that new feature: that will give you (and other readers) some context. – VonC Feb 08 '19 at 07:50