Skip to content

Commit 9dc607f

Browse files
peffgitster
authored andcommitted
fast-import: fix file access when run from subdir
In cmd_fast_import(), we ignore the "prefix" argument entirely, even though it tells us how we may have changed directory to the root of the repository earlier in the process. Which means that if you run it from a subdir and point to paths in the filesystem, like: cd subdir git fast-import --import-marks=foo <dump then it will look for "foo" in the root of the repository, not the current directory ("subdir/") which the user would have expected. We can fix this by recording the prefix and using it as appropriate whenever we open a file for reading or writing. I found each of these by looking for cases where we call fopen() within fast-import.c, so this should cover all cases. The new test triggers each one, as well as making sure we don't accidentally apply the prefix when --relative-marks is in use (since that option interprets some paths as relative to a specific directory). Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 8d90352 commit 9dc607f

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

builtin/fast-import.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ static FILE *pack_edges;
176176
static unsigned int show_stats = 1;
177177
static int global_argc;
178178
static const char **global_argv;
179+
static const char *global_prefix;
179180

180181
/* Memory pools */
181182
static struct mem_pool fi_mem_pool = {
@@ -3246,7 +3247,7 @@ static void parse_alias(void)
32463247
static char* make_fast_import_path(const char *path)
32473248
{
32483249
if (!relative_marks_paths || is_absolute_path(path))
3249-
return xstrdup(path);
3250+
return prefix_filename(global_prefix, path);
32503251
return git_pathdup("info/fast-import/%s", path);
32513252
}
32523253

@@ -3317,9 +3318,11 @@ static void option_cat_blob_fd(const char *fd)
33173318

33183319
static void option_export_pack_edges(const char *edges)
33193320
{
3321+
char *fn = prefix_filename(global_prefix, edges);
33203322
if (pack_edges)
33213323
fclose(pack_edges);
3322-
pack_edges = xfopen(edges, "a");
3324+
pack_edges = xfopen(fn, "a");
3325+
free(fn);
33233326
}
33243327

33253328
static void option_rewrite_submodules(const char *arg, struct string_list *list)
@@ -3334,11 +3337,13 @@ static void option_rewrite_submodules(const char *arg, struct string_list *list)
33343337
f++;
33353338
CALLOC_ARRAY(ms, 1);
33363339

3340+
f = prefix_filename(global_prefix, f);
33373341
fp = fopen(f, "r");
33383342
if (!fp)
33393343
die_errno("cannot read '%s'", f);
33403344
read_mark_file(&ms, fp, insert_oid_entry);
33413345
fclose(fp);
3346+
free(f);
33423347

33433348
string_list_insert(list, s)->util = ms;
33443349
}
@@ -3552,6 +3557,7 @@ int cmd_fast_import(int argc, const char **argv, const char *prefix)
35523557

35533558
global_argc = argc;
35543559
global_argv = argv;
3560+
global_prefix = prefix;
35553561

35563562
rc_free = mem_pool_alloc(&fi_mem_pool, cmd_save * sizeof(*rc_free));
35573563
for (i = 0; i < (cmd_save - 1); i++)

t/t9304-fast-import-marks.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,33 @@ test_expect_success 'import with submodule mapping' '
4949
test_cmp expect actual
5050
'
5151

52+
test_expect_success 'paths adjusted for relative subdir' '
53+
git init deep-dst &&
54+
mkdir deep-dst/subdir &&
55+
>deep-dst/subdir/empty-marks &&
56+
git -C deep-dst/subdir fast-import \
57+
--rewrite-submodules-from=sub:../../from \
58+
--rewrite-submodules-to=sub:../../to \
59+
--import-marks=empty-marks \
60+
--export-marks=exported-marks \
61+
--export-pack-edges=exported-edges \
62+
<dump &&
63+
# we do not bother checking resulting repo; we just care that nothing
64+
# complained about failing to open files for reading, and that files
65+
# for writing were created in the expected spot
66+
test_path_is_file deep-dst/subdir/exported-marks &&
67+
test_path_is_file deep-dst/subdir/exported-edges
68+
'
69+
70+
test_expect_success 'relative marks are not affected by subdir' '
71+
git init deep-relative &&
72+
mkdir deep-relative/subdir &&
73+
git -C deep-relative/subdir fast-import \
74+
--relative-marks \
75+
--export-marks=exported-marks \
76+
<dump &&
77+
test_path_is_missing deep-relative/subdir/exported-marks &&
78+
test_path_is_file deep-relative/.git/info/fast-import/exported-marks
79+
'
80+
5281
test_done

0 commit comments

Comments
 (0)