summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/name-rev.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 98f55bcea9..23a639ff30 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -17,7 +17,7 @@
#define CUTOFF_DATE_SLOP 86400
struct rev_name {
- const char *tip_name;
+ char *tip_name;
timestamp_t taggerdate;
int generation;
int distance;
@@ -34,7 +34,7 @@ static struct commit_rev_name rev_names;
static int is_valid_rev_name(const struct rev_name *name)
{
- return name && name->tip_name;
+ return name && (name->generation || name->tip_name);
}
static struct rev_name *get_commit_rev_name(const struct commit *commit)
@@ -87,9 +87,20 @@ static struct rev_name *create_or_update_name(struct commit *commit,
{
struct rev_name *name = commit_rev_name_at(&rev_names, commit);
- if (is_valid_rev_name(name) &&
- !is_better_name(name, taggerdate, distance, from_tag))
- return NULL;
+ if (is_valid_rev_name(name)) {
+ if (!is_better_name(name, taggerdate, distance, from_tag))
+ return NULL;
+
+ /*
+ * This string might still be shared with ancestors
+ * (generation > 0). We can release it here regardless,
+ * because the new name that has just won will be better
+ * for them as well, so name_rev() will replace these
+ * stale pointers when it processes the parents.
+ */
+ if (!name->generation)
+ free(name->tip_name);
+ }
name->taggerdate = taggerdate;
name->generation = generation;