Merge branch 'mz/pick-unborn' into maint

"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
This commit is contained in:
Junio C Hamano 2013-02-07 15:16:04 -08:00
commit 57ff1703d7
10 changed files with 44 additions and 48 deletions

View File

@ -186,14 +186,15 @@ static int error_dirty_index(struct replay_opts *opts)
return -1; 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; struct ref_lock *ref_lock;
read_cache(); read_cache();
if (checkout_fast_forward(from, to, 1)) if (checkout_fast_forward(from, to, 1))
exit(1); /* the callee should have complained already */ 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"); 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 }; struct commit_message msg = { NULL, NULL, NULL, NULL, NULL };
char *defmsg = NULL; char *defmsg = NULL;
struct strbuf msgbuf = STRBUF_INIT; struct strbuf msgbuf = STRBUF_INIT;
int res; int res, unborn = 0;
if (opts->no_commit) { 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)) if (write_cache_as_tree(head, 0, NULL))
die (_("Your index file is unmerged.")); die (_("Your index file is unmerged."));
} else { } else {
if (get_sha1("HEAD", head)) unborn = get_sha1("HEAD", head);
return error(_("You do not have a valid HEAD")); if (unborn)
if (index_differs_from("HEAD", 0)) hashcpy(head, EMPTY_TREE_SHA1_BIN);
if (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : "HEAD", 0))
return error_dirty_index(opts); return error_dirty_index(opts);
} }
discard_cache(); discard_cache();
@ -435,8 +437,10 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
else else
parent = commit->parents->item; parent = commit->parents->item;
if (opts->allow_ff && parent && !hashcmp(parent->object.sha1, head)) if (opts->allow_ff &&
return fast_forward_to(commit->object.sha1, head); ((parent && !hashcmp(parent->object.sha1, head)) ||
(!parent && unborn)))
return fast_forward_to(commit->object.sha1, head, unborn);
if (parent && parse_commit(parent) < 0) if (parent && parse_commit(parent) < 0)
/* TRANSLATORS: The first %s will be "revert" or /* TRANSLATORS: The first %s will be "revert" or

View File

@ -32,32 +32,24 @@ test_expect_success 'setup' '
# #
# and 'side' should be the last branch # 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_expect_success '@{-1} works' '
test_rev_equivalent side @{-1} test_cmp_rev side @{-1}
' '
test_expect_success '@{-1}~2 works' ' 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_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_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_expect_success '@{-2} works' '
test_rev_equivalent master @{-2} test_cmp_rev master @{-2}
' '
test_expect_success '@{-3} fails' ' test_expect_success '@{-3} fails' '

View File

@ -29,12 +29,6 @@ Initial setup:
. "$TEST_DIRECTORY"/lib-rebase.sh . "$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 set_fake_editor
# WARNING: Modifications to the initial repository can change the SHA ID used # WARNING: Modifications to the initial repository can change the SHA ID used

View File

@ -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 test_done

View File

@ -105,4 +105,12 @@ test_expect_success 'cherry pick a root commit with --ff' '
test "$(git rev-parse --verify HEAD)" = "1df192cd8bc58a2b275d842cede4d221ad9000d1" 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 test_done

View File

@ -11,12 +11,6 @@ test_description='test cherry-pick and revert with conflicts
. ./test-lib.sh . ./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 () { pristine_detach () {
git checkout -f "$1^0" && git checkout -f "$1^0" &&
git read-tree -u --reset HEAD && git read-tree -u --reset HEAD &&

View File

@ -5,15 +5,11 @@ test_description='test cherry-picking many commits'
. ./test-lib.sh . ./test-lib.sh
check_head_differs_from() { check_head_differs_from() {
head=$(git rev-parse --verify HEAD) && ! test_cmp_rev HEAD "$1"
arg=$(git rev-parse --verify "$1") &&
test "$head" != "$arg"
} }
check_head_equals() { check_head_equals() {
head=$(git rev-parse --verify HEAD) && test_cmp_rev HEAD "$1"
arg=$(git rev-parse --verify "$1") &&
test "$head" = "$arg"
} }
test_expect_success setup ' test_expect_success setup '

View File

@ -24,12 +24,6 @@ pristine_detach () {
git clean -d -f -f -q -x 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 ' test_expect_success setup '
git config advice.detachedhead false && git config advice.detachedhead false &&
echo unrelated >unrelated && echo unrelated >unrelated &&

View File

@ -676,9 +676,7 @@ test_expect_success 'bisect fails if tree is broken on trial commit' '
check_same() check_same()
{ {
echo "Checking $1 is the same as $2" && echo "Checking $1 is the same as $2" &&
git rev-parse "$1" > expected.same && test_cmp_rev "$1" "$2"
git rev-parse "$2" > expected.actual &&
test_cmp expected.same expected.actual
} }
test_expect_success 'bisect: --no-checkout - start commit bad' ' test_expect_success 'bisect: --no-checkout - start commit bad' '

View File

@ -602,6 +602,13 @@ test_cmp() {
$GIT_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 # Print a sequence of numbers or letters in increasing order. This is
# similar to GNU seq(1), but the latter might not be available # similar to GNU seq(1), but the latter might not be available
# everywhere (and does not do letters). It may be used like: # everywhere (and does not do letters). It may be used like: