Skip to content

Commit ce1d6d9

Browse files
jiangxingitster
authored andcommitted
bundle: lost objects when removing duplicate pendings
`git rev-list` will list one commit for the following command: $ git rev-list 'main^!' <tip-commit-of-main-branch> But providing the same rev-list args to `git bundle`, fail to create a bundle file. $ git bundle create - 'main^!' # v2 git bundle -<OID> <one-line-message> fatal: Refusing to create empty bundle. This is because when removing duplicate objects in function `object_array_remove_duplicates()`, one unique pending object which has the same name is deleted by mistake. The revision arg 'main^!' in the above example is parsed by `handle_revision_arg()`, and at lease two different objects will be appended to `revs.pending`, one points to the parent commit of the "main" branch, and the other points to the tip commit of the "main" branch. These two objects have the same name "main". Only one object is left with the name "main" after calling the function `object_array_remove_duplicates()`. And what's worse, when adding boundary commits into pending list, we use one-line commit message as names, and the arbitory names may surprise git-bundle. Only comparing objects themselves (".item") is also not good enough, because user may want to create a bundle with two identical objects but with different reference names, such as: "HEAD" and "refs/heads/main". Add new function `contains_object()` which compare both the address and the name of the object. Signed-off-by: Jiang Xin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 9901164 commit ce1d6d9

File tree

2 files changed

+7
-5
lines changed

2 files changed

+7
-5
lines changed

object.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -412,15 +412,16 @@ void object_array_clear(struct object_array *array)
412412
}
413413

414414
/*
415-
* Return true iff array already contains an entry with name.
415+
* Return true if array already contains an entry.
416416
*/
417-
static int contains_name(struct object_array *array, const char *name)
417+
static int contains_object(struct object_array *array,
418+
const struct object *item, const char *name)
418419
{
419420
unsigned nr = array->nr, i;
420421
struct object_array_entry *object = array->objects;
421422

422423
for (i = 0; i < nr; i++, object++)
423-
if (!strcmp(object->name, name))
424+
if (item == object->item && !strcmp(object->name, name))
424425
return 1;
425426
return 0;
426427
}
@@ -432,7 +433,8 @@ void object_array_remove_duplicates(struct object_array *array)
432433

433434
array->nr = 0;
434435
for (src = 0; src < nr; src++) {
435-
if (!contains_name(array, objects[src].name)) {
436+
if (!contains_object(array, objects[src].item,
437+
objects[src].name)) {
436438
if (src != array->nr)
437439
objects[array->nr] = objects[src];
438440
array->nr++;

t/t6020-bundle-misc.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ test_expect_success 'setup' '
167167
test_commit_setvar P "Commit P" main.txt
168168
'
169169

170-
test_expect_failure 'create bundle from special rev: main^!' '
170+
test_expect_success 'create bundle from special rev: main^!' '
171171
git bundle create special-rev.bdl "main^!" &&
172172
173173
git bundle list-heads special-rev.bdl |

0 commit comments

Comments
 (0)