When using git-cherry-pick(1) with `--allow-empty` while on an unborn branch, an error is thrown. This is inconsistent with the same cherry-pick when `--allow-empty` is not specified. Treat a failure reading HEAD as an unborn branch in `is_index_unchanged`. This is consistent with other sequencer logic such as `do_pick_commit`. When on an unborn branch, use the `empty_tree` as the tree to compare against. Signed-off-by: Brian Lyles <brianmlyles@xxxxxxxxx> Helped-by: Phillip Wood <phillip.wood@xxxxxxxxxxxxx> --- This is another new commit that was not present in v1. See this comment[1] from Phillip for context. [1]: https://lore.kernel.org/git/b5213705-4cd6-40ef-8c5f-32b214534b8b@xxxxxxxxx/ sequencer.c | 36 ++++++++++++++++++++--------------- t/t3501-revert-cherry-pick.sh | 11 +++++++++++ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/sequencer.c b/sequencer.c index 3cc88d8a80..b1b19512de 100644 --- a/sequencer.c +++ b/sequencer.c @@ -769,30 +769,36 @@ static struct object_id *get_cache_tree_oid(struct index_state *istate) static int is_index_unchanged(struct repository *r) { - struct object_id head_oid, *cache_tree_oid; + struct object_id head_oid, *cache_tree_oid, head_tree_oid; struct commit *head_commit; struct index_state *istate = r->index; - if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL)) - return error(_("could not resolve HEAD commit")); + if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL)) { + /* + * Treat an error reading HEAD as an unborn branch. + */ + head_tree_oid = *the_hash_algo->empty_tree; + } else { + head_commit = lookup_commit(r, &head_oid); - head_commit = lookup_commit(r, &head_oid); + /* + * If head_commit is NULL, check_commit, called from + * lookup_commit, would have indicated that head_commit is not + * a commit object already. repo_parse_commit() will return failure + * without further complaints in such a case. Otherwise, if + * the commit is invalid, repo_parse_commit() will complain. So + * there is nothing for us to say here. Just return failure. + */ + if (repo_parse_commit(r, head_commit)) + return -1; - /* - * If head_commit is NULL, check_commit, called from - * lookup_commit, would have indicated that head_commit is not - * a commit object already. repo_parse_commit() will return failure - * without further complaints in such a case. Otherwise, if - * the commit is invalid, repo_parse_commit() will complain. So - * there is nothing for us to say here. Just return failure. - */ - if (repo_parse_commit(r, head_commit)) - return -1; + head_tree_oid = *get_commit_tree_oid(head_commit); + } if (!(cache_tree_oid = get_cache_tree_oid(istate))) return -1; - return oideq(cache_tree_oid, get_commit_tree_oid(head_commit)); + return oideq(cache_tree_oid, &head_tree_oid); } static int write_author_script(const char *message) diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index aeab689a98..390e0ed186 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -112,6 +112,17 @@ test_expect_success 'cherry-pick on unborn branch' ' test_cmp_rev ! initial HEAD ' +test_expect_success 'cherry-pick on unborn branch with --allow-empty' ' + git checkout main && + git branch -D unborn && + git checkout --orphan unborn && + git rm --cached -r . && + rm -rf * && + git cherry-pick initial --allow-empty && + git diff --quiet initial && + test_cmp_rev ! initial HEAD +' + test_expect_success 'cherry-pick "-" to pick from previous branch' ' git checkout unborn && test_commit to-pick actual content && -- 2.43.0