Skip to content

Commit 4f7599a

Browse files
author
Junio C Hamano
committed
[PATCH] Add a new extended SHA1 syntax <name>~<num>
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: Junio C Hamano <junkio@cox.net>
1 parent 792fe55 commit 4f7599a

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

sha1_name.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,29 @@ static int get_parent(const char *name, int len,
191191
return -1;
192192
}
193193

194+
static int get_nth_ancestor(const char *name, int len,
195+
unsigned char *result, int generation)
196+
{
197+
unsigned char sha1[20];
198+
int ret = get_sha1_1(name, len, sha1);
199+
if (ret)
200+
return ret;
201+
202+
while (generation--) {
203+
struct commit *commit = lookup_commit_reference(sha1);
204+
205+
if (!commit || parse_commit(commit) || !commit->parents)
206+
return -1;
207+
memcpy(sha1, commit->parents->item->object.sha1, 20);
208+
}
209+
memcpy(result, sha1, 20);
210+
return 0;
211+
}
212+
194213
static int get_sha1_1(const char *name, int len, unsigned char *sha1)
195214
{
196215
int parent, ret;
216+
const char *cp;
197217

198218
/* foo^[0-9] or foo^ (== foo^1); we do not do more than 9 parents. */
199219
if (len > 2 && name[len-2] == '^' &&
@@ -210,6 +230,27 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1)
210230
if (parent >= 0)
211231
return get_parent(name, len, sha1, parent);
212232

233+
/* "name~3" is "name^^^",
234+
* "name~12" is "name^^^^^^^^^^^^", and
235+
* "name~" and "name~0" are name -- not "name^0"!
236+
*/
237+
parent = 0;
238+
for (cp = name + len - 1; name <= cp; cp--) {
239+
int ch = *cp;
240+
if ('0' <= ch && ch <= '9')
241+
continue;
242+
if (ch != '~')
243+
parent = -1;
244+
break;
245+
}
246+
if (!parent && *cp == '~') {
247+
int len1 = cp - name;
248+
cp++;
249+
while (cp < name + len)
250+
parent = parent * 10 + *cp++ - '0';
251+
return get_nth_ancestor(name, len1, sha1, parent);
252+
}
253+
213254
ret = get_sha1_basic(name, len, sha1);
214255
if (!ret)
215256
return 0;

0 commit comments

Comments
 (0)