Skip to content

Commit cd13762

Browse files
newrengitster
authored andcommitted
fast-export: when using paths, avoid corrupt stream with non-existent mark
If file paths are specified to fast-export and multiple refs point to a commit that does not touch any of the relevant file paths, then fast-export can hit problems. fast-export has a list of additional refs that it needs to explicitly set after exporting all blobs and commits, and when it tries to get_object_mark() on the relevant commit, it can get a mark of 0, i.e. "not found", because the commit in question did not touch the relevant paths and thus was not exported. Trying to import a stream with a mark corresponding to an unexported object will cause fast-import to crash. Avoid this problem by taking the commit the ref points to and finding an ancestor of it that was exported, and make the ref point to that commit instead. Signed-off-by: Elijah Newren <[email protected]> Acked-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f129c42 commit cd13762

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

builtin/fast-export.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -901,7 +901,18 @@ static void handle_tags_and_duplicates(void)
901901
if (anonymize)
902902
name = anonymize_refname(name);
903903
/* create refs pointing to already seen commits */
904-
commit = (struct commit *)object;
904+
commit = rewrite_commit((struct commit *)object);
905+
if (!commit) {
906+
/*
907+
* Neither this object nor any of its
908+
* ancestors touch any relevant paths, so
909+
* it has been filtered to nothing. Delete
910+
* it.
911+
*/
912+
printf("reset %s\nfrom %s\n\n",
913+
name, oid_to_hex(&null_oid));
914+
continue;
915+
}
905916
printf("reset %s\nfrom :%d\n\n", name,
906917
get_object_mark(&commit->object));
907918
show_progress();

t/t9350-fast-export.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,26 @@ test_expect_success 'path limiting with import-marks does not lose unmodified fi
382382
grep file0 actual
383383
'
384384

385+
test_expect_success 'avoid corrupt stream with non-existent mark' '
386+
test_create_repo avoid_non_existent_mark &&
387+
(
388+
cd avoid_non_existent_mark &&
389+
390+
test_commit important-path &&
391+
392+
test_commit ignored &&
393+
394+
git branch A &&
395+
git branch B &&
396+
397+
echo foo >>important-path.t &&
398+
git add important-path.t &&
399+
test_commit more changes &&
400+
401+
git fast-export --all -- important-path.t | git fast-import --force
402+
)
403+
'
404+
385405
test_expect_success 'full-tree re-shows unmodified files' '
386406
git checkout -f simple &&
387407
git fast-export --full-tree simple >actual &&

0 commit comments

Comments
 (0)