learn to pick/revert into unborn branch
cherry-picking into an unborn branch should work, so make it work, with or without --ff. Cherry-picking anything other than a commit that only adds files, will naturally result in conflicts. Similarly, revert also works, but will result in conflicts unless the specified revision only deletes files. Signed-off-by: Martin von Zweigbergk <martinvonz@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Martin von Zweigbergk committed
Dec 21, 2012 at 11:10 UTC
334ae397452170dacfcd8e69e4a41f6a64f54eec
3 files changed
+29
-8
sequencer.c
+12
-8
@@ -186,14 +186,15 @@ static int error_dirty_index(struct replay_opts *opts)
186
return -1;
187
}
188
189
-static int fast_forward_to(const unsigned char *to, const unsigned char *from)
189
+static int fast_forward_to(const unsigned char *to, const unsigned char *from,
190
+ int unborn)
191
{
192
struct ref_lock *ref_lock;
193
194
read_cache();
195
if (checkout_fast_forward(from, to, 1))
196
exit(1); /* the callee should have complained already */
196
- ref_lock = lock_any_ref_for_update("HEAD", from, 0);
197
+ ref_lock = lock_any_ref_for_update("HEAD", unborn ? null_sha1 : from, 0);
198
return write_ref_sha1(ref_lock, to, "cherry-pick");
199
}
200
@@ -390,7 +391,7 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
391
struct commit_message msg = { NULL, NULL, NULL, NULL, NULL };
392
char *defmsg = NULL;
393
struct strbuf msgbuf = STRBUF_INIT;
393
- int res;
394
+ int res, unborn = 0;
395
396
if (opts->no_commit) {
397
/*
@@ -402,9 +403,10 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
403
if (write_cache_as_tree(head, 0, NULL))
404
die (_("Your index file is unmerged."));
405
} else {
405
- if (get_sha1("HEAD", head))
406
- return error(_("You do not have a valid HEAD"));
407
- if (index_differs_from("HEAD", 0))
406
+ unborn = get_sha1("HEAD", head);
407
+ if (unborn)
408
+ hashcpy(head, EMPTY_TREE_SHA1_BIN);
409
+ if (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : "HEAD", 0))
410
return error_dirty_index(opts);
411
}
412
discard_cache();
@@ -435,8 +437,10 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
437
else
438
parent = commit->parents->item;
439
438
- if (opts->allow_ff && parent && !hashcmp(parent->object.sha1, head))
439
- return fast_forward_to(commit->object.sha1, head);
440
+ if (opts->allow_ff &&
441
+ ((parent && !hashcmp(parent->object.sha1, head)) ||
442
+ (!parent && unborn)))
443
+ return fast_forward_to(commit->object.sha1, head, unborn);
444
445
if (parent && parse_commit(parent) < 0)
446
/* TRANSLATORS: The first %s will be "revert" or
t/t3501-revert-cherry-pick.sh
+9
@@ -100,4 +100,13 @@ test_expect_success 'revert forbidden on dirty working tree' '
100
101
'
102
103
+test_expect_success 'chery-pick on unborn branch' '
104
+ git checkout --orphan unborn &&
105
+ git rm --cached -r . &&
106
+ rm -rf * &&
107
+ git cherry-pick initial &&
108
+ git diff --quiet initial &&
109
+ ! test_cmp_rev initial HEAD
110
+'
111
+
112
test_done
t/t3506-cherry-pick-ff.sh
+8
@@ -105,4 +105,12 @@ test_expect_success 'cherry pick a root commit with --ff' '
105
test "$(git rev-parse --verify HEAD)" = "1df192cd8bc58a2b275d842cede4d221ad9000d1"
106
'
107
108
+test_expect_success 'chery-pick --ff on unborn branch' '
109
+ git checkout --orphan unborn &&
110
+ git rm --cached -r . &&
111
+ rm -rf * &&
112
+ git cherry-pick --ff first &&
113
+ test_cmp_rev first HEAD
114
+'
115
+
116
test_done