@@ -32,6 +32,12 @@ static struct unpack_trees_error_msgs unpack_plumbing_errors = {
3232
3333 /* bind_overlap */
3434 "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." ,
3541};
3642
3743#define ERRORMSG (o ,fld ) \
@@ -125,6 +131,57 @@ static int check_updates(struct unpack_trees_options *o)
125131 return errs != 0 ;
126132}
127133
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+
128185static inline int call_unpack_fn (struct cache_entry * * src , struct unpack_trees_options * o )
129186{
130187 int ret = o -> fn (src , o );
@@ -376,7 +433,7 @@ static int unpack_failed(struct unpack_trees_options *o, const char *message)
376433 */
377434int unpack_trees (unsigned len , struct tree_desc * t , struct unpack_trees_options * o )
378435{
379- int ret ;
436+ int i , ret ;
380437 static struct cache_entry * dfc ;
381438 struct exclude_list el ;
382439
@@ -440,6 +497,17 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
440497 goto done ;
441498 }
442499
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+
443511 o -> src_index = NULL ;
444512 ret = check_updates (o ) ? (-2 ) : 0 ;
445513 if (o -> dst_index )
@@ -512,6 +580,12 @@ static int verify_uptodate(struct cache_entry *ce,
512580 return verify_uptodate_1 (ce , o , ERRORMSG (o , not_uptodate_file ));
513581}
514582
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+
515589static void invalidate_ce_path (struct cache_entry * ce , struct unpack_trees_options * o )
516590{
517591 if (ce )
@@ -705,6 +779,12 @@ static int verify_absent(struct cache_entry *ce, const char *action,
705779 return verify_absent_1 (ce , action , o , ERRORMSG (o , would_lose_untracked ));
706780}
707781
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+
708788static int merged_entry (struct cache_entry * merge , struct cache_entry * old ,
709789 struct unpack_trees_options * o )
710790{
0 commit comments