@@ -46,6 +46,7 @@ struct checkout_opts {
46
46
int ignore_other_worktrees ;
47
47
int show_progress ;
48
48
int count_checkout_paths ;
49
+ int overlay_mode ;
49
50
/*
50
51
* If new checkout options are added, skip_merge_working_tree
51
52
* should be updated accordingly.
@@ -135,14 +136,17 @@ static int skip_same_name(const struct cache_entry *ce, int pos)
135
136
return pos ;
136
137
}
137
138
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 )
139
141
{
140
142
while (pos < active_nr &&
141
143
!strcmp (active_cache [pos ]-> name , ce -> name )) {
142
144
if (ce_stage (active_cache [pos ]) == stage )
143
145
return 0 ;
144
146
pos ++ ;
145
147
}
148
+ if (!overlay_mode )
149
+ return 0 ;
146
150
if (stage == 2 )
147
151
return error (_ ("path '%s' does not have our version" ), ce -> name );
148
152
else
@@ -168,7 +172,8 @@ static int check_stages(unsigned stages, const struct cache_entry *ce, int pos)
168
172
}
169
173
170
174
static 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 )
172
177
{
173
178
while (pos < active_nr &&
174
179
!strcmp (active_cache [pos ]-> name , ce -> name )) {
@@ -177,6 +182,10 @@ static int checkout_stage(int stage, const struct cache_entry *ce, int pos,
177
182
NULL , nr_checkouts );
178
183
pos ++ ;
179
184
}
185
+ if (!overlay_mode ) {
186
+ unlink_entry (ce );
187
+ return 0 ;
188
+ }
180
189
if (stage == 2 )
181
190
return error (_ ("path '%s' does not have our version" ), ce -> name );
182
191
else
@@ -251,6 +260,59 @@ static int checkout_merged(int pos, const struct checkout *state, int *nr_checko
251
260
return status ;
252
261
}
253
262
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
+
254
316
static int checkout_paths (const struct checkout_opts * opts ,
255
317
const char * revision )
256
318
{
@@ -302,37 +364,15 @@ static int checkout_paths(const struct checkout_opts *opts,
302
364
* Make sure all pathspecs participated in locating the paths
303
365
* to be checked out.
304
366
*/
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 );
336
376
337
377
if (report_path_error (ps_matched , & opts -> pathspec , opts -> prefix )) {
338
378
free (ps_matched );
@@ -353,7 +393,7 @@ static int checkout_paths(const struct checkout_opts *opts,
353
393
if (opts -> force ) {
354
394
warning (_ ("path '%s' is unmerged" ), ce -> name );
355
395
} 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 );
357
397
} else if (opts -> merge ) {
358
398
errs |= check_stages ((1 <<2 ) | (1 <<3 ), ce , pos );
359
399
} else {
@@ -383,13 +423,16 @@ static int checkout_paths(const struct checkout_opts *opts,
383
423
if (opts -> writeout_stage )
384
424
errs |= checkout_stage (opts -> writeout_stage ,
385
425
ce , pos ,
386
- & state , & nr_checkouts );
426
+ & state ,
427
+ & nr_checkouts , opts -> overlay_mode );
387
428
else if (opts -> merge )
388
429
errs |= checkout_merged (pos , & state ,
389
430
& nr_unmerged );
390
431
pos = skip_same_name (ce , pos ) - 1 ;
391
432
}
392
433
}
434
+ remove_marked_cache_entries (& the_index , 1 );
435
+ remove_scheduled_dirs ();
393
436
errs |= finish_delayed_checkout (& state , & nr_checkouts );
394
437
395
438
if (opts -> count_checkout_paths ) {
@@ -571,6 +614,11 @@ static int skip_merge_working_tree(const struct checkout_opts *opts,
571
614
* opts->show_progress only impacts output so doesn't require a merge
572
615
*/
573
616
617
+ /*
618
+ * opts->overlay_mode cannot be used with switching branches so is
619
+ * not tested here
620
+ */
621
+
574
622
/*
575
623
* If we aren't creating a new branch any changes or updates will
576
624
* happen in the existing branch. Since that could only be updating
@@ -1224,6 +1272,10 @@ static int checkout_branch(struct checkout_opts *opts,
1224
1272
die (_ ("'%s' cannot be used with switching branches" ),
1225
1273
"--patch" );
1226
1274
1275
+ if (!opts -> overlay_mode )
1276
+ die (_ ("'%s' cannot be used with switching branches" ),
1277
+ "--no-overlay" );
1278
+
1227
1279
if (opts -> writeout_stage )
1228
1280
die (_ ("'%s' cannot be used with switching branches" ),
1229
1281
"--ours/--theirs" );
@@ -1312,6 +1364,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
1312
1364
"checkout" , "control recursive updating of submodules" ,
1313
1365
PARSE_OPT_OPTARG , option_parse_recurse_submodules_worktree_updater },
1314
1366
OPT_BOOL (0 , "progress" , & opts .show_progress , N_ ("force progress reporting" )),
1367
+ OPT_BOOL (0 , "overlay" , & opts .overlay_mode , N_ ("use overlay mode (default)" )),
1315
1368
OPT_END (),
1316
1369
};
1317
1370
@@ -1320,6 +1373,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
1320
1373
opts .overwrite_ignore = 1 ;
1321
1374
opts .prefix = prefix ;
1322
1375
opts .show_progress = -1 ;
1376
+ opts .overlay_mode = -1 ;
1323
1377
1324
1378
git_config (git_checkout_config , & opts );
1325
1379
@@ -1344,6 +1398,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
1344
1398
if ((!!opts .new_branch + !!opts .new_branch_force + !!opts .new_orphan_branch ) > 1 )
1345
1399
die (_ ("-b, -B and --orphan are mutually exclusive" ));
1346
1400
1401
+ if (opts .overlay_mode == 1 && opts .patch_mode )
1402
+ die (_ ("-p and --overlay are mutually exclusive" ));
1403
+
1347
1404
/*
1348
1405
* From here on, new_branch will contain the branch to be checked out,
1349
1406
* and new_branch_force and new_orphan_branch will tell us which one of
0 commit comments