@@ -39,6 +39,10 @@ struct checkout_opts {
39
39
int ignore_skipworktree ;
40
40
int ignore_other_worktrees ;
41
41
int show_progress ;
42
+ /*
43
+ * If new checkout options are added, needs_working_tree_merge
44
+ * should be updated accordingly.
45
+ */
42
46
43
47
const char * new_branch ;
44
48
const char * new_branch_force ;
@@ -461,130 +465,222 @@ static void setup_branch_path(struct branch_info *branch)
461
465
branch -> path = strbuf_detach (& buf , NULL );
462
466
}
463
467
464
- static int merge_working_tree (const struct checkout_opts * opts ,
465
- struct branch_info * old ,
466
- struct branch_info * new ,
467
- int * writeout_error )
468
+ static int needs_working_tree_merge (const struct checkout_opts * opts ,
469
+ const struct branch_info * old ,
470
+ const struct branch_info * new )
468
471
{
469
- int ret ;
470
- struct lock_file * lock_file = xcalloc (1 , sizeof (struct lock_file ));
472
+ /*
473
+ * We must do the merge if we are actually moving to a new
474
+ * commit tree.
475
+ */
476
+ if (!old -> commit || !new -> commit ||
477
+ oidcmp (& old -> commit -> tree -> object .oid , & new -> commit -> tree -> object .oid ))
478
+ return 1 ;
471
479
472
- hold_locked_index (lock_file , 1 );
473
- if (read_cache_preload (NULL ) < 0 )
474
- return error (_ ("corrupt index file" ));
480
+ /*
481
+ * opts->patch_mode cannot be used with switching branches so is
482
+ * not tested here
483
+ */
475
484
476
- resolve_undo_clear ();
477
- if (opts -> force ) {
478
- ret = reset_tree (new -> commit -> tree , opts , 1 , writeout_error );
479
- if (ret )
480
- return ret ;
481
- } else {
482
- struct tree_desc trees [2 ];
483
- struct tree * tree ;
484
- struct unpack_trees_options topts ;
485
+ /*
486
+ * opts->quiet only impacts output so doesn't require a merge
487
+ */
485
488
486
- memset (& topts , 0 , sizeof (topts ));
487
- topts .head_idx = -1 ;
488
- topts .src_index = & the_index ;
489
- topts .dst_index = & the_index ;
489
+ /*
490
+ * Honor the explicit request for a three-way merge or to throw away
491
+ * local changes
492
+ */
493
+ if (opts -> merge || opts -> force )
494
+ return 1 ;
490
495
491
- setup_unpack_trees_porcelain (& topts , "checkout" );
496
+ /*
497
+ * --detach is documented as "updating the index and the files in the
498
+ * working tree" but this optimization skips those steps so fall through
499
+ * to the regular code path.
500
+ */
501
+ if (opts -> force_detach )
502
+ return 1 ;
492
503
493
- refresh_cache (REFRESH_QUIET );
504
+ /*
505
+ * opts->writeout_stage cannot be used with switching branches so is
506
+ * not tested here
507
+ */
494
508
495
- if (unmerged_cache ()) {
496
- error (_ ("you need to resolve your current index first" ));
497
- return 1 ;
498
- }
509
+ /*
510
+ * Honor the explicit ignore requests
511
+ */
512
+ if (!opts -> overwrite_ignore || opts -> ignore_skipworktree ||
513
+ opts -> ignore_other_worktrees )
514
+ return 1 ;
499
515
500
- /* 2-way merge to the new branch */
501
- topts .initial_checkout = is_cache_unborn ();
502
- topts .update = 1 ;
503
- topts .merge = 1 ;
504
- topts .gently = opts -> merge && old -> commit ;
505
- topts .verbose_update = opts -> show_progress ;
506
- topts .fn = twoway_merge ;
507
- if (opts -> overwrite_ignore ) {
508
- topts .dir = xcalloc (1 , sizeof (* topts .dir ));
509
- topts .dir -> flags |= DIR_SHOW_IGNORED ;
510
- setup_standard_excludes (topts .dir );
511
- }
512
- tree = parse_tree_indirect (old -> commit ?
513
- old -> commit -> object .oid .hash :
514
- EMPTY_TREE_SHA1_BIN );
515
- init_tree_desc (& trees [0 ], tree -> buffer , tree -> size );
516
- tree = parse_tree_indirect (new -> commit -> object .oid .hash );
517
- init_tree_desc (& trees [1 ], tree -> buffer , tree -> size );
518
-
519
- ret = unpack_trees (2 , trees , & topts );
520
- if (ret == -1 ) {
521
- /*
522
- * Unpack couldn't do a trivial merge; either
523
- * give up or do a real merge, depending on
524
- * whether the merge flag was used.
525
- */
526
- struct tree * result ;
527
- struct tree * work ;
528
- struct merge_options o ;
529
- if (!opts -> merge )
530
- return 1 ;
516
+ /*
517
+ * opts->show_progress only impacts output so doesn't require a merge
518
+ */
531
519
532
- /*
533
- * Without old->commit, the below is the same as
534
- * the two-tree unpack we already tried and failed.
535
- */
536
- if (!old -> commit )
537
- return 1 ;
520
+ /*
521
+ * If we aren't creating a new branch any changes or updates will
522
+ * happen in the existing branch. Since that could only be updating
523
+ * the index and working directory, we don't want to skip those steps
524
+ * or we've defeated any purpose in running the command.
525
+ */
526
+ if (!opts -> new_branch )
527
+ return 1 ;
528
+
529
+ /*
530
+ * new_branch_force is defined to "create/reset and checkout a branch"
531
+ * so needs to go through the merge to do the reset
532
+ */
533
+ if (opts -> new_branch_force )
534
+ return 1 ;
538
535
539
- /* Do more real merge */
536
+ /*
537
+ * A new orphaned branch requrires the index and the working tree to be
538
+ * adjusted to <start_point>
539
+ */
540
+ if (opts -> new_orphan_branch )
541
+ return 1 ;
540
542
541
- /*
542
- * We update the index fully, then write the
543
- * tree from the index, then merge the new
544
- * branch with the current tree, with the old
545
- * branch as the base. Then we reset the index
546
- * (but not the working tree) to the new
547
- * branch, leaving the working tree as the
548
- * merged version, but skipping unmerged
549
- * entries in the index.
550
- */
543
+ /*
544
+ * Remaining variables are not checkout options but used to track state
545
+ */
551
546
552
- add_files_to_cache (NULL , NULL , 0 , 0 );
553
- /*
554
- * NEEDSWORK: carrying over local changes
555
- * when branches have different end-of-line
556
- * normalization (or clean+smudge rules) is
557
- * a pain; plumb in an option to set
558
- * o.renormalize?
559
- */
560
- init_merge_options (& o );
561
- o .verbosity = 0 ;
562
- work = write_tree_from_memory (& o );
547
+ return 0 ;
548
+ }
563
549
564
- ret = reset_tree (new -> commit -> tree , opts , 1 ,
565
- writeout_error );
566
- if (ret )
567
- return ret ;
568
- o .ancestor = old -> name ;
569
- o .branch1 = new -> name ;
570
- o .branch2 = "local" ;
571
- merge_trees (& o , new -> commit -> tree , work ,
572
- old -> commit -> tree , & result );
573
- ret = reset_tree (new -> commit -> tree , opts , 0 ,
574
- writeout_error );
550
+
551
+ static int merge_working_tree (const struct checkout_opts * opts ,
552
+ struct branch_info * old ,
553
+ struct branch_info * new ,
554
+ int * writeout_error )
555
+ {
556
+ /*
557
+ * Skip merging the trees, updating the index, and work tree only if we
558
+ * are simply creating a new branch via "git checkout -b foo." Any other
559
+ * options or usage will continue to do all these steps.
560
+ */
561
+ if (!gvfs_config_is_set (GVFS_SKIP_MERGE_IN_CHECKOUT ) ||
562
+ needs_working_tree_merge (opts , old , new )) {
563
+
564
+ int ret ;
565
+ struct lock_file * lock_file = xcalloc (1 , sizeof (struct lock_file ));
566
+
567
+ hold_locked_index (lock_file , 1 );
568
+ if (read_cache_preload (NULL ) < 0 )
569
+ return error (_ ("corrupt index file" ));
570
+
571
+ resolve_undo_clear ();
572
+ if (opts -> force ) {
573
+ ret = reset_tree (new -> commit -> tree , opts , 1 , writeout_error );
575
574
if (ret )
576
575
return ret ;
576
+ } else {
577
+ struct tree_desc trees [2 ];
578
+ struct tree * tree ;
579
+ struct unpack_trees_options topts ;
580
+
581
+ memset (& topts , 0 , sizeof (topts ));
582
+ topts .head_idx = -1 ;
583
+ topts .src_index = & the_index ;
584
+ topts .dst_index = & the_index ;
585
+
586
+ setup_unpack_trees_porcelain (& topts , "checkout" );
587
+
588
+ refresh_cache (REFRESH_QUIET );
589
+
590
+ if (unmerged_cache ()) {
591
+ error (_ ("you need to resolve your current index first" ));
592
+ return 1 ;
593
+ }
594
+
595
+ /* 2-way merge to the new branch */
596
+ topts .initial_checkout = is_cache_unborn ();
597
+ topts .update = 1 ;
598
+ topts .merge = 1 ;
599
+ topts .gently = opts -> merge && old -> commit ;
600
+ topts .verbose_update = opts -> show_progress ;
601
+ topts .fn = twoway_merge ;
602
+ if (opts -> overwrite_ignore ) {
603
+ topts .dir = xcalloc (1 , sizeof (* topts .dir ));
604
+ topts .dir -> flags |= DIR_SHOW_IGNORED ;
605
+ setup_standard_excludes (topts .dir );
606
+ }
607
+ tree = parse_tree_indirect (old -> commit ?
608
+ old -> commit -> object .oid .hash :
609
+ EMPTY_TREE_SHA1_BIN );
610
+ init_tree_desc (& trees [0 ], tree -> buffer , tree -> size );
611
+ tree = parse_tree_indirect (new -> commit -> object .oid .hash );
612
+ init_tree_desc (& trees [1 ], tree -> buffer , tree -> size );
613
+
614
+ ret = unpack_trees (2 , trees , & topts );
615
+ if (ret == -1 ) {
616
+ /*
617
+ * Unpack couldn't do a trivial merge; either
618
+ * give up or do a real merge, depending on
619
+ * whether the merge flag was used.
620
+ */
621
+ struct tree * result ;
622
+ struct tree * work ;
623
+ struct merge_options o ;
624
+ if (!opts -> merge )
625
+ return 1 ;
626
+
627
+ /*
628
+ * Without old->commit, the below is the same as
629
+ * the two-tree unpack we already tried and failed.
630
+ */
631
+ if (!old -> commit )
632
+ return 1 ;
633
+
634
+ /* Do more real merge */
635
+
636
+ /*
637
+ * We update the index fully, then write the
638
+ * tree from the index, then merge the new
639
+ * branch with the current tree, with the old
640
+ * branch as the base. Then we reset the index
641
+ * (but not the working tree) to the new
642
+ * branch, leaving the working tree as the
643
+ * merged version, but skipping unmerged
644
+ * entries in the index.
645
+ */
646
+
647
+ add_files_to_cache (NULL , NULL , 0 , 0 );
648
+ /*
649
+ * NEEDSWORK: carrying over local changes
650
+ * when branches have different end-of-line
651
+ * normalization (or clean+smudge rules) is
652
+ * a pain; plumb in an option to set
653
+ * o.renormalize?
654
+ */
655
+ init_merge_options (& o );
656
+ o .verbosity = 0 ;
657
+ work = write_tree_from_memory (& o );
658
+
659
+ ret = reset_tree (new -> commit -> tree , opts , 1 ,
660
+ writeout_error );
661
+ if (ret )
662
+ return ret ;
663
+ o .ancestor = old -> name ;
664
+ o .branch1 = new -> name ;
665
+ o .branch2 = "local" ;
666
+ merge_trees (& o , new -> commit -> tree , work ,
667
+ old -> commit -> tree , & result );
668
+ ret = reset_tree (new -> commit -> tree , opts , 0 ,
669
+ writeout_error );
670
+ if (ret )
671
+ return ret ;
672
+ }
577
673
}
578
- }
579
674
580
- if (!active_cache_tree )
581
- active_cache_tree = cache_tree ();
675
+ if (!active_cache_tree )
676
+ active_cache_tree = cache_tree ();
582
677
583
- if (!cache_tree_fully_valid (active_cache_tree ))
584
- cache_tree_update (& the_index , WRITE_TREE_SILENT | WRITE_TREE_REPAIR );
678
+ if (!cache_tree_fully_valid (active_cache_tree ))
679
+ cache_tree_update (& the_index , WRITE_TREE_SILENT | WRITE_TREE_REPAIR );
585
680
586
- if (write_locked_index (& the_index , lock_file , COMMIT_LOCK ))
587
- die (_ ("unable to write new index file" ));
681
+ if (write_locked_index (& the_index , lock_file , COMMIT_LOCK ))
682
+ die (_ ("unable to write new index file" ));
683
+ }
588
684
589
685
if (!opts -> force && !opts -> quiet )
590
686
show_local_changes (& new -> commit -> object , & opts -> diff_options );
@@ -825,26 +921,10 @@ static int switch_branches(const struct checkout_opts *opts,
825
921
parse_commit_or_die (new -> commit );
826
922
}
827
923
828
- /*
829
- * Optimize the performance of "git checkout foo" by skipping the call
830
- * to merge_working_tree. Make this as restrictive as possible, only
831
- * checkout a new branch with the current commit. Any other options force
832
- * it through the old path.
833
- */
834
- if (!gvfs_config_is_set (GVFS_SKIP_MERGE_IN_CHECKOUT )
835
- || !old .commit || !new -> commit
836
- || oidcmp (& old .commit -> object .oid , & new -> commit -> object .oid )
837
- || !opts -> new_branch || opts -> new_branch_force || opts -> new_orphan_branch
838
- || opts -> patch_mode || opts -> merge || opts -> force || opts -> force_detach
839
- || opts -> writeout_stage || !opts -> overwrite_ignore
840
- || opts -> ignore_skipworktree || opts -> ignore_other_worktrees
841
- || opts -> new_branch_log || opts -> branch_exists || opts -> prefix
842
- || opts -> source_tree ) {
843
- ret = merge_working_tree (opts , & old , new , & writeout_error );
844
- if (ret ) {
845
- free (path_to_free );
846
- return ret ;
847
- }
924
+ ret = merge_working_tree (opts , & old , new , & writeout_error );
925
+ if (ret ) {
926
+ free (path_to_free );
927
+ return ret ;
848
928
}
849
929
850
930
if (!opts -> quiet && !old .path && old .commit && new -> commit != old .commit )
0 commit comments