Skip to content

Commit baf18fc

Browse files
pcloudsgitster
authored andcommitted
Accept tags in HEAD or MERGE_HEAD
HEAD and MERGE_HEAD (among other branch tips) should never hold a tag. That can only be caused by broken tools and is cumbersome to fix by an end user with: $ git update-ref HEAD $(git rev-parse HEAD^{commit}) which may look like a magic to a new person. Be easy, warn users (so broken tools can be fixed if they bother to report) and move on. Be robust, if the given SHA-1 cannot be resolved to a commit object, die (therefore return value is always valid). Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 894642f commit baf18fc

File tree

7 files changed

+34
-14
lines changed

7 files changed

+34
-14
lines changed

builtin/commit.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,7 +1396,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
13961396
if (get_sha1("HEAD", sha1))
13971397
current_head = NULL;
13981398
else {
1399-
current_head = lookup_commit(sha1);
1399+
current_head = lookup_commit_or_die(sha1, "HEAD");
14001400
if (!current_head || parse_commit(current_head))
14011401
die(_("could not parse HEAD commit"));
14021402
}
@@ -1431,6 +1431,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
14311431
pptr = &commit_list_insert(c->item, pptr)->next;
14321432
} else if (whence == FROM_MERGE) {
14331433
struct strbuf m = STRBUF_INIT;
1434+
struct commit *commit;
14341435
FILE *fp;
14351436

14361437
if (!reflog_msg)
@@ -1444,7 +1445,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
14441445
unsigned char sha1[20];
14451446
if (get_sha1_hex(m.buf, sha1) < 0)
14461447
die(_("Corrupt MERGE_HEAD file (%s)"), m.buf);
1447-
pptr = &commit_list_insert(lookup_commit(sha1), pptr)->next;
1448+
commit = lookup_commit_or_die(sha1, "MERGE_HEAD");
1449+
pptr = &commit_list_insert(commit, pptr)->next;
14481450
}
14491451
fclose(fp);
14501452
strbuf_release(&m);

builtin/fmt-merge-msg.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ static int do_fmt_merge_msg(int merge_title, struct strbuf *in,
293293
struct commit *head;
294294
struct rev_info rev;
295295

296-
head = lookup_commit(head_sha1);
296+
head = lookup_commit_or_die(head_sha1, "HEAD");
297297
init_revisions(&rev, NULL);
298298
rev.commit_format = CMIT_FMT_ONELINE;
299299
rev.ignore_merges = 1;

builtin/merge.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,11 +1036,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
10361036
branch += 11;
10371037
if (!branch || is_null_sha1(head_sha1))
10381038
head_commit = NULL;
1039-
else {
1040-
head_commit = lookup_commit(head_sha1);
1041-
if (!head_commit)
1042-
die(_("could not parse HEAD"));
1043-
}
1039+
else
1040+
head_commit = lookup_commit_or_die(head_sha1, "HEAD");
10441041

10451042
git_config(git_merge_config, NULL);
10461043

commit.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,18 @@ struct commit *lookup_commit_reference(const unsigned char *sha1)
3939
return lookup_commit_reference_gently(sha1, 0);
4040
}
4141

42+
struct commit *lookup_commit_or_die(const unsigned char *sha1, const char *ref_name)
43+
{
44+
struct commit *c = lookup_commit_reference(sha1);
45+
if (!c)
46+
die(_("could not parse %s"), ref_name);
47+
if (hashcmp(sha1, c->object.sha1)) {
48+
warning(_("%s %s is not a commit!"),
49+
ref_name, sha1_to_hex(sha1));
50+
}
51+
return c;
52+
}
53+
4254
struct commit *lookup_commit(const unsigned char *sha1)
4355
{
4456
struct object *obj = lookup_object(sha1);

commit.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
3838
int quiet);
3939
struct commit *lookup_commit_reference_by_name(const char *name);
4040

41+
/*
42+
* Look up object named by "sha1", dereference tag as necessary,
43+
* get a commit and return it. If "sha1" does not dereference to
44+
* a commit, use ref_name to report an error and die.
45+
*/
46+
struct commit *lookup_commit_or_die(const unsigned char *sha1, const char *ref_name);
47+
4148
int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long size);
4249
int parse_commit(struct commit *item);
4350

http-push.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,10 +1606,10 @@ static void fetch_symref(const char *path, char **symref, unsigned char *sha1)
16061606
strbuf_release(&buffer);
16071607
}
16081608

1609-
static int verify_merge_base(unsigned char *head_sha1, unsigned char *branch_sha1)
1609+
static int verify_merge_base(unsigned char *head_sha1, struct ref *remote)
16101610
{
1611-
struct commit *head = lookup_commit(head_sha1);
1612-
struct commit *branch = lookup_commit(branch_sha1);
1611+
struct commit *head = lookup_commit_or_die(head_sha1, "HEAD");
1612+
struct commit *branch = lookup_commit_or_die(remote->old_sha1, remote->name);
16131613
struct commit_list *merge_bases = get_merge_bases(head, branch, 1);
16141614

16151615
return (merge_bases && !merge_bases->next && merge_bases->item == branch);
@@ -1680,7 +1680,7 @@ static int delete_remote_branch(const char *pattern, int force)
16801680
return error("Remote branch %s resolves to object %s\nwhich does not exist locally, perhaps you need to fetch?", remote_ref->name, sha1_to_hex(remote_ref->old_sha1));
16811681

16821682
/* Remote branch must be an ancestor of remote HEAD */
1683-
if (!verify_merge_base(head_sha1, remote_ref->old_sha1)) {
1683+
if (!verify_merge_base(head_sha1, remote_ref)) {
16841684
return error("The branch '%s' is not an ancestor "
16851685
"of your current HEAD.\n"
16861686
"If you are sure you want to delete it,"

revision.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -986,10 +986,12 @@ static void prepare_show_merge(struct rev_info *revs)
986986
const char **prune = NULL;
987987
int i, prune_num = 1; /* counting terminating NULL */
988988

989-
if (get_sha1("HEAD", sha1) || !(head = lookup_commit(sha1)))
989+
if (get_sha1("HEAD", sha1))
990990
die("--merge without HEAD?");
991-
if (get_sha1("MERGE_HEAD", sha1) || !(other = lookup_commit(sha1)))
991+
head = lookup_commit_or_die(sha1, "HEAD");
992+
if (get_sha1("MERGE_HEAD", sha1))
992993
die("--merge without MERGE_HEAD?");
994+
other = lookup_commit_or_die(sha1, "MERGE_HEAD");
993995
add_pending_object(revs, &head->object, "HEAD");
994996
add_pending_object(revs, &other->object, "MERGE_HEAD");
995997
bases = get_merge_bases(head, other, 1);

0 commit comments

Comments
 (0)