@@ -32,6 +32,12 @@ static struct unpack_trees_error_msgs unpack_plumbing_errors = {
32
32
33
33
/* bind_overlap */
34
34
"Entry '%s' overlaps with '%s'. Cannot bind." ,
35
+
36
+ /* sparse_not_uptodate_file */
37
+ "Entry '%s' not uptodate. Cannot update sparse checkout." ,
38
+
39
+ /* would_lose_orphaned */
40
+ "Working tree file '%s' would be %s by sparse checkout update." ,
35
41
};
36
42
37
43
#define ERRORMSG (o ,fld ) \
@@ -125,6 +131,57 @@ static int check_updates(struct unpack_trees_options *o)
125
131
return errs != 0 ;
126
132
}
127
133
134
+ static int verify_uptodate_sparse (struct cache_entry * ce , struct unpack_trees_options * o );
135
+ static int verify_absent_sparse (struct cache_entry * ce , const char * action , struct unpack_trees_options * o );
136
+
137
+ static int will_have_skip_worktree (const struct cache_entry * ce , struct unpack_trees_options * o )
138
+ {
139
+ const char * basename ;
140
+
141
+ if (ce_stage (ce ))
142
+ return 0 ;
143
+
144
+ basename = strrchr (ce -> name , '/' );
145
+ basename = basename ? basename + 1 : ce -> name ;
146
+ return excluded_from_list (ce -> name , ce_namelen (ce ), basename , NULL , o -> el ) <= 0 ;
147
+ }
148
+
149
+ static int apply_sparse_checkout (struct cache_entry * ce , struct unpack_trees_options * o )
150
+ {
151
+ int was_skip_worktree = ce_skip_worktree (ce );
152
+
153
+ if (will_have_skip_worktree (ce , o ))
154
+ ce -> ce_flags |= CE_SKIP_WORKTREE ;
155
+ else
156
+ ce -> ce_flags &= ~CE_SKIP_WORKTREE ;
157
+
158
+ /*
159
+ * We only care about files getting into the checkout area
160
+ * If merge strategies want to remove some, go ahead, this
161
+ * flag will be removed eventually in unpack_trees() if it's
162
+ * outside checkout area.
163
+ */
164
+ if (ce -> ce_flags & CE_REMOVE )
165
+ return 0 ;
166
+
167
+ if (!was_skip_worktree && ce_skip_worktree (ce )) {
168
+ /*
169
+ * If CE_UPDATE is set, verify_uptodate() must be called already
170
+ * also stat info may have lost after merged_entry() so calling
171
+ * verify_uptodate() again may fail
172
+ */
173
+ if (!(ce -> ce_flags & CE_UPDATE ) && verify_uptodate_sparse (ce , o ))
174
+ return -1 ;
175
+ ce -> ce_flags |= CE_WT_REMOVE ;
176
+ }
177
+ if (was_skip_worktree && !ce_skip_worktree (ce )) {
178
+ if (verify_absent_sparse (ce , "overwritten" , o ))
179
+ return -1 ;
180
+ ce -> ce_flags |= CE_UPDATE ;
181
+ }
182
+ return 0 ;
183
+ }
184
+
128
185
static inline int call_unpack_fn (struct cache_entry * * src , struct unpack_trees_options * o )
129
186
{
130
187
int ret = o -> fn (src , o );
@@ -376,7 +433,7 @@ static int unpack_failed(struct unpack_trees_options *o, const char *message)
376
433
*/
377
434
int unpack_trees (unsigned len , struct tree_desc * t , struct unpack_trees_options * o )
378
435
{
379
- int ret ;
436
+ int i , ret ;
380
437
static struct cache_entry * dfc ;
381
438
struct exclude_list el ;
382
439
@@ -440,6 +497,17 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
440
497
goto done ;
441
498
}
442
499
500
+ if (!o -> skip_sparse_checkout ) {
501
+ for (i = 0 ;i < o -> result .cache_nr ;i ++ ) {
502
+ struct cache_entry * ce = o -> result .cache [i ];
503
+
504
+ if (apply_sparse_checkout (ce , o )) {
505
+ ret = -1 ;
506
+ goto done ;
507
+ }
508
+ }
509
+ }
510
+
443
511
o -> src_index = NULL ;
444
512
ret = check_updates (o ) ? (-2 ) : 0 ;
445
513
if (o -> dst_index )
@@ -512,6 +580,12 @@ static int verify_uptodate(struct cache_entry *ce,
512
580
return verify_uptodate_1 (ce , o , ERRORMSG (o , not_uptodate_file ));
513
581
}
514
582
583
+ static int verify_uptodate_sparse (struct cache_entry * ce ,
584
+ struct unpack_trees_options * o )
585
+ {
586
+ return verify_uptodate_1 (ce , o , ERRORMSG (o , sparse_not_uptodate_file ));
587
+ }
588
+
515
589
static void invalidate_ce_path (struct cache_entry * ce , struct unpack_trees_options * o )
516
590
{
517
591
if (ce )
@@ -705,6 +779,12 @@ static int verify_absent(struct cache_entry *ce, const char *action,
705
779
return verify_absent_1 (ce , action , o , ERRORMSG (o , would_lose_untracked ));
706
780
}
707
781
782
+ static int verify_absent_sparse (struct cache_entry * ce , const char * action ,
783
+ struct unpack_trees_options * o )
784
+ {
785
+ return verify_absent_1 (ce , action , o , ERRORMSG (o , would_lose_orphaned ));
786
+ }
787
+
708
788
static int merged_entry (struct cache_entry * merge , struct cache_entry * old ,
709
789
struct unpack_trees_options * o )
710
790
{
0 commit comments