Skip to content

Commit 829c32a

Browse files
committed
sparse-index: partially expand directories
The expand_to_pattern_list() method expands sparse directory entries to their list of contained files when either the pattern list is NULL or the directory is contained in the new pattern list's cone mode patterns. It is possible that the pattern list has a recursive match with a directory 'A/B/C/' and so an existing sparse directory 'A/B/' would need to be expanded. If there exists a directory 'A/B/D/', then that directory should not be expanded and instead we can create a sparse directory. To implement this, we plug into the add_path_to_index() callback for the call to read_tree_at(). Since we now need access to both the index we are writing and the pattern list we are comparing, create a 'struct modify_index_context' to use as a data transfer object. It is important that we use the given pattern list since we will use this pattern list to change the sparse-checkout patterns and cannot use istate->sparse_checkout_patterns. Signed-off-by: Derrick Stolee <[email protected]>
1 parent 57dc87a commit 829c32a

File tree

1 file changed

+36
-7
lines changed

1 file changed

+36
-7
lines changed

sparse-index.c

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
#include "dir.h"
1010
#include "fsmonitor.h"
1111

12+
struct modify_index_context {
13+
struct index_state *write;
14+
struct pattern_list *pl;
15+
};
16+
1217
static struct cache_entry *construct_sparse_dir_entry(
1318
struct index_state *istate,
1419
const char *sparse_dir,
@@ -222,18 +227,38 @@ static int add_path_to_index(const struct object_id *oid,
222227
struct strbuf *base, const char *path,
223228
unsigned int mode, void *context)
224229
{
225-
struct index_state *istate = (struct index_state *)context;
230+
struct modify_index_context *ctx = (struct modify_index_context *)context;
226231
struct cache_entry *ce;
227232
size_t len = base->len;
228233

229-
if (S_ISDIR(mode))
230-
return READ_TREE_RECURSIVE;
234+
if (S_ISDIR(mode)) {
235+
size_t baselen = base->len;
236+
if (!ctx->pl)
237+
return READ_TREE_RECURSIVE;
238+
239+
/*
240+
* Have we expanded to a point outside of the sparse-checkout?
241+
*/
242+
strbuf_addstr(base, path);
243+
strbuf_add(base, "/-", 2);
244+
245+
if (path_matches_cone_mode_pattern_list(base->buf, base->len, ctx->pl)) {
246+
strbuf_setlen(base, baselen);
247+
return READ_TREE_RECURSIVE;
248+
}
231249

232-
strbuf_addstr(base, path);
250+
/*
251+
* The path "{base}{path}/" is a sparse directory. Create the correct
252+
* name for inserting the entry into the idnex.
253+
*/
254+
strbuf_setlen(base, base->len - 1);
255+
} else {
256+
strbuf_addstr(base, path);
257+
}
233258

234-
ce = make_cache_entry(istate, mode, oid, base->buf, 0, 0);
259+
ce = make_cache_entry(ctx->write, mode, oid, base->buf, 0, 0);
235260
ce->ce_flags |= CE_SKIP_WORKTREE | CE_EXTENDED;
236-
set_index_entry(istate, istate->cache_nr++, ce);
261+
set_index_entry(ctx->write, ctx->write->cache_nr++, ce);
237262

238263
strbuf_setlen(base, len);
239264
return 0;
@@ -245,6 +270,7 @@ void expand_to_pattern_list(struct index_state *istate,
245270
int i;
246271
struct index_state *full;
247272
struct strbuf base = STRBUF_INIT;
273+
struct modify_index_context ctx;
248274

249275
/*
250276
* If the index is already full, then keep it full. We will convert
@@ -285,6 +311,9 @@ void expand_to_pattern_list(struct index_state *istate,
285311
full->cache_nr = 0;
286312
ALLOC_ARRAY(full->cache, full->cache_alloc);
287313

314+
ctx.write = full;
315+
ctx.pl = pl;
316+
288317
for (i = 0; i < istate->cache_nr; i++) {
289318
struct cache_entry *ce = istate->cache[i];
290319
struct tree *tree;
@@ -310,7 +339,7 @@ void expand_to_pattern_list(struct index_state *istate,
310339
strbuf_add(&base, ce->name, strlen(ce->name));
311340

312341
read_tree_at(istate->repo, tree, &base, &ps,
313-
add_path_to_index, full);
342+
add_path_to_index, &ctx);
314343

315344
/* free directory entries. full entries are re-used */
316345
discard_cache_entry(ce);

0 commit comments

Comments
 (0)