get_ref_states: strdup entries and free util in stale list
[gitweb.git] / builtin-mktree.c
index 73b0abbd8d9bb6d3b312c382b72f8a6e9d124cfa..098395fda1932674e29f8d2cb332c722a6cb275f 100644 (file)
@@ -71,7 +71,8 @@ static void mktree_line(char *buf, size_t len, int line_termination, int allow_m
 {
        char *ptr, *ntr;
        unsigned mode;
-       enum object_type type;
+       enum object_type mode_type; /* object type derived from mode */
+       enum object_type obj_type; /* object type derived from sha */
        char *path;
        unsigned char sha1[20];
 
@@ -94,17 +95,8 @@ static void mktree_line(char *buf, size_t len, int line_termination, int allow_m
        if (S_ISGITLINK(mode))
                allow_missing = 1;
 
-       if (!allow_missing)
-               type = sha1_object_info(sha1, NULL);
-       else
-               type = object_type(mode);
-
-       if (type < 0)
-               die("object %s unavailable", sha1_to_hex(sha1));
 
        *ntr++ = 0; /* now at the beginning of SHA1 */
-       if (type != type_from_string(ptr))
-               die("object type %s mismatch (%s)", ptr, typename(type));
 
        path = ntr + 41;  /* at the beginning of name */
        if (line_termination && path[0] == '"') {
@@ -113,6 +105,37 @@ static void mktree_line(char *buf, size_t len, int line_termination, int allow_m
                        die("invalid quoting");
                path = strbuf_detach(&p_uq, NULL);
        }
+
+       /*
+        * Object type is redundantly derivable three ways.
+        * These should all agree.
+        */
+       mode_type = object_type(mode);
+       if (mode_type != type_from_string(ptr)) {
+               die("entry '%s' object type (%s) doesn't match mode type (%s)",
+                       path, ptr, typename(mode_type));
+       }
+
+       /* Check the type of object identified by sha1 */
+       obj_type = sha1_object_info(sha1, NULL);
+       if (obj_type < 0) {
+               if (allow_missing) {
+                       ; /* no problem - missing objects are presumed to be of the right type */
+               } else {
+                       die("entry '%s' object %s is unavailable", path, sha1_to_hex(sha1));
+               }
+       } else {
+               if (obj_type != mode_type) {
+                       /*
+                        * The object exists but is of the wrong type.
+                        * This is a problem regardless of allow_missing
+                        * because the new tree entry will never be correct.
+                        */
+                       die("entry '%s' object %s is a %s but specified type was (%s)",
+                               path, sha1_to_hex(sha1), typename(obj_type), typename(mode_type));
+               }
+       }
+
        append_to_tree(mode, sha1, path);
 }
 
@@ -132,7 +155,7 @@ int cmd_mktree(int ac, const char **av, const char *prefix)
                OPT_END()
        };
 
-       ac = parse_options(ac, av, option, mktree_usage, 0);
+       ac = parse_options(ac, av, prefix, option, mktree_usage, 0);
 
        while (!got_eof) {
                while (1) {