diff options
Diffstat (limited to 'refs.c')
-rw-r--r-- | refs.c | 19 |
1 files changed, 19 insertions, 0 deletions
@@ -1119,10 +1119,16 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1, return 0; } +static int is_branch(const char *refname) +{ + return !strcmp(refname, "HEAD") || !prefixcmp(refname, "refs/heads/"); +} + int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, const char *logmsg) { static char term = '\n'; + struct object *o; if (!lock) return -1; @@ -1130,6 +1136,19 @@ int write_ref_sha1(struct ref_lock *lock, unlock_ref(lock); return 0; } + o = parse_object(sha1); + if (!o) { + error("Trying to write ref %s with nonexistant object %s", + lock->ref_name, sha1_to_hex(sha1)); + unlock_ref(lock); + return -1; + } + if (o->type != OBJ_COMMIT && is_branch(lock->ref_name)) { + error("Trying to write non-commit object %s to branch %s", + sha1_to_hex(sha1), lock->ref_name); + unlock_ref(lock); + return -1; + } if (write_in_full(lock->lock_fd, sha1_to_hex(sha1), 40) != 40 || write_in_full(lock->lock_fd, &term, 1) != 1 || close(lock->lock_fd) < 0) { |