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>
This commit is contained in:
Junio C Hamano 2005-09-25 19:30:24 -07:00
parent ed1aadf1b0
commit 9b143c6e15

View File

@ -13,6 +13,7 @@ static const char *resolve_ref(const char *path, unsigned char *sha1)
for (;;) {
struct stat st;
char *buf;
int fd;
if (--depth < 0)
@ -44,7 +45,19 @@ static const char *resolve_ref(const char *path, unsigned char *sha1)
return NULL;
len = read(fd, buffer, sizeof(buffer)-1);
close(fd);
break;
/*
* Is it a symbolic ref?
*/
if (len < 4 || memcmp("ref:", buffer, 4))
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))
return NULL;