Merge branch 'mz/pick-unborn' into maint
authorJunio C Hamano <gitster@pobox.com>
Thu, 7 Feb 2013 23:16:04 +0000 (15:16 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 7 Feb 2013 23:16:04 +0000 (15:16 -0800)
"git cherry-pick" did not replay a root commit to an unborn branch.

* mz/pick-unborn:
learn to pick/revert into unborn branch
tests: move test_cmp_rev to test-lib-functions

sequencer.c
t/t1505-rev-parse-last.sh
t/t3404-rebase-interactive.sh
t/t3501-revert-cherry-pick.sh
t/t3506-cherry-pick-ff.sh
t/t3507-cherry-pick-conflict.sh
t/t3508-cherry-pick-many-commits.sh
t/t3510-cherry-pick-sequence.sh
t/t6030-bisect-porcelain.sh
t/test-lib-functions.sh
index 22604902aa4c4dd146f562c4841c344a773a9bda..aef5e8a0170c5b337f1aa3ac7a35be3b54957729 100644 (file)
@@ -186,14 +186,15 @@ static int error_dirty_index(struct replay_opts *opts)
        return -1;
 }
 
-static int fast_forward_to(const unsigned char *to, const unsigned char *from)
+static int fast_forward_to(const unsigned char *to, const unsigned char *from,
+                          int unborn)
 {
        struct ref_lock *ref_lock;
 
        read_cache();
        if (checkout_fast_forward(from, to, 1))
                exit(1); /* the callee should have complained already */
-       ref_lock = lock_any_ref_for_update("HEAD", from, 0);
+       ref_lock = lock_any_ref_for_update("HEAD", unborn ? null_sha1 : from, 0);
        return write_ref_sha1(ref_lock, to, "cherry-pick");
 }
 
@@ -390,7 +391,7 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
        struct commit_message msg = { NULL, NULL, NULL, NULL, NULL };
        char *defmsg = NULL;
        struct strbuf msgbuf = STRBUF_INIT;
-       int res;
+       int res, unborn = 0;
 
        if (opts->no_commit) {
                /*
@@ -402,9 +403,10 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
                if (write_cache_as_tree(head, 0, NULL))
                        die (_("Your index file is unmerged."));
        } else {
-               if (get_sha1("HEAD", head))
-                       return error(_("You do not have a valid HEAD"));
-               if (index_differs_from("HEAD", 0))
+               unborn = get_sha1("HEAD", head);
+               if (unborn)
+                       hashcpy(head, EMPTY_TREE_SHA1_BIN);
+               if (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : "HEAD", 0))
                        return error_dirty_index(opts);
        }
        discard_cache();
@@ -435,8 +437,10 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
        else
                parent = commit->parents->item;
 
-       if (opts->allow_ff && parent && !hashcmp(parent->object.sha1, head))
-               return fast_forward_to(commit->object.sha1, head);
+       if (opts->allow_ff &&
+           ((parent && !hashcmp(parent->object.sha1, head)) ||
+            (!parent && unborn)))
+            return fast_forward_to(commit->object.sha1, head, unborn);
 
        if (parent && parse_commit(parent) < 0)
                /* TRANSLATORS: The first %s will be "revert" or
index d709ecf8df136539a746ef1873821baee6fab428..4969edb31441c81cf2e63385d07d780a52faa53b 100755 (executable)
@@ -32,32 +32,24 @@ test_expect_success 'setup' '
 #
 # and 'side' should be the last branch
 
-test_rev_equivalent () {
-
-       git rev-parse "$1" > expect &&
-       git rev-parse "$2" > output &&
-       test_cmp expect output
-
-}
-
 test_expect_success '@{-1} works' '
-       test_rev_equivalent side @{-1}
+       test_cmp_rev side @{-1}
 '
 
 test_expect_success '@{-1}~2 works' '
-       test_rev_equivalent side~2 @{-1}~2
+       test_cmp_rev side~2 @{-1}~2
 '
 
 test_expect_success '@{-1}^2 works' '
-       test_rev_equivalent side^2 @{-1}^2
+       test_cmp_rev side^2 @{-1}^2
 '
 
 test_expect_success '@{-1}@{1} works' '
-       test_rev_equivalent side@{1} @{-1}@{1}
+       test_cmp_rev side@{1} @{-1}@{1}
 '
 
 test_expect_success '@{-2} works' '
-       test_rev_equivalent master @{-2}
+       test_cmp_rev master @{-2}
 '
 
 test_expect_success '@{-3} fails' '
index 32fdc9938e1dc29d9a1c6c1dd54379ee33644561..8462be1db6a0fe4f9e28cd1662be604196141055 100755 (executable)
@@ -29,12 +29,6 @@ Initial setup:
 
 . "$TEST_DIRECTORY"/lib-rebase.sh
 
-test_cmp_rev () {
-       git rev-parse --verify "$1" >expect.rev &&
-       git rev-parse --verify "$2" >actual.rev &&
-       test_cmp expect.rev actual.rev
-}
-
 set_fake_editor
 
 # WARNING: Modifications to the initial repository can change the SHA ID used
index 34c86e5de69468fe7618383e556d1711cc49b0bb..6f489e20eecb48c6e1a2dc2b1fe90e47e7b3e7ad 100755 (executable)
@@ -100,4 +100,13 @@ test_expect_success 'revert forbidden on dirty working tree' '
 
 '
 
+test_expect_success 'chery-pick on unborn branch' '
+       git checkout --orphan unborn &&
+       git rm --cached -r . &&
+       rm -rf * &&
+       git cherry-pick initial &&
+       git diff --quiet initial &&
+       ! test_cmp_rev initial HEAD
+'
+
 test_done
index 51ca391e472441d2d503e721795d609bfaad1100..373aad623c8f02f6f9753eb38c6393a69c027001 100755 (executable)
@@ -105,4 +105,12 @@ test_expect_success 'cherry pick a root commit with --ff' '
        test "$(git rev-parse --verify HEAD)" = "1df192cd8bc58a2b275d842cede4d221ad9000d1"
 '
 
+test_expect_success 'chery-pick --ff on unborn branch' '
+       git checkout --orphan unborn &&
+       git rm --cached -r . &&
+       rm -rf * &&
+       git cherry-pick --ff first &&
+       test_cmp_rev first HEAD
+'
+
 test_done
index c82f7210c4ca10e35d9d2000aa8da2d10194a6c6..223b98433c502b03c4ba70550cb32d42a5f6295b 100755 (executable)
@@ -11,12 +11,6 @@ test_description='test cherry-pick and revert with conflicts
 
 . ./test-lib.sh
 
-test_cmp_rev () {
-       git rev-parse --verify "$1" >expect.rev &&
-       git rev-parse --verify "$2" >actual.rev &&
-       test_cmp expect.rev actual.rev
-}
-
 pristine_detach () {
        git checkout -f "$1^0" &&
        git read-tree -u --reset HEAD &&
index 340afc760de030879fff496dca3db8432a6b992b..4e7136b83775946a07678119c7c9897bb0f2b709 100755 (executable)
@@ -5,15 +5,11 @@ test_description='test cherry-picking many commits'
 . ./test-lib.sh
 
 check_head_differs_from() {
-       head=$(git rev-parse --verify HEAD) &&
-       arg=$(git rev-parse --verify "$1") &&
-       test "$head" != "$arg"
+       ! test_cmp_rev HEAD "$1"
 }
 
 check_head_equals() {
-       head=$(git rev-parse --verify HEAD) &&
-       arg=$(git rev-parse --verify "$1") &&
-       test "$head" = "$arg"
+       test_cmp_rev HEAD "$1"
 }
 
 test_expect_success setup '
index b5fb527b2e686d158a6e7d53d6246b9e66f80a7b..7b7a89dbd5ce578e0a722345a00f247e383689ef 100755 (executable)
@@ -24,12 +24,6 @@ pristine_detach () {
        git clean -d -f -f -q -x
 }
 
-test_cmp_rev () {
-       git rev-parse --verify "$1" >expect.rev &&
-       git rev-parse --verify "$2" >actual.rev &&
-       test_cmp expect.rev actual.rev
-}
-
 test_expect_success setup '
        git config advice.detachedhead false &&
        echo unrelated >unrelated &&
index 72e28ee5350926f3c4f27e2c99f8323a3eb8e57c..3e0e15fb3e0b92ab7e95789d27db34d9a1fa423c 100755 (executable)
@@ -676,9 +676,7 @@ test_expect_success 'bisect fails if tree is broken on trial commit' '
 check_same()
 {
        echo "Checking $1 is the same as $2" &&
-       git rev-parse "$1" > expected.same &&
-       git rev-parse "$2" > expected.actual &&
-       test_cmp expected.same expected.actual
+       test_cmp_rev "$1" "$2"
 }
 
 test_expect_success 'bisect: --no-checkout - start commit bad' '
index 22a4f8fb64a4e8084139fc148e8e7dd4aa73d684..fa62d010f68e3ee97e6754687ad4d08564d3c96b 100644 (file)
@@ -602,6 +602,13 @@ test_cmp() {
        $GIT_TEST_CMP "$@"
 }
 
+# Tests that its two parameters refer to the same revision
+test_cmp_rev () {
+       git rev-parse --verify "$1" >expect.rev &&
+       git rev-parse --verify "$2" >actual.rev &&
+       test_cmp expect.rev actual.rev
+}
+
 # Print a sequence of numbers or letters in increasing order.  This is
 # similar to GNU seq(1), but the latter might not be available
 # everywhere (and does not do letters).  It may be used like: