Skip to content

Commit 9c87c79

Browse files
derrickstoleegitster
authored andcommitted
commit-graph: normalize commit-graph filenames
When writing commit-graph files, we append path data to an object directory, which may be specified by the user via the '--object-dir' option. If the user supplies a trailing slash, or some other alternative path format, the resulting path may be usable for writing to the correct location. However, when expiring graph files from the <obj-dir>/info/commit-graphs directory during a write, we need to compare paths with exact string matches. Normalize the commit-graph filenames to avoid ambiguity. This creates extra allocations, but this is a constant multiple of the number of commit-graph files, which should be a number in the single digits. Further normalize the object directory in the context. Due to a comparison between g->obj_dir and ctx->obj_dir in split_graph_merge_strategy(), a trailing slash would prevent any merging of layers within the same object directory. The check is there to ensure we do not merge across alternates. Update the tests to include a case with this trailing slash problem. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 3cc7951 commit 9c87c79

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

commit-graph.c

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,23 @@
4343

4444
char *get_commit_graph_filename(const char *obj_dir)
4545
{
46-
return xstrfmt("%s/info/commit-graph", obj_dir);
46+
char *filename = xstrfmt("%s/info/commit-graph", obj_dir);
47+
char *normalized = xmalloc(strlen(filename) + 1);
48+
normalize_path_copy(normalized, filename);
49+
free(filename);
50+
return normalized;
4751
}
4852

4953
static char *get_split_graph_filename(const char *obj_dir,
5054
const char *oid_hex)
5155
{
52-
return xstrfmt("%s/info/commit-graphs/graph-%s.graph",
53-
obj_dir,
54-
oid_hex);
56+
char *filename = xstrfmt("%s/info/commit-graphs/graph-%s.graph",
57+
obj_dir,
58+
oid_hex);
59+
char *normalized = xmalloc(strlen(filename) + 1);
60+
normalize_path_copy(normalized, filename);
61+
free(filename);
62+
return normalized;
5563
}
5664

5765
static char *get_chain_filename(const char *obj_dir)
@@ -744,7 +752,7 @@ struct packed_oid_list {
744752

745753
struct write_commit_graph_context {
746754
struct repository *r;
747-
const char *obj_dir;
755+
char *obj_dir;
748756
char *graph_name;
749757
struct packed_oid_list oids;
750758
struct packed_commit_list commits;
@@ -1693,7 +1701,11 @@ static void expire_commit_graphs(struct write_commit_graph_context *ctx)
16931701
}
16941702

16951703
strbuf_addstr(&path, ctx->obj_dir);
1696-
strbuf_addstr(&path, "/info/commit-graphs");
1704+
1705+
if (path.buf[path.len - 1] != '/')
1706+
strbuf_addch(&path, '/');
1707+
1708+
strbuf_addstr(&path, "info/commit-graphs");
16971709
dir = opendir(path.buf);
16981710

16991711
if (!dir) {
@@ -1727,7 +1739,6 @@ static void expire_commit_graphs(struct write_commit_graph_context *ctx)
17271739

17281740
if (!found)
17291741
unlink(path.buf);
1730-
17311742
}
17321743
}
17331744

@@ -1739,14 +1750,22 @@ int write_commit_graph(const char *obj_dir,
17391750
{
17401751
struct write_commit_graph_context *ctx;
17411752
uint32_t i, count_distinct = 0;
1753+
size_t len;
17421754
int res = 0;
17431755

17441756
if (!commit_graph_compatible(the_repository))
17451757
return 0;
17461758

17471759
ctx = xcalloc(1, sizeof(struct write_commit_graph_context));
17481760
ctx->r = the_repository;
1749-
ctx->obj_dir = obj_dir;
1761+
1762+
/* normalize object dir with no trailing slash */
1763+
ctx->obj_dir = xmallocz(strlen(obj_dir) + 1);
1764+
normalize_path_copy(ctx->obj_dir, obj_dir);
1765+
len = strlen(ctx->obj_dir);
1766+
if (len && ctx->obj_dir[len - 1] == '/')
1767+
ctx->obj_dir[len - 1] = 0;
1768+
17501769
ctx->append = flags & COMMIT_GRAPH_APPEND ? 1 : 0;
17511770
ctx->report_progress = flags & COMMIT_GRAPH_PROGRESS ? 1 : 0;
17521771
ctx->split = flags & COMMIT_GRAPH_SPLIT ? 1 : 0;
@@ -1854,6 +1873,7 @@ int write_commit_graph(const char *obj_dir,
18541873
free(ctx->graph_name);
18551874
free(ctx->commits.list);
18561875
free(ctx->oids.list);
1876+
free(ctx->obj_dir);
18571877

18581878
if (ctx->commit_graph_filenames_after) {
18591879
for (i = 0; i < ctx->num_commit_graphs_after; i++) {

0 commit comments

Comments
 (0)