revert: plug memory leak in "cherry-pick root commit" codepath
The empty tree passed as common ancestor to merge_trees() when cherry-picking a parentless commit is allocated on the heap and never freed. Leaking such a small one-time allocation is not a very big problem, but now that "git cherry-pick" can cherry-pick multiple commits it can start to add up. Avoid the leak by storing the fake tree exactly once in the BSS section (i.e., use a static). While at it, let's add a test to make sure cherry-picking multiple parentless commits continues to work. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jonathan Nieder committed
Aug 14, 2011 at 10:22 UTC
127f04522292fc62152762405c92d6acca4dbcb5
2 files changed
+27
-7
builtin/revert.c
+1
-6
@@ -273,12 +273,7 @@ static void write_message(struct strbuf *msgbuf, const char *filename)
273
274
static struct tree *empty_tree(void)
275
{
276
- struct tree *tree = xcalloc(1, sizeof(struct tree));
277
-
278
- tree->object.parsed = 1;
279
- tree->object.type = OBJ_TREE;
280
- pretend_sha1_file(NULL, 0, OBJ_TREE, tree->object.sha1);
281
- return tree;
276
+ return lookup_tree((const unsigned char *)EMPTY_TREE_SHA1_BIN);
277
}
278
279
static NORETURN void die_dirty_index(const char *me)
t/t3503-cherry-pick-root.sh
+26
-1
@@ -16,15 +16,40 @@ test_expect_success setup '
16
echo second > file2 &&
17
git add file2 &&
18
test_tick &&
19
- git commit -m "second"
19
+ git commit -m "second" &&
20
+
21
+ git symbolic-ref HEAD refs/heads/third &&
22
+ rm .git/index file2 &&
23
+ echo third > file3 &&
24
+ git add file3 &&
25
+ test_tick &&
26
+ git commit -m "third"
27
28
'
29
30
test_expect_success 'cherry-pick a root commit' '
31
32
+ git checkout second^0 &&
33
git cherry-pick master &&
34
test first = $(cat file1)
35
36
'
37
38
+test_expect_success 'cherry-pick two root commits' '
39
+
40
+ echo first >expect.file1 &&
41
+ echo second >expect.file2 &&
42
+ echo third >expect.file3 &&
43
+
44
+ git checkout second^0 &&
45
+ git cherry-pick master third &&
46
+
47
+ test_cmp expect.file1 file1 &&
48
+ test_cmp expect.file2 file2 &&
49
+ test_cmp expect.file3 file3 &&
50
+ git rev-parse --verify HEAD^^ &&
51
+ test_must_fail git rev-parse --verify HEAD^^^
52
+
53
+'
54
+
55
test_done