Re: [PATCH v3] Accept tags in HEAD or MERGE_HEAD

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Nguyễn Thái Ngọc Duy  <pclouds@xxxxxxxxx> writes:

> 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) and move on.

We do not really fix broken tools; we just fix breakages caused by them.

> Be robust, if the given SHA-1 cannot be resolved to a commit object,
> die (therefore return value is always valid).

Makes sense.

> diff --git a/builtin/commit.c b/builtin/commit.c
> index cb73857..f78b449 100644
> --- a/builtin/commit.c
> +++ b/builtin/commit.c
> @@ -63,6 +63,7 @@ N_("The previous cherry-pick is now empty, possibly due to conflict resolution.\
>  "Otherwise, please use 'git reset'\n");
>  
>  static unsigned char head_sha1[20];
> +static struct commit *head_commit;

I was not happy with the file-scope global head_sha1[] already, and this
makes me even less happy. Was it too much trouble to keep them local to
cmd_commit() and pass them around as arguments where necessary?  If you
pass around head_commit, is_null_sha1(head_sha1) can be replaced with a
check !head_commit so we may even be able to lose the head_sha1[] global.

And actually removing head_sha1[] is a necessary step from the correctness
point of view. The repository may have given an object name for a tag in
head_sha1[] and lookup_expect_commit() may have peeled it to a commit.
The code may want to add the "HEAD" as one of the parents of a new commit,
and head_sha1[] is no longer the place to pick that information up after
your fix. The code needs to look at head_commit->object.sha1[] instead.
Losing the use of head_sha1[] variable and forcing the code to go to
head_commit->object.sha1[] reduces the risk of such confusion.

> @@ -1028,6 +1026,9 @@ static int parse_and_validate_options(int argc, const char *argv[],
>  
>  	if (get_sha1("HEAD", head_sha1))
>  		initial_commit = 1;
> +	else
> +		head_commit = lookup_expect_commit(head_sha1, "HEAD");

It may be just me, but the name feels a bit funny. The original name was
"look up" (verb) + "commit" (direct object of the verb), and what you are
doing is lookup_and_expect_commit(), but it is too long.

Perhaps lookup_commit_or_die()?

To a naïve reader of the caller, the function looks as if it would do

	struct commit *lookup_expect_commit(unsigned char *head_sha1, char *name)
        {
        	struct commit *c;
		if (get_sha1("HEAD", head_sha1) ||
	            !(c = lookup_commit(head_sha1))) die(...);
		return c;
	}

but in fact it does not use "HEAD" for anything other than error reporting
and it is the caller's responsibility to supply head_sha1[].

It is documented in the function declaration by making the memory
head_sha1 points at as a "const" (i.e. the function can't be calling
get_sha() on the refname), but it may also need a comment or two there.

> diff --git a/builtin/merge.c b/builtin/merge.c
> index 325891e..22e98e8 100644
> --- a/builtin/merge.c
> +++ b/builtin/merge.c
> @@ -51,6 +51,7 @@ static int allow_trivial = 1, have_message;
>  static struct strbuf merge_msg;
>  static struct commit_list *remoteheads;
>  static unsigned char head[20], stash[20];
> +static struct commit* head_commit;

This is C, not C++; asterisk sticks to the variable, not type.

> @@ -1030,6 +1031,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
>  		branch += 11;
>  	if (is_null_sha1(head))
>  		head_invalid = 1;
> +	else
> +		head_commit = lookup_expect_commit(head, "HEAD");
>  
>  	git_config(git_merge_config, NULL);
>  

The same comment as head[] vs head_commit->object.sha1[] redundancy
applies from builtin/commit.c here.

Overall, the changes to buitlin/merge.c look very nice, getting rid of the
repeated lookup_commit(head). In a separate patch after this fix gets
ready, we may want to further clean it up so that head_commit being NULL
means head_invalid, losing a redundant variable.
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]