801
test_cmp_config "" --default "" branch.main2.merge
802
'
803
804
+test_expect_success 'setup upstream for --track=fetch tests' '
805
+ git checkout main &&
806
+ git init fetch_upstream &&
807
+ test_commit -C fetch_upstream u_main &&
808
+ git remote add fetch_upstream fetch_upstream &&
809
+ git fetch fetch_upstream &&
810
+ git -C fetch_upstream checkout -b fetch_new &&
811
+ test_commit -C fetch_upstream u_new
812
+'
813
+
814
+test_expect_success 'checkout --track=fetch -b picks up branch created upstream after clone' '
815
+ git checkout main &&
816
+ test_must_fail git rev-parse --verify refs/remotes/fetch_upstream/fetch_new &&
817
+ git checkout --track=fetch -b local_new fetch_upstream/fetch_new &&
818
+ test_cmp_rev refs/remotes/fetch_upstream/fetch_new HEAD &&
819
+ test_cmp_config fetch_upstream branch.local_new.remote &&
820
+ test_cmp_config refs/heads/fetch_new branch.local_new.merge
821
+'
822
+
823
+test_expect_success 'checkout --track=fetch <remote>/<branch> leaves other tracking branches untouched' '
824
+ git checkout main &&
825
+ git -C fetch_upstream checkout -b fetch_target &&
826
+ test_commit -C fetch_upstream u_target_pre &&
827
+ git -C fetch_upstream checkout -b fetch_other &&
828
+ test_commit -C fetch_upstream u_other_pre &&
829
+ git fetch fetch_upstream &&
830
+ git update-ref refs/heads/snapshot_other refs/remotes/fetch_upstream/fetch_other &&
831
+ git -C fetch_upstream checkout fetch_target &&
832
+ test_commit -C fetch_upstream u_target_post &&
833
+ git -C fetch_upstream checkout fetch_other &&
834
+ test_commit -C fetch_upstream u_other_post &&
835
+ git checkout --track=fetch -b local_target fetch_upstream/fetch_target &&
836
+ test_cmp_rev refs/remotes/fetch_upstream/fetch_target HEAD &&
837
+ test_cmp_rev refs/remotes/fetch_upstream/fetch_other snapshot_other
838
+'
839
+
840
+test_expect_success 'checkout --track=fetch with bare remote name fetches only <remote>/HEAD target' '
841
+ git checkout main &&
842
+ git -C fetch_upstream checkout main &&
843
+ git remote set-head fetch_upstream main &&
844
+ git -C fetch_upstream checkout -b fetch_unrelated &&
845
+ test_commit -C fetch_upstream u_unrelated_pre &&
846
+ git fetch fetch_upstream fetch_unrelated &&
847
+ git update-ref refs/heads/snapshot_unrelated \
848
+ refs/remotes/fetch_upstream/fetch_unrelated &&
849
+ git -C fetch_upstream checkout main &&
850
+ test_commit -C fetch_upstream u_main_post &&
851
+ git -C fetch_upstream checkout fetch_unrelated &&
852
+ test_commit -C fetch_upstream u_unrelated_post &&
853
+ git checkout --track=fetch -b local_from_remote fetch_upstream &&
854
+ test_cmp_rev refs/remotes/fetch_upstream/main HEAD &&
855
+ test_cmp_rev refs/remotes/fetch_upstream/fetch_unrelated snapshot_unrelated
856
+'
857
+
858
+test_expect_success 'checkout --track=fetch aborts and does not create branch when no existing ref' '
859
+ git checkout main &&
860
+ test_might_fail git branch -D bogus &&
861
+ test_must_fail git checkout --track=fetch -b bogus fetch_upstream/does_not_exist &&
862
+ test_must_fail git rev-parse --verify refs/heads/bogus
863
+'
864
+
865
+test_expect_success 'checkout --track=fetch warns and proceeds when fetch fails but ref exists' '
866
+ git checkout main &&
867
+ git -C fetch_upstream checkout -b fetch_offline &&
868
+ test_commit -C fetch_upstream u_offline &&
869
+ git fetch fetch_upstream fetch_offline &&
870
+ saved_url=$(git config remote.fetch_upstream.url) &&
871
+ test_when_finished "git config remote.fetch_upstream.url \"$saved_url\"" &&
872
+ git config remote.fetch_upstream.url ./does-not-exist &&
873
+ git checkout --track=fetch -b local_offline fetch_upstream/fetch_offline 2>err &&
874
+ test_grep "failed to fetch" err &&
875
+ test_cmp_rev refs/remotes/fetch_upstream/fetch_offline HEAD
876
+'
877
+
878
+test_expect_success 'checkout --track=fetch resolves through configured fetch refspec' '
879
+ git checkout main &&
880
+ git remote add fetch_custom ./fetch_upstream &&
881
+ test_when_finished "git remote remove fetch_custom" &&
882
+ git config --replace-all remote.fetch_custom.fetch \
883
+ "+refs/heads/*:refs/remotes/custom-ns/*" &&
884
+ git -C fetch_upstream checkout -b fetch_refspec &&
885
+ test_commit -C fetch_upstream u_refspec &&
886
+ test_must_fail git rev-parse --verify refs/remotes/custom-ns/fetch_refspec &&
887
+ git checkout --track=fetch -b local_refspec custom-ns/fetch_refspec &&
888
+ test_cmp_rev refs/remotes/custom-ns/fetch_refspec HEAD
889
+'
890
+
891
+test_expect_success 'checkout --track=fetch on bare remote-tracking prefix follows <prefix>/HEAD' '
892
+ git checkout main &&
893
+ git remote add fetch_ns ./fetch_upstream &&
894
+ test_when_finished "git remote remove fetch_ns" &&
895
+ test_when_finished "git update-ref -d refs/remotes/ns_alias/HEAD" &&
896
+ git config --replace-all remote.fetch_ns.fetch \
897
+ "+refs/heads/*:refs/remotes/ns_alias/*" &&
898
+ git fetch fetch_ns &&
899
+ git symbolic-ref refs/remotes/ns_alias/HEAD refs/remotes/ns_alias/main &&
900
+ git -C fetch_upstream checkout main &&
901
+ test_commit -C fetch_upstream u_ns_post &&
902
+ git checkout --track=fetch -b local_ns ns_alias &&
903
+ test_cmp_rev refs/remotes/ns_alias/main HEAD &&
904
+ test_cmp_config fetch_ns branch.local_ns.remote &&
905
+ test_cmp_config refs/heads/main branch.local_ns.merge
906
+'
907
+
908
+test_expect_success 'checkout --track=fetch dies on bare remote name with no <ns>/HEAD' '
909
+ git checkout main &&
910
+ git remote add fetch_nohead ./fetch_upstream &&
911
+ test_when_finished "git remote remove fetch_nohead" &&
912
+ test_might_fail git symbolic-ref -d refs/remotes/fetch_nohead/HEAD &&
913
+ test_must_fail git checkout --track=fetch -b local_nohead fetch_nohead 2>err &&
914
+ test_grep "refs/remotes/fetch_nohead/HEAD" err &&
915
+ test_grep "git remote set-head fetch_nohead --auto" err &&
916
+ test_must_fail git rev-parse --verify refs/heads/local_nohead
917
+'
918
+
919
+test_expect_success 'checkout --track=fetch on bare unknown name does not suggest set-head' '
920
+ git checkout main &&
921
+ test_must_fail git rev-parse --verify refs/remotes/no_such_ns/HEAD &&
922
+ test_must_fail git config --get remote.no_such_ns.url &&
923
+ test_must_fail git checkout --track=fetch -b local_unknown no_such_ns 2>err &&
924
+ test_grep "no configured remote" err &&
925
+ test_grep ! "set-head" err &&
926
+ test_must_fail git rev-parse --verify refs/heads/local_unknown
927
+'
928
+
929
+test_expect_success 'checkout --track=fetch rejects <ns>/HEAD pointing outside the tracking prefix' '
930
+ git checkout main &&
931
+ git remote add fetch_crossns ./fetch_upstream &&
932
+ test_when_finished "git remote remove fetch_crossns" &&
933
+ test_when_finished "git update-ref -d refs/remotes/fetch_crossns/HEAD" &&
934
+ git fetch fetch_crossns &&
935
+ git symbolic-ref refs/remotes/fetch_crossns/HEAD \
936
+ refs/remotes/fetch_upstream/u_main &&
937
+ test_must_fail git checkout --track=fetch -b local_crossns fetch_crossns 2>err &&
938
+ test_grep "refs/remotes/fetch_crossns/HEAD" err &&
939
+ test_must_fail git rev-parse --verify refs/heads/local_crossns
940
+'
941
+
942
+test_expect_success 'checkout --track=fetch dies on ambiguous fetch refspec match' '
943
+ git checkout main &&
944
+ git remote add fetch_ambig_a ./fetch_upstream &&
945
+ git remote add fetch_ambig_b ./fetch_upstream &&
946
+ test_when_finished "git remote remove fetch_ambig_a" &&
947
+ test_when_finished "git remote remove fetch_ambig_b" &&
948
+ git config --replace-all remote.fetch_ambig_a.fetch \
949
+ "+refs/heads/*:refs/remotes/ambig_ns/*" &&
950
+ git config --replace-all remote.fetch_ambig_b.fetch \
951
+ "+refs/heads/*:refs/remotes/ambig_ns/*" &&
952
+ git -C fetch_upstream checkout -b fetch_ambig &&
953
+ test_commit -C fetch_upstream u_ambig &&
954
+ test_must_fail git checkout --track=fetch -b local_ambig ambig_ns/fetch_ambig 2>err &&
955
+ test_grep "fetch_ambig_a" err &&
956
+ test_grep "fetch_ambig_b" err &&
957
+ test_grep "tracking namespaces" err &&
958
+ test_must_fail git rev-parse --verify refs/heads/local_ambig
959
+'
960
+
961
+test_expect_success 'checkout --track=fetch rejects invalid refname components' '
962
+ git checkout main &&
963
+ test_must_fail git checkout --track=fetch -b local_invalid "foo..bar" 2>err &&
964
+ test_grep "valid" err &&
965
+ test_must_fail git rev-parse --verify refs/heads/local_invalid
966
+'
967
+
968
+test_expect_success 'checkout --track=inherit,direct is rejected' '
969
+ test_must_fail git checkout --track=inherit,direct -b bad fetch_upstream/fetch_new 2>err &&
970
+ test_grep "cannot combine" err
971
+'
972
+
973
+test_expect_success 'checkout --track=fetch then --track=direct drops fetch (last-one-wins)' '
974
+ git checkout main &&
975
+ git -C fetch_upstream checkout -b fetch_lastwin &&
976
+ test_commit -C fetch_upstream u_lastwin &&
977
+ test_must_fail git rev-parse --verify refs/remotes/fetch_upstream/fetch_lastwin &&
978
+ test_must_fail git checkout --track=fetch --track=direct \
979
+ -b local_lastwin fetch_upstream/fetch_lastwin &&
980
+ test_must_fail git rev-parse --verify refs/remotes/fetch_upstream/fetch_lastwin
981
+'
982
+
983
+test_expect_success 'checkout --track=fetch,inherit fetches remote-tracking start-point' '
984
+ git checkout main &&
985
+ git -C fetch_upstream checkout -b fetch_inherit &&
986
+ test_commit -C fetch_upstream u_inherit &&
987
+ test_must_fail git rev-parse --verify refs/remotes/fetch_upstream/fetch_inherit &&
988
+ git checkout --track=fetch,inherit -b local_inherit \
989
+ fetch_upstream/fetch_inherit &&
990
+ test_cmp_rev refs/remotes/fetch_upstream/fetch_inherit HEAD
991
+'
992
+
993
+test_expect_success 'checkout --track=fetch on local start-point errors' '
994
+ git checkout main &&
995
+ test_must_fail git checkout --track=fetch -b bad main 2>err &&
996
+ test_grep "no configured remote" err &&
997
+ test_must_fail git rev-parse --verify refs/heads/bad
998
+'
999
+
1000
+test_expect_success 'checkout --track=bogus reports an error' '
1001
+ git checkout main &&
1002
+ test_must_fail git checkout --track=bogus -b bogus_branch fetch_upstream/fetch_new 2>err &&
1003
+ test_grep "expects" err
1004
+'
1005
+
1006
+test_expect_success 'checkout -q --track=fetch silences the fetch output' '
1007
+ git checkout main &&
1008
+ git -C fetch_upstream checkout -b fetch_quiet &&
1009
+ test_commit -C fetch_upstream u_quiet &&
1010
+ test_must_fail git rev-parse --verify refs/remotes/fetch_upstream/fetch_quiet &&
1011
+ git checkout -q --track=fetch -b local_quiet \
1012
+ fetch_upstream/fetch_quiet 2>err &&
1013
+ test_grep ! "-> fetch_upstream/fetch_quiet" err &&
1014
+ test_cmp_rev refs/remotes/fetch_upstream/fetch_quiet HEAD
1015
+'
1016
+
1017
+test_expect_success 'switch --track=fetch -c picks up branch created upstream after clone' '
1018
+ git checkout main &&
1019
+ git -C fetch_upstream checkout -b fetch_switch &&
1020
+ test_commit -C fetch_upstream u_switch &&
1021
+ test_must_fail git rev-parse --verify refs/remotes/fetch_upstream/fetch_switch &&
1022
+ git switch --track=fetch -c local_switch fetch_upstream/fetch_switch &&
1023
+ test_cmp_rev refs/remotes/fetch_upstream/fetch_switch HEAD
1024
+'
1025
+
1026
test_done