summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Haggerty <mhagger@alum.mit.edu>2017-01-06 17:22:41 +0100
committerJunio C Hamano <gitster@pobox.com>2017-01-07 19:30:09 -0800
commit8bdaecb402cc024ff1ce7fc8856e4ee87f9102f1 (patch)
tree9964565f49ecf5390eb5cd5e9a09abd6e65f2468
parent730e0342869744e33a2db76fda5f3acf28fc889c (diff)
downloadgit-8bdaecb402cc024ff1ce7fc8856e4ee87f9102f1.tar.gz
try_remove_empty_parents(): don't trash argument contents
It's bad manners and surprising and therefore error-prone. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Reviewed-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--refs/files-backend.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 92a9d99ba5..88f8c7aa4b 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -2282,13 +2282,15 @@ static int pack_if_possible_fn(struct ref_entry *entry, void *cb_data)
/*
* Remove empty parents, but spare refs/ and immediate subdirs.
- * Note: munges *refname.
*/
-static void try_remove_empty_parents(char *refname)
+static void try_remove_empty_parents(const char *refname)
{
+ struct strbuf buf = STRBUF_INIT;
char *p, *q;
int i;
- p = refname;
+
+ strbuf_addstr(&buf, refname);
+ p = buf.buf;
for (i = 0; i < 2; i++) { /* refs/{heads,tags,...}/ */
while (*p && *p != '/')
p++;
@@ -2296,8 +2298,7 @@ static void try_remove_empty_parents(char *refname)
while (*p == '/')
p++;
}
- for (q = p; *q; q++)
- ;
+ q = buf.buf + buf.len;
while (1) {
while (q > p && *q != '/')
q--;
@@ -2305,10 +2306,11 @@ static void try_remove_empty_parents(char *refname)
q--;
if (q == p)
break;
- *q = '\0';
- if (rmdir(git_path("%s", refname)))
+ strbuf_setlen(&buf, q - buf.buf);
+ if (rmdir(git_path("%s", buf.buf)))
break;
}
+ strbuf_release(&buf);
}
/* make sure nobody touched the ref, and unlink */