git-pull: allow pulling into an empty repository
[gitweb.git] / refs.c
diff --git a/refs.c b/refs.c
index 858c53445c01fc0ed0db2affc99ddf9b9c319e19..f003a0b1080267b419296b3b37312b858b8b215d 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -234,6 +234,12 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int *
                        }
                }
 
+               /* Is it a directory? */
+               if (S_ISDIR(st.st_mode)) {
+                       errno = EISDIR;
+                       return NULL;
+               }
+
                /*
                 * Anything else, just open it and try to use it as
                 * a ref
@@ -498,7 +504,7 @@ static int remove_empty_dir_recursive(char *path, int len)
                    strcpy(path + len, e->d_name) &&
                    !lstat(path, &st) &&
                    S_ISDIR(st.st_mode) &&
-                   remove_empty_dir_recursive(path, len + namlen))
+                   !remove_empty_dir_recursive(path, len + namlen))
                        continue; /* happy */
 
                /* path too long, stat fails, or non-directory still exists */
@@ -621,12 +627,13 @@ struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *o
        return lock_ref_sha1_basic(ref, old_sha1, NULL);
 }
 
+static struct lock_file packlock;
+
 static int repack_without_ref(const char *refname)
 {
        struct ref_list *list, *packed_ref_list;
        int fd;
        int found = 0;
-       struct lock_file packlock;
 
        packed_ref_list = get_packed_refs();
        for (list = packed_ref_list; list; list = list->next) {
@@ -714,7 +721,8 @@ static int log_ref_write(struct ref_lock *lock,
        char *logrec;
        const char *committer;
 
-       if (log_all_ref_updates) {
+       if (log_all_ref_updates &&
+           !strncmp(lock->ref_name, "refs/heads/", 11)) {
                if (safe_create_leading_directories(lock->log_file) < 0)
                        return error("unable to create directory for %s",
                                lock->log_file);
@@ -723,10 +731,20 @@ static int log_ref_write(struct ref_lock *lock,
 
        logfd = open(lock->log_file, oflags, 0666);
        if (logfd < 0) {
-               if (!log_all_ref_updates && errno == ENOENT)
+               if (!(oflags & O_CREAT) && errno == ENOENT)
                        return 0;
-               return error("Unable to append to %s: %s",
-                       lock->log_file, strerror(errno));
+
+               if ((oflags & O_CREAT) && errno == EISDIR) {
+                       if (remove_empty_directories(lock->log_file)) {
+                               return error("There are still logs under '%s'",
+                                            lock->log_file);
+                       }
+                       logfd = open(lock->log_file, oflags, 0666);
+               }
+
+               if (logfd < 0)
+                       return error("Unable to append to %s: %s",
+                                    lock->log_file, strerror(errno));
        }
 
        committer = git_committer_info(1);
@@ -788,7 +806,7 @@ int write_ref_sha1(struct ref_lock *lock,
        return 0;
 }
 
-int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1)
+int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *sha1)
 {
        const char *logfile, *logdata, *logend, *rec, *lastgt, *lastrec;
        char *tz_c;
@@ -821,7 +839,7 @@ int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1)
                if (!lastgt)
                        die("Log %s is corrupt.", logfile);
                date = strtoul(lastgt + 1, &tz_c, 10);
-               if (date <= at_time) {
+               if (date <= at_time || cnt == 0) {
                        if (lastrec) {
                                if (get_sha1_hex(lastrec, logged_sha1))
                                        die("Log %s is corrupt.", logfile);
@@ -852,6 +870,8 @@ int read_ref_at(const char *ref, unsigned long at_time, unsigned char *sha1)
                        return 0;
                }
                lastrec = rec;
+               if (cnt > 0)
+                       cnt--;
        }
 
        rec = logdata;