]> asedeno.scripts.mit.edu Git - git.git/blobdiff - refs.c
receive-pack: check object type of sha1 before using them as commits
[git.git] / refs.c
diff --git a/refs.c b/refs.c
index ae532540cf2592aee2be7610ac811082c3a9b6be..7484a46d6834b4c85dd81f1f38596bc3be087426 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -613,34 +613,70 @@ int check_ref_format(const char *ref)
                while ((ch = *cp++) == '/')
                        ; /* tolerate duplicated slashes */
                if (!ch)
-                       return -1; /* should not end with slashes */
+                       /* should not end with slashes */
+                       return CHECK_REF_FORMAT_ERROR;
 
                /* we are at the beginning of the path component */
                if (ch == '.')
-                       return -1;
+                       return CHECK_REF_FORMAT_ERROR;
                bad_type = bad_ref_char(ch);
                if (bad_type) {
-                       return (bad_type == 2 && !*cp) ? -3 : -1;
+                       return (bad_type == 2 && !*cp)
+                               ? CHECK_REF_FORMAT_WILDCARD
+                               : CHECK_REF_FORMAT_ERROR;
                }
 
                /* scan the rest of the path component */
                while ((ch = *cp++) != 0) {
                        bad_type = bad_ref_char(ch);
                        if (bad_type) {
-                               return (bad_type == 2 && !*cp) ? -3 : -1;
+                               return (bad_type == 2 && !*cp)
+                                       ? CHECK_REF_FORMAT_WILDCARD
+                                       : CHECK_REF_FORMAT_ERROR;
                        }
                        if (ch == '/')
                                break;
                        if (ch == '.' && *cp == '.')
-                               return -1;
+                               return CHECK_REF_FORMAT_ERROR;
                }
                level++;
                if (!ch) {
                        if (level < 2)
-                               return -2; /* at least of form "heads/blah" */
-                       return 0;
+                               return CHECK_REF_FORMAT_ONELEVEL;
+                       return CHECK_REF_FORMAT_OK;
+               }
+       }
+}
+
+const char *ref_rev_parse_rules[] = {
+       "%.*s",
+       "refs/%.*s",
+       "refs/tags/%.*s",
+       "refs/heads/%.*s",
+       "refs/remotes/%.*s",
+       "refs/remotes/%.*s/HEAD",
+       NULL
+};
+
+const char *ref_fetch_rules[] = {
+       "%.*s",
+       "refs/%.*s",
+       "refs/heads/%.*s",
+       NULL
+};
+
+int refname_match(const char *abbrev_name, const char *full_name, const char **rules)
+{
+       const char **p;
+       const int abbrev_name_len = strlen(abbrev_name);
+
+       for (p = rules; *p; p++) {
+               if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) {
+                       return 1;
                }
        }
+
+       return 0;
 }
 
 static struct ref_lock *verify_lock(struct ref_lock *lock,
@@ -785,9 +821,13 @@ 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, int flags)
 {
-       if (check_ref_format(ref) == -1)
+       switch (check_ref_format(ref)) {
+       case CHECK_REF_FORMAT_ERROR:
+       case CHECK_REF_FORMAT_WILDCARD:
                return NULL;
-       return lock_ref_sha1_basic(ref, old_sha1, flags, NULL);
+       default:
+               return lock_ref_sha1_basic(ref, old_sha1, flags, NULL);
+       }
 }
 
 static struct lock_file packlock;
@@ -1063,7 +1103,7 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1,
        adjust_shared_perm(log_file);
 
        msglen = msg ? strlen(msg) : 0;
-       committer = git_committer_info(-1);
+       committer = git_committer_info(0);
        maxlen = strlen(committer) + msglen + 100;
        logrec = xmalloc(maxlen);
        len = sprintf(logrec, "%s %s %s\n",
@@ -1433,3 +1473,11 @@ int update_ref(const char *action, const char *refname,
        }
        return 0;
 }
+
+struct ref *find_ref_by_name(struct ref *list, const char *name)
+{
+       for ( ; list; list = list->next)
+               if (!strcmp(list->name, name))
+                       return list;
+       return NULL;
+}