Skip to content

Commit 9b143c6

Browse files
author
Junio C Hamano
committed
Teach update-ref about a symbolic ref stored in a textfile.
A symbolic ref is a regular file whose contents is "ref:", followed by optional leading whitespaces, followed by a GIT_DIR relative pathname, followed by optional trailing whitespaces (the optional whitespaces are unconditionally removed, so you cannot have leading nor trailing whitespaces). This can be used in place of a traditional symbolic link .git/HEAD that usually points at "refs/heads/master". You can instead have a regular file .git/HEAD whose contents is "ref: refs/heads/master". [jc: currently the code does not enforce the symbolic ref to begin with refs/, unlike the symbolic link case. It may be worthwhile to require either case to begin with refs/ and not have any /./ nor /../ in them.] Signed-off-by: Junio C Hamano <[email protected]>
1 parent ed1aadf commit 9b143c6

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

update-ref.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ static const char *resolve_ref(const char *path, unsigned char *sha1)
1313

1414
for (;;) {
1515
struct stat st;
16+
char *buf;
1617
int fd;
1718

1819
if (--depth < 0)
@@ -44,7 +45,19 @@ static const char *resolve_ref(const char *path, unsigned char *sha1)
4445
return NULL;
4546
len = read(fd, buffer, sizeof(buffer)-1);
4647
close(fd);
47-
break;
48+
49+
/*
50+
* Is it a symbolic ref?
51+
*/
52+
if (len < 4 || memcmp("ref:", buffer, 4))
53+
break;
54+
buf = buffer + 4;
55+
len -= 4;
56+
while (len && isspace(*buf))
57+
buf++, len--;
58+
while (len && isspace(buf[len-1]))
59+
buf[--len] = 0;
60+
path = git_path("%.*s", len, buf);
4861
}
4962
if (len < 40 || get_sha1_hex(buffer, sha1))
5063
return NULL;

0 commit comments

Comments
 (0)