mirror of
https://github.com/git/git.git
synced 2024-11-06 17:23:00 +01:00
Merge branch 'mz/pick-unborn'
Allow "git cherry-pick $commit" even when you do not have any history behind HEAD yet. * mz/pick-unborn: learn to pick/revert into unborn branch tests: move test_cmp_rev to test-lib-functions
This commit is contained in:
commit
6a37cee10a
10 changed files with 44 additions and 48 deletions
20
sequencer.c
20
sequencer.c
|
@ -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
|
||||
|
|
|
@ -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' '
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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 '
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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' '
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue