There is no good reason why cherry-picking root commits should not be allowed. Further, since cherry-pick is the working horse of git-rebase, we _should_ allow picking root commits, so that you can rebase originally independent branches on top of another branch. Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx> --- On Fri, 4 Jul 2008, Stephan Beyer wrote: > On Fri, Jul 04, 2008 at 03:03:37AM +0200, Johannes Schindelin > wrote: > > > Well, logically, it should come _before_ you use it in > > sequencer. And you should use it in sequencer. > > Yet nobody seems to have asked for a cherry-pick that is able to > pick root commits and sequencer is not closed source after GSoC, so > this can be added whenever there is need and time for it. However, this is the wrong sequence. Anyhow, I give up on trying to convince you. builtin-revert.c | 26 ++++++++++++++++---------- t/t3503-cherry-pick-root.sh | 30 ++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 10 deletions(-) create mode 100755 t/t3503-cherry-pick-root.sh diff --git a/builtin-revert.c b/builtin-revert.c index 0270f9b..f3d4524 100644 --- a/builtin-revert.c +++ b/builtin-revert.c @@ -206,6 +206,7 @@ static int merge_recursive(const char *base_sha1, { char buffer[256]; const char *argv[6]; + int i = 0; sprintf(buffer, "GITHEAD_%s", head_sha1); setenv(buffer, head_name, 1); @@ -218,12 +219,13 @@ static int merge_recursive(const char *base_sha1, * and $prev on top of us (when reverting), or the change between * $prev and $commit on top of us (when cherry-picking or replaying). */ - argv[0] = "merge-recursive"; - argv[1] = base_sha1; - argv[2] = "--"; - argv[3] = head_sha1; - argv[4] = next_sha1; - argv[5] = NULL; + argv[i++] = "merge-recursive"; + if (base_sha1) + argv[i++] = base_sha1; + argv[i++] = "--"; + argv[i++] = head_sha1; + argv[i++] = next_sha1; + argv[i++] = NULL; return run_command_v_opt(argv, RUN_COMMAND_NO_STDIN | RUN_GIT_CMD); } @@ -297,9 +299,12 @@ static int revert_or_cherry_pick(int argc, const char **argv) discard_cache(); } - if (!commit->parents) - die ("Cannot %s a root commit", me); - if (commit->parents->next) { + if (!commit->parents) { + if (action == REVERT) + die ("Cannot revert a root commit"); + parent = NULL; + } + else if (commit->parents->next) { /* Reverting or cherry-picking a merge commit */ int cnt; struct commit_list *p; @@ -368,7 +373,8 @@ static int revert_or_cherry_pick(int argc, const char **argv) } } - if (merge_recursive(sha1_to_hex(base->object.sha1), + if (merge_recursive(base == NULL ? + NULL : sha1_to_hex(base->object.sha1), sha1_to_hex(head), "HEAD", sha1_to_hex(next->object.sha1), oneline) || write_cache_as_tree(head, 0, NULL)) { diff --git a/t/t3503-cherry-pick-root.sh b/t/t3503-cherry-pick-root.sh new file mode 100755 index 0000000..b0faa29 --- /dev/null +++ b/t/t3503-cherry-pick-root.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +test_description='test cherry-picking a root commit' + +. ./test-lib.sh + +test_expect_success setup ' + + echo first > file1 && + git add file1 && + test_tick && + git commit -m "first" && + + git symbolic-ref HEAD refs/heads/second && + rm .git/index file1 && + echo second > file2 && + git add file2 && + test_tick && + git commit -m "second" + +' + +test_expect_success 'cherry-pick a root commit' ' + + git cherry-pick master && + test first = $(cat file1) + +' + +test_done -- 1.5.6.1.376.g6b0fd -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html