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 <junkio@cox.net>maint
parent
ed1aadf1b0
commit
9b143c6e15
13
update-ref.c
13
update-ref.c
|
@ -13,6 +13,7 @@ static const char *resolve_ref(const char *path, unsigned char *sha1)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
char *buf;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (--depth < 0)
|
if (--depth < 0)
|
||||||
|
@ -44,7 +45,19 @@ static const char *resolve_ref(const char *path, unsigned char *sha1)
|
||||||
return NULL;
|
return NULL;
|
||||||
len = read(fd, buffer, sizeof(buffer)-1);
|
len = read(fd, buffer, sizeof(buffer)-1);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Is it a symbolic ref?
|
||||||
|
*/
|
||||||
|
if (len < 4 || memcmp("ref:", buffer, 4))
|
||||||
break;
|
break;
|
||||||
|
buf = buffer + 4;
|
||||||
|
len -= 4;
|
||||||
|
while (len && isspace(*buf))
|
||||||
|
buf++, len--;
|
||||||
|
while (len && isspace(buf[len-1]))
|
||||||
|
buf[--len] = 0;
|
||||||
|
path = git_path("%.*s", len, buf);
|
||||||
}
|
}
|
||||||
if (len < 40 || get_sha1_hex(buffer, sha1))
|
if (len < 40 || get_sha1_hex(buffer, sha1))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in New Issue