Skip to content

Commit d3def43

Browse files
committed
Merge branch 'sparse-index-stuff'
This is random stuff that probably all got upstream in the meantime.
2 parents 2aa3e49 + 581d05b commit d3def43

14 files changed

+199
-17
lines changed

Documentation/config/index.adoc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
index.deleteSparseDirectories::
2+
When enabled, the cone mode sparse-checkout feature will delete
3+
directories that are outside of the sparse-checkout cone, unless
4+
such a directory contains an untracked, non-ignored file. Defaults
5+
to true.
6+
17
index.recordEndOfIndexEntries::
28
Specifies whether the index file should include an "End Of Index
39
Entry" section. This reduces index load time on multiprocessor

builtin/add.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
#define USE_THE_REPOSITORY_VARIABLE
2+
13
/*
24
* "git add" builtin command
35
*
46
* Copyright (C) 2006 Linus Torvalds
57
*/
68

79
#include "builtin.h"
10+
#include "environment.h"
811
#include "advice.h"
912
#include "config.h"
1013
#include "lockfile.h"
@@ -47,6 +50,7 @@ static int chmod_pathspec(struct repository *repo,
4750
int err;
4851

4952
if (!include_sparse &&
53+
!core_virtualfilesystem &&
5054
(ce_skip_worktree(ce) ||
5155
!path_in_sparse_checkout(ce->name, repo->index)))
5256
continue;
@@ -132,8 +136,9 @@ static int refresh(struct repository *repo, int verbose, const struct pathspec *
132136
if (!seen[i]) {
133137
const char *path = pathspec->items[i].original;
134138

135-
if (matches_skip_worktree(pathspec, i, &skip_worktree_seen) ||
136-
!path_in_sparse_checkout(path, repo->index)) {
139+
if (!core_virtualfilesystem &&
140+
(matches_skip_worktree(pathspec, i, &skip_worktree_seen) ||
141+
!path_in_sparse_checkout(path, repo->index))) {
137142
string_list_append(&only_match_skip_worktree,
138143
pathspec->items[i].original);
139144
} else {
@@ -143,7 +148,11 @@ static int refresh(struct repository *repo, int verbose, const struct pathspec *
143148
}
144149
}
145150

146-
if (only_match_skip_worktree.nr) {
151+
/*
152+
* When using a virtual filesystem, we might re-add a path
153+
* that is currently virtual and we want that to succeed.
154+
*/
155+
if (!core_virtualfilesystem && only_match_skip_worktree.nr) {
147156
advise_on_updating_sparse_paths(&only_match_skip_worktree);
148157
ret = 1;
149158
}
@@ -529,7 +538,11 @@ int cmd_add(int argc,
529538
if (seen[i])
530539
continue;
531540

532-
if (!include_sparse &&
541+
/*
542+
* When using a virtual filesystem, we might re-add a path
543+
* that is currently virtual and we want that to succeed.
544+
*/
545+
if (!include_sparse && !core_virtualfilesystem &&
533546
matches_skip_worktree(&pathspec, i, &skip_worktree_seen)) {
534547
string_list_append(&only_match_skip_worktree,
535548
pathspec.items[i].original);
@@ -553,7 +566,6 @@ int cmd_add(int argc,
553566
}
554567
}
555568

556-
557569
if (only_match_skip_worktree.nr) {
558570
advise_on_updating_sparse_paths(&only_match_skip_worktree);
559571
exit_status = 1;

builtin/reset.c

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
#include "add-interactive.h"
4141
#include "strbuf.h"
4242
#include "quote.h"
43+
#include "dir.h"
44+
#include "entry.h"
4345

4446
#define REFRESH_INDEX_DELAY_WARNING_IN_MS (2 * 1000)
4547

@@ -160,9 +162,48 @@ static void update_index_from_diff(struct diff_queue_struct *q,
160162

161163
for (i = 0; i < q->nr; i++) {
162164
int pos;
165+
int respect_skip_worktree = 1;
163166
struct diff_filespec *one = q->queue[i]->one;
167+
struct diff_filespec *two = q->queue[i]->two;
164168
int is_in_reset_tree = one->mode && !is_null_oid(&one->oid);
169+
int is_missing = !(one->mode && !is_null_oid(&one->oid));
170+
int was_missing = !two->mode && is_null_oid(&two->oid);
165171
struct cache_entry *ce;
172+
struct cache_entry *ceBefore;
173+
struct checkout state = CHECKOUT_INIT;
174+
175+
/*
176+
* When using the virtual filesystem feature, the cache entries that are
177+
* added here will not have the skip-worktree bit set.
178+
*
179+
* Without this code there is data that is lost because the files that
180+
* would normally be in the working directory are not there and show as
181+
* deleted for the next status or in the case of added files just disappear.
182+
* We need to create the previous version of the files in the working
183+
* directory so that they will have the right content and the next
184+
* status call will show modified or untracked files correctly.
185+
*/
186+
if (core_virtualfilesystem && !file_exists(two->path))
187+
{
188+
respect_skip_worktree = 0;
189+
pos = index_name_pos(the_repository->index, two->path, strlen(two->path));
190+
191+
if ((pos >= 0 && ce_skip_worktree(the_repository->index->cache[pos])) &&
192+
(is_missing || !was_missing))
193+
{
194+
state.force = 1;
195+
state.refresh_cache = 1;
196+
state.istate = the_repository->index;
197+
ceBefore = make_cache_entry(the_repository->index, two->mode,
198+
&two->oid, two->path,
199+
0, 0);
200+
if (!ceBefore)
201+
die(_("make_cache_entry failed for path '%s'"),
202+
two->path);
203+
204+
checkout_entry(ceBefore, &state, NULL, NULL);
205+
}
206+
}
166207

167208
if (!is_in_reset_tree && !intent_to_add) {
168209
remove_file_from_index(the_repository->index, one->path);
@@ -181,8 +222,14 @@ static void update_index_from_diff(struct diff_queue_struct *q,
181222
* to properly construct the reset sparse directory.
182223
*/
183224
pos = index_name_pos(the_repository->index, one->path, strlen(one->path));
184-
if ((pos >= 0 && ce_skip_worktree(the_repository->index->cache[pos])) ||
185-
(pos < 0 && !path_in_sparse_checkout(one->path, the_repository->index)))
225+
226+
/*
227+
* Do not add the SKIP_WORKTREE bit back if we populated the
228+
* file on purpose in a virtual filesystem scenario.
229+
*/
230+
if (respect_skip_worktree &&
231+
((pos >= 0 && ce_skip_worktree(the_repository->index->cache[pos])) ||
232+
(pos < 0 && !path_in_sparse_checkout(one->path, the_repository->index))))
186233
ce->ce_flags |= CE_SKIP_WORKTREE;
187234

188235
if (!ce)

builtin/rm.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define USE_THE_REPOSITORY_VARIABLE
88

99
#include "builtin.h"
10+
#include "environment.h"
1011
#include "advice.h"
1112
#include "config.h"
1213
#include "lockfile.h"
@@ -314,7 +315,7 @@ int cmd_rm(int argc,
314315
for (unsigned int i = 0; i < the_repository->index->cache_nr; i++) {
315316
const struct cache_entry *ce = the_repository->index->cache[i];
316317

317-
if (!include_sparse &&
318+
if (!include_sparse && !core_virtualfilesystem &&
318319
(ce_skip_worktree(ce) ||
319320
!path_in_sparse_checkout(ce->name, the_repository->index)))
320321
continue;
@@ -351,7 +352,11 @@ int cmd_rm(int argc,
351352
*original ? original : ".");
352353
}
353354

354-
if (only_match_skip_worktree.nr) {
355+
/*
356+
* When using a virtual filesystem, we might re-add a path
357+
* that is currently virtual and we want that to succeed.
358+
*/
359+
if (!core_virtualfilesystem && only_match_skip_worktree.nr) {
355360
advise_on_updating_sparse_paths(&only_match_skip_worktree);
356361
ret = 1;
357362
}

builtin/sparse-checkout.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static int sparse_checkout_list(int argc, const char **argv, const char *prefix,
112112

113113
static void clean_tracked_sparse_directories(struct repository *r)
114114
{
115-
int i, was_full = 0;
115+
int i, value, was_full = 0;
116116
struct strbuf path = STRBUF_INIT;
117117
size_t pathlen;
118118
struct string_list_item *item;
@@ -128,6 +128,13 @@ static void clean_tracked_sparse_directories(struct repository *r)
128128
!r->index->sparse_checkout_patterns->use_cone_patterns)
129129
return;
130130

131+
/*
132+
* Users can disable this behavior.
133+
*/
134+
if (!repo_config_get_bool(r, "index.deletesparsedirectories", &value) &&
135+
!value)
136+
return;
137+
131138
/*
132139
* Use the sparse index as a data structure to assist finding
133140
* directories that are safe to delete. This conversion to a

diff.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4046,6 +4046,13 @@ static int reuse_worktree_file(struct index_state *istate,
40464046
has_object_pack(istate->repo, oid))
40474047
return 0;
40484048

4049+
/*
4050+
* If this path does not match our sparse-checkout definition,
4051+
* then the file will not be in the working directory.
4052+
*/
4053+
if (!path_in_sparse_checkout(name, istate))
4054+
return 0;
4055+
40494056
/*
40504057
* Similarly, if we'd have to convert the file contents anyway, that
40514058
* makes the optimization not worthwhile.

dir.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,6 +1588,13 @@ static int path_in_sparse_checkout_1(const char *path,
15881588
enum pattern_match_result match = UNDECIDED;
15891589
const char *end, *slash;
15901590

1591+
/*
1592+
* When using a virtual filesystem, there aren't really patterns
1593+
* to follow, but be extra careful to skip this check.
1594+
*/
1595+
if (core_virtualfilesystem)
1596+
return 1;
1597+
15911598
/*
15921599
* We default to accepting a path if the path is empty, there are no
15931600
* patterns, or the patterns are of the wrong type.

read-cache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3953,7 +3953,7 @@ static void update_callback(struct diff_queue_struct *q,
39533953
struct diff_filepair *p = q->queue[i];
39543954
const char *path = p->one->path;
39553955

3956-
if (!data->include_sparse &&
3956+
if (!data->include_sparse && !core_virtualfilesystem &&
39573957
!path_in_sparse_checkout(path, data->index))
39583958
continue;
39593959

repo-settings.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ void prepare_repo_settings(struct repository *r)
7878
repo_cfg_bool(r, "pack.usesparse", &r->settings.pack_use_sparse, 1);
7979
repo_cfg_bool(r, "pack.usepathwalk", &r->settings.pack_use_path_walk, 0);
8080
repo_cfg_bool(r, "core.multipackindex", &r->settings.core_multi_pack_index, 1);
81-
repo_cfg_bool(r, "index.sparse", &r->settings.sparse_index, 0);
81+
repo_cfg_bool(r, "index.sparse", &r->settings.sparse_index, 1);
8282
repo_cfg_bool(r, "index.skiphash", &r->settings.index_skip_hash, r->settings.index_skip_hash);
8383
repo_cfg_bool(r, "pack.readreverseindex", &r->settings.pack_read_reverse_index, 1);
8484
repo_cfg_bool(r, "pack.usebitmapboundarytraversal",

sequencer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ static int do_recursive_merge(struct repository *r,
765765
o.branch2 = next ? next_label : "(empty tree)";
766766
if (is_rebase_i(opts))
767767
o.buffer_output = 2;
768-
o.show_rename_progress = 1;
768+
o.show_rename_progress = isatty(2);
769769

770770
head_tree = parse_tree_indirect(head);
771771
if (!head_tree)

0 commit comments

Comments
 (0)