Merge branch 'cc/cherry-pick-stdin'
authorJunio C Hamano <gitster@pobox.com>
Wed, 30 Jun 2010 18:55:39 +0000 (11:55 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 30 Jun 2010 18:55:39 +0000 (11:55 -0700)
* cc/cherry-pick-stdin:
revert: do not rebuild argv on heap
revert: accept arbitrary rev-list options
t3508 (cherry-pick): futureproof against unmerged files

Documentation/git-cherry-pick.txt
builtin/revert.c
t/t3501-revert-cherry-pick.sh
t/t3508-cherry-pick-many-commits.sh
index bcb4c758b748b53b7a990455bf4ef9d89f901079..ca485dbac19da231eca045bcf55c6b5df87e8dec 100644 (file)
@@ -113,6 +113,13 @@ git cherry-pick --ff ..next::
        are in next but not HEAD to the current branch, creating a new
        commit for each new change.
 
+git rev-list --reverse master \-- README | git cherry-pick -n --stdin::
+
+       Apply the changes introduced by all commits on the master
+       branch that touched README to the working tree and index,
+       so the result can be inspected and made into a single new
+       commit if suitable.
+
 Author
 ------
 Written by Junio C Hamano <gitster@pobox.com>
index 853e9e406c7fe258c39fa7e5c53f15f739a935b1..8b9d829a73a0862dfdf2c2499b18878489620f16 100644 (file)
@@ -50,10 +50,14 @@ static const char *strategy;
 
 static char *get_encoding(const char *message);
 
+static const char * const *revert_or_cherry_pick_usage(void)
+{
+       return action == REVERT ? revert_usage : cherry_pick_usage;
+}
+
 static void parse_args(int argc, const char **argv)
 {
-       const char * const * usage_str =
-               action == REVERT ?  revert_usage : cherry_pick_usage;
+       const char * const * usage_str = revert_or_cherry_pick_usage();
        int noop;
        struct option options[] = {
                OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"),
@@ -78,8 +82,10 @@ static void parse_args(int argc, const char **argv)
                        die("program error");
        }
 
-       commit_argc = parse_options(argc, argv, NULL, options, usage_str, 0);
-       if (commit_argc < 1)
+       commit_argc = parse_options(argc, argv, NULL, options, usage_str,
+                                   PARSE_OPT_KEEP_ARGV0 |
+                                   PARSE_OPT_KEEP_UNKNOWN);
+       if (commit_argc < 2)
                usage_with_options(usage_str, options);
 
        commit_argv = argv;
@@ -525,27 +531,22 @@ static int do_pick_commit(void)
 
 static void prepare_revs(struct rev_info *revs)
 {
-       int argc = 0;
-       int i;
-       const char **argv = xmalloc((commit_argc + 4) * sizeof(*argv));
+       int argc;
 
-       argv[argc++] = NULL;
-       argv[argc++] = "--no-walk";
+       init_revisions(revs, NULL);
+       revs->no_walk = 1;
        if (action != REVERT)
-               argv[argc++] = "--reverse";
-       for (i = 0; i < commit_argc; i++)
-               argv[argc++] = commit_argv[i];
-       argv[argc++] = NULL;
+               revs->reverse = 1;
+
+       argc = setup_revisions(commit_argc, commit_argv, revs, NULL);
+       if (argc > 1)
+               usage(*revert_or_cherry_pick_usage());
 
-       init_revisions(revs, NULL);
-       setup_revisions(argc - 1, argv, revs, NULL);
        if (prepare_revision_walk(revs))
                die("revision walk setup failed");
 
        if (!revs->commits)
                die("empty commit set passed");
-
-       free(argv);
 }
 
 static int revert_or_cherry_pick(int argc, const char **argv)
index e4fbf7a2107c680ee5c51f2ccf5297ed1fd4d868..bc7aedd0484ed5ad1115cac0f22943445d658f47 100755 (executable)
@@ -41,6 +41,24 @@ test_expect_success setup '
        git tag rename2
 '
 
+test_expect_success 'cherry-pick --nonsense' '
+
+       pos=$(git rev-parse HEAD) &&
+       git diff --exit-code HEAD &&
+       test_must_fail git cherry-pick --nonsense 2>msg &&
+       git diff --exit-code HEAD "$pos" &&
+       grep '[Uu]sage:' msg
+'
+
+test_expect_success 'revert --nonsense' '
+
+       pos=$(git rev-parse HEAD) &&
+       git diff --exit-code HEAD &&
+       test_must_fail git revert --nonsense 2>msg &&
+       git diff --exit-code HEAD "$pos" &&
+       grep '[Uu]sage:' msg
+'
+
 test_expect_success 'cherry-pick after renaming branch' '
 
        git checkout rename2 &&
index 3b87efe3adffc025275ff5ad5ee4cd8251a39522..f90ed3da3e0cb93b63d32d8002dc6d9bd3596a65 100755 (executable)
@@ -23,7 +23,7 @@ test_expect_success setup '
 '
 
 test_expect_success 'cherry-pick first..fourth works' '
-       git checkout master &&
+       git checkout -f master &&
        git reset --hard first &&
        test_tick &&
        git cherry-pick first..fourth &&
@@ -33,7 +33,7 @@ test_expect_success 'cherry-pick first..fourth works' '
 '
 
 test_expect_success 'cherry-pick --ff first..fourth works' '
-       git checkout master &&
+       git checkout -f master &&
        git reset --hard first &&
        test_tick &&
        git cherry-pick --ff first..fourth &&
@@ -43,7 +43,7 @@ test_expect_success 'cherry-pick --ff first..fourth works' '
 '
 
 test_expect_success 'cherry-pick -n first..fourth works' '
-       git checkout master &&
+       git checkout -f master &&
        git reset --hard first &&
        test_tick &&
        git cherry-pick -n first..fourth &&
@@ -53,7 +53,7 @@ test_expect_success 'cherry-pick -n first..fourth works' '
 '
 
 test_expect_success 'revert first..fourth works' '
-       git checkout master &&
+       git checkout -f master &&
        git reset --hard fourth &&
        test_tick &&
        git revert first..fourth &&
@@ -63,7 +63,7 @@ test_expect_success 'revert first..fourth works' '
 '
 
 test_expect_success 'revert ^first fourth works' '
-       git checkout master &&
+       git checkout -f master &&
        git reset --hard fourth &&
        test_tick &&
        git revert ^first fourth &&
@@ -73,7 +73,7 @@ test_expect_success 'revert ^first fourth works' '
 '
 
 test_expect_success 'revert fourth fourth~1 fourth~2 works' '
-       git checkout master &&
+       git checkout -f master &&
        git reset --hard fourth &&
        test_tick &&
        git revert fourth fourth~1 fourth~2 &&
@@ -82,8 +82,8 @@ test_expect_success 'revert fourth fourth~1 fourth~2 works' '
        git diff --quiet HEAD first
 '
 
-test_expect_failure 'cherry-pick -3 fourth works' '
-       git checkout master &&
+test_expect_success 'cherry-pick -3 fourth works' '
+       git checkout -f master &&
        git reset --hard first &&
        test_tick &&
        git cherry-pick -3 fourth &&
@@ -92,4 +92,14 @@ test_expect_failure 'cherry-pick -3 fourth works' '
        test "$(git rev-parse --verify HEAD)" != "$(git rev-parse --verify fourth)"
 '
 
+test_expect_success 'cherry-pick --stdin works' '
+       git checkout -f master &&
+       git reset --hard first &&
+       test_tick &&
+       git rev-list --reverse first..fourth | git cherry-pick --stdin &&
+       git diff --quiet other &&
+       git diff --quiet HEAD other &&
+       test "$(git rev-parse --verify HEAD)" != "$(git rev-parse --verify fourth)"
+'
+
 test_done