From e67f4b53f5881eede60f3d5975cbd04296afceca Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Wed, 3 Mar 2021 15:14:35 +0900 Subject: [PATCH] Imported Upstream version 2.0.4 --- Documentation/RelNotes/2.0.4.txt | 5 +++ Documentation/git.txt | 3 +- GIT-VERSION-GEN | 2 +- RelNotes | 2 +- alloc.c | 95 ++++++++++++++++++++++++++++------------ blob.c | 11 +---- builtin/blame.c | 1 - builtin/diff-tree.c | 4 +- cache.h | 1 + commit.c | 25 ++--------- object.c | 26 ++++++++--- object.h | 4 +- refs.c | 3 +- t/t4013-diff-various.sh | 10 +++++ t/t7509-commit.sh | 1 + tag.c | 11 +---- tree.c | 11 +---- 17 files changed, 123 insertions(+), 92 deletions(-) create mode 100644 Documentation/RelNotes/2.0.4.txt diff --git a/Documentation/RelNotes/2.0.4.txt b/Documentation/RelNotes/2.0.4.txt new file mode 100644 index 0000000..7e34092 --- /dev/null +++ b/Documentation/RelNotes/2.0.4.txt @@ -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. diff --git a/Documentation/git.txt b/Documentation/git.txt index f95911a..cd50977 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -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], diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 0d1a86c..3e9d508 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.0.3 +DEF_VER=v2.0.4 LF=' ' diff --git a/RelNotes b/RelNotes index 84ad4af..76462ab 120000 --- 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 --- a/alloc.c +++ b/alloc.c @@ -18,25 +18,6 @@ #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 --- 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) diff --git a/builtin/blame.c b/builtin/blame.c index 6a284ce..eefd6bc 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -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)) diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index be6417d..dddd0f9 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -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 --- 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))) diff --git a/commit.c b/commit.c index 4ff8077..65179f9 100644 --- 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) diff --git a/object.c b/object.c index 9c31e9a..69fbbbf 100644 --- 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; } diff --git a/object.h b/object.h index 6e12f2c..5e8d8ee 100644 --- 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 --- 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) diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index e77c09c..f7a9af8 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -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 diff --git a/t/t7509-commit.sh b/t/t7509-commit.sh index b61fd3c..9ac7940 100755 --- a/t/t7509-commit.sh +++ b/t/t7509-commit.sh @@ -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 --- 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 --- 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) -- 2.7.4