@@ -46,6 +46,7 @@ struct checkout_opts {
4646 int ignore_other_worktrees ;
4747 int show_progress ;
4848 int count_checkout_paths ;
49+ int overlay_mode ;
4950 /*
5051 * If new checkout options are added, skip_merge_working_tree
5152 * should be updated accordingly.
@@ -135,14 +136,17 @@ static int skip_same_name(const struct cache_entry *ce, int pos)
135136 return pos ;
136137}
137138
138- static int check_stage (int stage , const struct cache_entry * ce , int pos )
139+ static int check_stage (int stage , const struct cache_entry * ce , int pos ,
140+ int overlay_mode )
139141{
140142 while (pos < active_nr &&
141143 !strcmp (active_cache [pos ]-> name , ce -> name )) {
142144 if (ce_stage (active_cache [pos ]) == stage )
143145 return 0 ;
144146 pos ++ ;
145147 }
148+ if (!overlay_mode )
149+ return 0 ;
146150 if (stage == 2 )
147151 return error (_ ("path '%s' does not have our version" ), ce -> name );
148152 else
@@ -168,7 +172,8 @@ static int check_stages(unsigned stages, const struct cache_entry *ce, int pos)
168172}
169173
170174static int checkout_stage (int stage , const struct cache_entry * ce , int pos ,
171- const struct checkout * state , int * nr_checkouts )
175+ const struct checkout * state , int * nr_checkouts ,
176+ int overlay_mode )
172177{
173178 while (pos < active_nr &&
174179 !strcmp (active_cache [pos ]-> name , ce -> name )) {
@@ -177,6 +182,10 @@ static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
177182 NULL , nr_checkouts );
178183 pos ++ ;
179184 }
185+ if (!overlay_mode ) {
186+ unlink_entry (ce );
187+ return 0 ;
188+ }
180189 if (stage == 2 )
181190 return error (_ ("path '%s' does not have our version" ), ce -> name );
182191 else
@@ -251,6 +260,59 @@ static int checkout_merged(int pos, const struct checkout *state, int *nr_checko
251260 return status ;
252261}
253262
263+ static void mark_ce_for_checkout_overlay (struct cache_entry * ce ,
264+ char * ps_matched ,
265+ const struct checkout_opts * opts )
266+ {
267+ ce -> ce_flags &= ~CE_MATCHED ;
268+ if (!opts -> ignore_skipworktree && ce_skip_worktree (ce ))
269+ return ;
270+ if (opts -> source_tree && !(ce -> ce_flags & CE_UPDATE ))
271+ /*
272+ * "git checkout tree-ish -- path", but this entry
273+ * is in the original index but is not in tree-ish
274+ * or does not match the pathspec; it will not be
275+ * checked out to the working tree. We will not do
276+ * anything to this entry at all.
277+ */
278+ return ;
279+ /*
280+ * Either this entry came from the tree-ish we are
281+ * checking the paths out of, or we are checking out
282+ * of the index.
283+ *
284+ * If it comes from the tree-ish, we already know it
285+ * matches the pathspec and could just stamp
286+ * CE_MATCHED to it from update_some(). But we still
287+ * need ps_matched and read_tree_recursive (and
288+ * eventually tree_entry_interesting) cannot fill
289+ * ps_matched yet. Once it can, we can avoid calling
290+ * match_pathspec() for _all_ entries when
291+ * opts->source_tree != NULL.
292+ */
293+ if (ce_path_match (& the_index , ce , & opts -> pathspec , ps_matched ))
294+ ce -> ce_flags |= CE_MATCHED ;
295+ }
296+
297+ static void mark_ce_for_checkout_no_overlay (struct cache_entry * ce ,
298+ char * ps_matched ,
299+ const struct checkout_opts * opts )
300+ {
301+ ce -> ce_flags &= ~CE_MATCHED ;
302+ if (!opts -> ignore_skipworktree && ce_skip_worktree (ce ))
303+ return ;
304+ if (ce_path_match (& the_index , ce , & opts -> pathspec , ps_matched )) {
305+ ce -> ce_flags |= CE_MATCHED ;
306+ if (opts -> source_tree && !(ce -> ce_flags & CE_UPDATE ))
307+ /*
308+ * In overlay mode, but the path is not in
309+ * tree-ish, which means we should remove it
310+ * from the index and the working tree.
311+ */
312+ ce -> ce_flags |= CE_REMOVE | CE_WT_REMOVE ;
313+ }
314+ }
315+
254316static int checkout_paths (const struct checkout_opts * opts ,
255317 const char * revision )
256318{
@@ -302,37 +364,15 @@ static int checkout_paths(const struct checkout_opts *opts,
302364 * Make sure all pathspecs participated in locating the paths
303365 * to be checked out.
304366 */
305- for (pos = 0 ; pos < active_nr ; pos ++ ) {
306- struct cache_entry * ce = active_cache [pos ];
307- ce -> ce_flags &= ~CE_MATCHED ;
308- if (!opts -> ignore_skipworktree && ce_skip_worktree (ce ))
309- continue ;
310- if (opts -> source_tree && !(ce -> ce_flags & CE_UPDATE ))
311- /*
312- * "git checkout tree-ish -- path", but this entry
313- * is in the original index; it will not be checked
314- * out to the working tree and it does not matter
315- * if pathspec matched this entry. We will not do
316- * anything to this entry at all.
317- */
318- continue ;
319- /*
320- * Either this entry came from the tree-ish we are
321- * checking the paths out of, or we are checking out
322- * of the index.
323- *
324- * If it comes from the tree-ish, we already know it
325- * matches the pathspec and could just stamp
326- * CE_MATCHED to it from update_some(). But we still
327- * need ps_matched and read_tree_recursive (and
328- * eventually tree_entry_interesting) cannot fill
329- * ps_matched yet. Once it can, we can avoid calling
330- * match_pathspec() for _all_ entries when
331- * opts->source_tree != NULL.
332- */
333- if (ce_path_match (& the_index , ce , & opts -> pathspec , ps_matched ))
334- ce -> ce_flags |= CE_MATCHED ;
335- }
367+ for (pos = 0 ; pos < active_nr ; pos ++ )
368+ if (opts -> overlay_mode )
369+ mark_ce_for_checkout_overlay (active_cache [pos ],
370+ ps_matched ,
371+ opts );
372+ else
373+ mark_ce_for_checkout_no_overlay (active_cache [pos ],
374+ ps_matched ,
375+ opts );
336376
337377 if (report_path_error (ps_matched , & opts -> pathspec , opts -> prefix )) {
338378 free (ps_matched );
@@ -353,7 +393,7 @@ static int checkout_paths(const struct checkout_opts *opts,
353393 if (opts -> force ) {
354394 warning (_ ("path '%s' is unmerged" ), ce -> name );
355395 } else if (opts -> writeout_stage ) {
356- errs |= check_stage (opts -> writeout_stage , ce , pos );
396+ errs |= check_stage (opts -> writeout_stage , ce , pos , opts -> overlay_mode );
357397 } else if (opts -> merge ) {
358398 errs |= check_stages ((1 <<2 ) | (1 <<3 ), ce , pos );
359399 } else {
@@ -383,13 +423,16 @@ static int checkout_paths(const struct checkout_opts *opts,
383423 if (opts -> writeout_stage )
384424 errs |= checkout_stage (opts -> writeout_stage ,
385425 ce , pos ,
386- & state , & nr_checkouts );
426+ & state ,
427+ & nr_checkouts , opts -> overlay_mode );
387428 else if (opts -> merge )
388429 errs |= checkout_merged (pos , & state ,
389430 & nr_unmerged );
390431 pos = skip_same_name (ce , pos ) - 1 ;
391432 }
392433 }
434+ remove_marked_cache_entries (& the_index , 1 );
435+ remove_scheduled_dirs ();
393436 errs |= finish_delayed_checkout (& state , & nr_checkouts );
394437
395438 if (opts -> count_checkout_paths ) {
@@ -571,6 +614,11 @@ static int skip_merge_working_tree(const struct checkout_opts *opts,
571614 * opts->show_progress only impacts output so doesn't require a merge
572615 */
573616
617+ /*
618+ * opts->overlay_mode cannot be used with switching branches so is
619+ * not tested here
620+ */
621+
574622 /*
575623 * If we aren't creating a new branch any changes or updates will
576624 * happen in the existing branch. Since that could only be updating
@@ -1224,6 +1272,10 @@ static int checkout_branch(struct checkout_opts *opts,
12241272 die (_ ("'%s' cannot be used with switching branches" ),
12251273 "--patch" );
12261274
1275+ if (!opts -> overlay_mode )
1276+ die (_ ("'%s' cannot be used with switching branches" ),
1277+ "--no-overlay" );
1278+
12271279 if (opts -> writeout_stage )
12281280 die (_ ("'%s' cannot be used with switching branches" ),
12291281 "--ours/--theirs" );
@@ -1312,6 +1364,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
13121364 "checkout" , "control recursive updating of submodules" ,
13131365 PARSE_OPT_OPTARG , option_parse_recurse_submodules_worktree_updater },
13141366 OPT_BOOL (0 , "progress" , & opts .show_progress , N_ ("force progress reporting" )),
1367+ OPT_BOOL (0 , "overlay" , & opts .overlay_mode , N_ ("use overlay mode (default)" )),
13151368 OPT_END (),
13161369 };
13171370
@@ -1320,6 +1373,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
13201373 opts .overwrite_ignore = 1 ;
13211374 opts .prefix = prefix ;
13221375 opts .show_progress = -1 ;
1376+ opts .overlay_mode = -1 ;
13231377
13241378 git_config (git_checkout_config , & opts );
13251379
@@ -1344,6 +1398,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
13441398 if ((!!opts .new_branch + !!opts .new_branch_force + !!opts .new_orphan_branch ) > 1 )
13451399 die (_ ("-b, -B and --orphan are mutually exclusive" ));
13461400
1401+ if (opts .overlay_mode == 1 && opts .patch_mode )
1402+ die (_ ("-p and --overlay are mutually exclusive" ));
1403+
13471404 /*
13481405 * From here on, new_branch will contain the branch to be checked out,
13491406 * and new_branch_force and new_orphan_branch will tell us which one of
0 commit comments