From f65fdf04a13d2252de8b2b4b161db7c43f2c28ad Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 30 Jun 2005 11:04:59 -0700 Subject: Add support for "forcing" a ref on the remote side A "old ref" of all zeroes is considered a "don't care" ref, and allows us to say "write the new ref regardless of what the old ref contained (or even if it existed at all)". This allows (if git-send-pack were to do it) creating new refs, and fixing up old ones. --- receive-pack.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/receive-pack.c b/receive-pack.c index 7ce5f1e24..0a3e012ad 100644 --- a/receive-pack.c +++ b/receive-pack.c @@ -97,11 +97,22 @@ struct command { struct command *commands = NULL; +static int is_all_zeroes(const char *hex) +{ + int i; + for (i = 0; i < 40; i++) + if (*hex++ != '0') + return 0; + return 1; +} + static int verify_old_ref(const char *name, char *hex_contents) { int fd, ret; char buffer[60]; + if (is_all_zeroes(hex_contents)) + return 0; fd = open(name, O_RDONLY); if (fd < 0) return -1; @@ -125,8 +136,6 @@ static void update(const char *name, unsigned char *old_sha1, unsigned char *new memcpy(lock_name + namelen, ".lock", 6); strcpy(new_hex, sha1_to_hex(new_sha1)); - new_hex[40] = '\n'; - new_hex[41] = 0; old_hex = sha1_to_hex(old_sha1); if (!has_sha1_file(new_sha1)) die("unpack should have generated %s, but I can't find it!", new_hex); @@ -134,7 +143,14 @@ static void update(const char *name, unsigned char *old_sha1, unsigned char *new newfd = open(lock_name, O_CREAT | O_EXCL | O_WRONLY, 0644); if (newfd < 0) die("unable to create %s (%s)", lock_name, strerror(errno)); + + /* Write the ref with an ending '\n' */ + new_hex[40] = '\n'; + new_hex[41] = 0; written = write(newfd, new_hex, 41); + /* Remove the '\n' again */ + new_hex[40] = 0; + close(newfd); if (written != 41) { unlink(lock_name); -- cgit v1.2.1