cherry-pick: Suggest a better method to retain authorship
[gitweb.git] / refs.c
diff --git a/refs.c b/refs.c
index da09e434c7ac5dfceebc6a2ffd85e57eaeb75eef..7a1f89caad17cfb090e683c9888537666e8398b9 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -663,6 +663,8 @@ struct ref_lock *lock_ref_sha1(const char *ref, const unsigned char *old_sha1)
 
 struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *old_sha1)
 {
+       if (check_ref_format(ref) == -1)
+               return NULL;
        return lock_ref_sha1_basic(ref, old_sha1, NULL);
 }
 
@@ -826,8 +828,8 @@ int rename_ref(const char *oldref, const char *newref, const char *logmsg)
                goto rollback;
        }
 
-       if (!strncmp(oldref, "refs/heads/", 11) &&
-                       !strncmp(newref, "refs/heads/", 11)) {
+       if (!prefixcmp(oldref, "refs/heads/") &&
+                       !prefixcmp(newref, "refs/heads/")) {
                char oldsection[1024], newsection[1024];
 
                snprintf(oldsection, 1024, "branch.%s", oldref + 11);
@@ -892,8 +894,8 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
        log_file = git_path("logs/%s", ref_name);
 
        if (log_all_ref_updates &&
-           (!strncmp(ref_name, "refs/heads/", 11) ||
-            !strncmp(ref_name, "refs/remotes/", 13) ||
+           (!prefixcmp(ref_name, "refs/heads/") ||
+            !prefixcmp(ref_name, "refs/remotes/") ||
             !strcmp(ref_name, "HEAD"))) {
                if (safe_create_leading_directories(log_file) < 0)
                        return error("unable to create directory for %s",
@@ -998,6 +1000,9 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
        if (logmsg && read_ref(ref_target, old_sha1))
                hashclr(old_sha1);
 
+       if (safe_create_leading_directories(git_HEAD) < 0)
+               return error("unable to create directory for %s", git_HEAD);
+
 #ifndef NO_SYMLINK_HEAD
        if (prefer_symlink_refs) {
                unlink(git_HEAD);
@@ -1037,7 +1042,9 @@ int create_symref(const char *ref_target, const char *refs_heads_master,
                return -1;
        }
 
+#ifndef NO_SYMLINK_HEAD
        done:
+#endif
        if (logmsg && !read_ref(refs_heads_master, new_sha1))
                log_ref_write(ref_target, old_sha1, new_sha1, logmsg);
 
@@ -1187,12 +1194,14 @@ int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
                    !message || message[0] != ' ' ||
                    (message[1] != '+' && message[1] != '-') ||
                    !isdigit(message[2]) || !isdigit(message[3]) ||
-                   !isdigit(message[4]) || !isdigit(message[5]) ||
-                   message[6] != '\t')
+                   !isdigit(message[4]) || !isdigit(message[5]))
                        continue; /* corrupt? */
                email_end[1] = '\0';
                tz = strtol(message + 1, NULL, 10);
-               message += 7;
+               if (message[6] != '\t')
+                       message += 6;
+               else
+                       message += 7;
                ret = fn(osha1, nsha1, buf+82, timestamp, tz, message, cb_data);
                if (ret)
                        break;
@@ -1204,7 +1213,7 @@ int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data)
 static int do_for_each_reflog(const char *base, each_ref_fn fn, void *cb_data)
 {
        DIR *dir = opendir(git_path("logs/%s", base));
-       int retval = errno;
+       int retval = 0;
 
        if (dir) {
                struct dirent *de;
@@ -1244,6 +1253,8 @@ static int do_for_each_reflog(const char *base, each_ref_fn fn, void *cb_data)
                free(log);
                closedir(dir);
        }
+       else if (*base)
+               return errno;
        return retval;
 }