• J
    [PATCH] sha1_name: do not accept .git/refs/snap/. · 1dfcfbce
    Junio C Hamano 提交于
    I think Linus did a cut & paste from an early JIT code while
    developing the current extended SHA1 notation, and left it there as a
    courtesy, but the directory does not deserve to be treated any more
    specially than, say, .git/refs/bisect.
    
    If the subdirectories under .git/refs proliferate, we may want to
    switch to scanning that hierarchy at runtime, instead of the current
    hard-coded set, although I think that would be overkill.
    Signed-off-by: NJunio C Hamano <junkio@cox.net>
    From nobody Mon Sep 17 00:00:00 2001
    Subject: [PATCH] Add a new extended SHA1 syntax <name>:<num>
    From: Junio C Hamano <junkio@cox.net>
    Date: 1124617434 -0700
    
    The new notation is a short-hand for <name> followed by <num>
    caret ('^') characters.  E.g. "master:4" is the fourth
    generation ancestor of the current "master" branch head,
    following the first parents; same as "master^^^^" but a bit more
    readable.
    
    This will be used in the updated "git show-branch" command.
    Signed-off-by: NJunio C Hamano <junkio@cox.net>
    
    ---
    
     sha1_name.c |   41 +++++++++++++++++++++++++++++++++++++++++
     1 files changed, 41 insertions(+), 0 deletions(-)
    
    d5098ce769da46df6d45dc8f41b06dd758fdaea7
    diff --git a/sha1_name.c b/sha1_name.c
    --- a/sha1_name.c
    +++ b/sha1_name.c
    @@ -191,9 +191,29 @@ static int get_parent(const char *name, 
     	return -1;
     }
     
    +static int get_nth_ancestor(const char *name, int len,
    +			    unsigned char *result, int generation)
    +{
    +	unsigned char sha1[20];
    +	int ret = get_sha1_1(name, len, sha1);
    +	if (ret)
    +		return ret;
    +
    +	while (generation--) {
    +		struct commit *commit = lookup_commit_reference(sha1);
    +
    +		if (!commit || parse_commit(commit) || !commit->parents)
    +			return -1;
    +		memcpy(sha1, commit->parents->item->object.sha1, 20);
    +	}
    +	memcpy(result, sha1, 20);
    +	return 0;
    +}
    +
     static int get_sha1_1(const char *name, int len, unsigned char *sha1)
     {
     	int parent, ret;
    +	const char *cp;
     
     	/* foo^[0-9] or foo^ (== foo^1); we do not do more than 9 parents. */
     	if (len > 2 && name[len-2] == '^' &&
    @@ -210,6 +230,27 @@ static int get_sha1_1(const char *name, 
     	if (parent >= 0)
     		return get_parent(name, len, sha1, parent);
     
    +	/* name:3 is name^^^,
    +	 * name:12 is name^^^^^^^^^^^^, and
    +	 * name: is name
    +	 */
    +	parent = 0;
    +	for (cp = name + len - 1; name <= cp; cp--) {
    +		int ch = *cp;
    +		if ('0' <= ch && ch <= '9')
    +			continue;
    +		if (ch != ':')
    +			parent = -1;
    +		break;
    +	}
    +	if (!parent && *cp == ':') {
    +		int len1 = cp - name;
    +		cp++;
    +		while (cp < name + len)
    +			parent = parent * 10 + *cp++ - '0';
    +		return get_nth_ancestor(name, len1, sha1, parent);
    +	}
    +
     	ret = get_sha1_basic(name, len, sha1);
     	if (!ret)
     		return 0;
    1dfcfbce
sha1_name.c 4.4 KB