Imported Upstream version 2.0.4 upstream/2.0.4
authorDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 3 Mar 2021 06:14:35 +0000 (15:14 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Wed, 3 Mar 2021 06:14:35 +0000 (15:14 +0900)
17 files changed:
Documentation/RelNotes/2.0.4.txt [new file with mode: 0644]
Documentation/git.txt
GIT-VERSION-GEN
RelNotes
alloc.c
blob.c
builtin/blame.c
builtin/diff-tree.c
cache.h
commit.c
object.c
object.h
refs.c
t/t4013-diff-various.sh
t/t7509-commit.sh
tag.c
tree.c

diff --git a/Documentation/RelNotes/2.0.4.txt b/Documentation/RelNotes/2.0.4.txt
new file mode 100644 (file)
index 0000000..7e34092
--- /dev/null
@@ -0,0 +1,5 @@
+Git v2.0.4 Release Notes
+========================
+
+ * An earlier update to v2.0.2 broken output from "git diff-tree",
+   which is fixed in this release.
index f95911a..cd50977 100644 (file)
@@ -43,9 +43,10 @@ unreleased) version of Git, that is available from 'master'
 branch of the `git.git` repository.
 Documentation for older releases are available here:
 
-* link:v2.0.3/git.html[documentation for release 2.0.3]
+* link:v2.0.4/git.html[documentation for release 2.0.4]
 
 * release notes for
+  link:RelNotes/2.0.4.txt[2.0.4],
   link:RelNotes/2.0.3.txt[2.0.3],
   link:RelNotes/2.0.2.txt[2.0.2],
   link:RelNotes/2.0.1.txt[2.0.1],
index 0d1a86c..3e9d508 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.0.3
+DEF_VER=v2.0.4
 
 LF='
 '
index 84ad4af..76462ab 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.0.3.txt
\ No newline at end of file
+Documentation/RelNotes/2.0.4.txt
\ No newline at end of file
diff --git a/alloc.c b/alloc.c
index eb22a45..12afadf 100644 (file)
--- a/alloc.c
+++ b/alloc.c
 
 #define BLOCKING 1024
 
-#define DEFINE_ALLOCATOR(name, type)                           \
-static unsigned int name##_allocs;                             \
-void *alloc_##name##_node(void)                                        \
-{                                                              \
-       static int nr;                                          \
-       static type *block;                                     \
-       void *ret;                                              \
-                                                               \
-       if (!nr) {                                              \
-               nr = BLOCKING;                                  \
-               block = xmalloc(BLOCKING * sizeof(type));       \
-       }                                                       \
-       nr--;                                                   \
-       name##_allocs++;                                        \
-       ret = block++;                                          \
-       memset(ret, 0, sizeof(type));                           \
-       return ret;                                             \
-}
-
 union any_object {
        struct object object;
        struct blob blob;
@@ -45,17 +26,73 @@ union any_object {
        struct tag tag;
 };
 
-DEFINE_ALLOCATOR(blob, struct blob)
-DEFINE_ALLOCATOR(tree, struct tree)
-DEFINE_ALLOCATOR(raw_commit, struct commit)
-DEFINE_ALLOCATOR(tag, struct tag)
-DEFINE_ALLOCATOR(object, union any_object)
+struct alloc_state {
+       int count; /* total number of nodes allocated */
+       int nr;    /* number of nodes left in current allocation */
+       void *p;   /* first free node in current allocation */
+};
+
+static inline void *alloc_node(struct alloc_state *s, size_t node_size)
+{
+       void *ret;
+
+       if (!s->nr) {
+               s->nr = BLOCKING;
+               s->p = xmalloc(BLOCKING * node_size);
+       }
+       s->nr--;
+       s->count++;
+       ret = s->p;
+       s->p = (char *)s->p + node_size;
+       memset(ret, 0, node_size);
+       return ret;
+}
+
+static struct alloc_state blob_state;
+void *alloc_blob_node(void)
+{
+       struct blob *b = alloc_node(&blob_state, sizeof(struct blob));
+       b->object.type = OBJ_BLOB;
+       return b;
+}
+
+static struct alloc_state tree_state;
+void *alloc_tree_node(void)
+{
+       struct tree *t = alloc_node(&tree_state, sizeof(struct tree));
+       t->object.type = OBJ_TREE;
+       return t;
+}
+
+static struct alloc_state tag_state;
+void *alloc_tag_node(void)
+{
+       struct tag *t = alloc_node(&tag_state, sizeof(struct tag));
+       t->object.type = OBJ_TAG;
+       return t;
+}
+
+static struct alloc_state object_state;
+void *alloc_object_node(void)
+{
+       struct object *obj = alloc_node(&object_state, sizeof(union any_object));
+       obj->type = OBJ_NONE;
+       return obj;
+}
+
+static struct alloc_state commit_state;
+
+unsigned int alloc_commit_index(void)
+{
+       static unsigned int count;
+       return count++;
+}
 
 void *alloc_commit_node(void)
 {
-       static int commit_count;
-       struct commit *c = alloc_raw_commit_node();
-       c->index = commit_count++;
+       struct commit *c = alloc_node(&commit_state, sizeof(struct commit));
+       c->object.type = OBJ_COMMIT;
+       c->index = alloc_commit_index();
        return c;
 }
 
@@ -66,13 +103,13 @@ static void report(const char *name, unsigned int count, size_t size)
 }
 
 #define REPORT(name, type)     \
-    report(#name, name##_allocs, name##_allocs * sizeof(type) >> 10)
+    report(#name, name##_state.count, name##_state.count * sizeof(type) >> 10)
 
 void alloc_report(void)
 {
        REPORT(blob, struct blob);
        REPORT(tree, struct tree);
-       REPORT(raw_commit, struct commit);
+       REPORT(commit, struct commit);
        REPORT(tag, struct tag);
        REPORT(object, union any_object);
 }
diff --git a/blob.c b/blob.c
index ae320bd..1fcb8e4 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -7,15 +7,8 @@ struct blob *lookup_blob(const unsigned char *sha1)
 {
        struct object *obj = lookup_object(sha1);
        if (!obj)
-               return create_object(sha1, OBJ_BLOB, alloc_blob_node());
-       if (!obj->type)
-               obj->type = OBJ_BLOB;
-       if (obj->type != OBJ_BLOB) {
-               error("Object %s is a %s, not a blob",
-                     sha1_to_hex(sha1), typename(obj->type));
-               return NULL;
-       }
-       return (struct blob *) obj;
+               return create_object(sha1, alloc_blob_node());
+       return object_as_type(obj, OBJ_BLOB, 0);
 }
 
 int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size)
index 6a284ce..eefd6bc 100644 (file)
@@ -2041,7 +2041,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
        commit = alloc_commit_node();
        commit->object.parsed = 1;
        commit->date = now;
-       commit->object.type = OBJ_COMMIT;
        parent_tail = &commit->parents;
 
        if (!resolve_ref_unsafe("HEAD", head_sha1, 1, NULL))
index be6417d..dddd0f9 100644 (file)
@@ -72,9 +72,7 @@ static int diff_tree_stdin(char *line)
        line[len-1] = 0;
        if (get_sha1_hex(line, sha1))
                return -1;
-       obj = lookup_unknown_object(sha1);
-       if (!obj || !obj->parsed)
-               obj = parse_object(sha1);
+       obj = parse_object(sha1);
        if (!obj)
                return -1;
        if (obj->type == OBJ_COMMIT)
diff --git a/cache.h b/cache.h
index cc46be4..c708062 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -1354,6 +1354,7 @@ extern void *alloc_commit_node(void);
 extern void *alloc_tag_node(void);
 extern void *alloc_object_node(void);
 extern void alloc_report(void);
+extern unsigned int alloc_commit_index(void);
 
 /* trace.c */
 __attribute__((format (printf, 1, 2)))
index 4ff8077..65179f9 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -18,19 +18,6 @@ int save_commit_buffer = 1;
 
 const char *commit_type = "commit";
 
-static struct commit *check_commit(struct object *obj,
-                                  const unsigned char *sha1,
-                                  int quiet)
-{
-       if (obj->type != OBJ_COMMIT) {
-               if (!quiet)
-                       error("Object %s is a %s, not a commit",
-                             sha1_to_hex(sha1), typename(obj->type));
-               return NULL;
-       }
-       return (struct commit *) obj;
-}
-
 struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
                                              int quiet)
 {
@@ -38,7 +25,7 @@ struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
 
        if (!obj)
                return NULL;
-       return check_commit(obj, sha1, quiet);
+       return object_as_type(obj, OBJ_COMMIT, quiet);
 }
 
 struct commit *lookup_commit_reference(const unsigned char *sha1)
@@ -61,13 +48,9 @@ struct commit *lookup_commit_or_die(const unsigned char *sha1, const char *ref_n
 struct commit *lookup_commit(const unsigned char *sha1)
 {
        struct object *obj = lookup_object(sha1);
-       if (!obj) {
-               struct commit *c = alloc_commit_node();
-               return create_object(sha1, OBJ_COMMIT, c);
-       }
-       if (!obj->type)
-               obj->type = OBJ_COMMIT;
-       return check_commit(obj, sha1, 0);
+       if (!obj)
+               return create_object(sha1, alloc_commit_node());
+       return object_as_type(obj, OBJ_COMMIT, 0);
 }
 
 struct commit *lookup_commit_reference_by_name(const char *name)
index 9c31e9a..69fbbbf 100644 (file)
--- a/object.c
+++ b/object.c
@@ -141,13 +141,12 @@ static void grow_object_hash(void)
        obj_hash_size = new_hash_size;
 }
 
-void *create_object(const unsigned char *sha1, int type, void *o)
+void *create_object(const unsigned char *sha1, void *o)
 {
        struct object *obj = o;
 
        obj->parsed = 0;
        obj->used = 0;
-       obj->type = type;
        obj->flags = 0;
        hashcpy(obj->sha1, sha1);
 
@@ -159,11 +158,30 @@ void *create_object(const unsigned char *sha1, int type, void *o)
        return obj;
 }
 
+void *object_as_type(struct object *obj, enum object_type type, int quiet)
+{
+       if (obj->type == type)
+               return obj;
+       else if (obj->type == OBJ_NONE) {
+               if (type == OBJ_COMMIT)
+                       ((struct commit *)obj)->index = alloc_commit_index();
+               obj->type = type;
+               return obj;
+       }
+       else {
+               if (!quiet)
+                       error("object %s is a %s, not a %s",
+                             sha1_to_hex(obj->sha1),
+                             typename(obj->type), typename(type));
+               return NULL;
+       }
+}
+
 struct object *lookup_unknown_object(const unsigned char *sha1)
 {
        struct object *obj = lookup_object(sha1);
        if (!obj)
-               obj = create_object(sha1, OBJ_NONE, alloc_object_node());
+               obj = create_object(sha1, alloc_object_node());
        return obj;
 }
 
@@ -214,8 +232,6 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
                warning("object %s has unknown type id %d", sha1_to_hex(sha1), type);
                obj = NULL;
        }
-       if (obj && obj->type == OBJ_NONE)
-               obj->type = type;
        return obj;
 }
 
index 6e12f2c..5e8d8ee 100644 (file)
--- a/object.h
+++ b/object.h
@@ -79,7 +79,9 @@ extern struct object *get_indexed_object(unsigned int);
  */
 struct object *lookup_object(const unsigned char *sha1);
 
-extern void *create_object(const unsigned char *sha1, int type, void *obj);
+extern void *create_object(const unsigned char *sha1, void *obj);
+
+void *object_as_type(struct object *obj, enum object_type type, int quiet);
 
 /*
  * Returns the object, having parsed it to find out what it is.
diff --git a/refs.c b/refs.c
index 59fb700..f0bd7ac 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -1520,9 +1520,8 @@ static enum peel_status peel_object(const unsigned char *name, unsigned char *sh
 
        if (o->type == OBJ_NONE) {
                int type = sha1_object_info(name, NULL);
-               if (type < 0)
+               if (type < 0 || !object_as_type(o, type, 0))
                        return PEEL_INVALID;
-               o->type = type;
        }
 
        if (o->type != OBJ_TAG)
index e77c09c..f7a9af8 100755 (executable)
@@ -324,4 +324,14 @@ test_expect_success 'diff --cached -- file on unborn branch' '
        test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--cached_--_file0" result
 '
 
+test_expect_success 'diff-tree --stdin with log formatting' '
+       cat >expect <<-\EOF &&
+       Side
+       Third
+       Second
+       EOF
+       git rev-list master | git diff-tree --stdin --format=%s -s >actual &&
+       test_cmp expect actual
+'
+
 test_done
index b61fd3c..9ac7940 100755 (executable)
@@ -77,6 +77,7 @@ test_expect_success '--amend option copies authorship' '
        git commit -a --amend -m "amend test" &&
        author_header Initial >expect &&
        author_header HEAD >actual &&
+       test_cmp expect actual &&
 
        echo "amend test" >expect &&
        message_body HEAD >actual &&
diff --git a/tag.c b/tag.c
index 7b07921..82d841b 100644 (file)
--- a/tag.c
+++ b/tag.c
@@ -40,15 +40,8 @@ struct tag *lookup_tag(const unsigned char *sha1)
 {
        struct object *obj = lookup_object(sha1);
        if (!obj)
-               return create_object(sha1, OBJ_TAG, alloc_tag_node());
-       if (!obj->type)
-               obj->type = OBJ_TAG;
-       if (obj->type != OBJ_TAG) {
-               error("Object %s is a %s, not a tag",
-                     sha1_to_hex(sha1), typename(obj->type));
-               return NULL;
-       }
-       return (struct tag *) obj;
+               return create_object(sha1, alloc_tag_node());
+       return object_as_type(obj, OBJ_TAG, 0);
 }
 
 static unsigned long parse_tag_date(const char *buf, const char *tail)
diff --git a/tree.c b/tree.c
index c8c49d7..bb02c1c 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -183,15 +183,8 @@ struct tree *lookup_tree(const unsigned char *sha1)
 {
        struct object *obj = lookup_object(sha1);
        if (!obj)
-               return create_object(sha1, OBJ_TREE, alloc_tree_node());
-       if (!obj->type)
-               obj->type = OBJ_TREE;
-       if (obj->type != OBJ_TREE) {
-               error("Object %s is a %s, not a tree",
-                     sha1_to_hex(sha1), typename(obj->type));
-               return NULL;
-       }
-       return (struct tree *) obj;
+               return create_object(sha1, alloc_tree_node());
+       return object_as_type(obj, OBJ_TREE, 0);
 }
 
 int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)