@@ -44,6 +44,14 @@ public void CanCheckoutAnExistingBranch(string branchName)
44
44
45
45
// Working directory should not be dirty
46
46
Assert . False ( repo . Index . RetrieveStatus ( ) . IsDirty ) ;
47
+
48
+ // Assert reflog entry is created
49
+ var reflogEntry = repo . Refs . Log ( repo . Refs . Head ) . First ( ) ;
50
+ Assert . Equal ( master . Tip . Id , reflogEntry . From ) ;
51
+ Assert . Equal ( branch . Tip . Id , reflogEntry . To ) ;
52
+ Assert . NotNull ( reflogEntry . Commiter . Email ) ;
53
+ Assert . NotNull ( reflogEntry . Commiter . Name ) ;
54
+ Assert . Equal ( string . Format ( "checkout: moving from master to {0}" , branchName ) , reflogEntry . Message ) ;
47
55
}
48
56
}
49
57
@@ -74,6 +82,14 @@ public void CanCheckoutAnExistingBranchByName(string branchName)
74
82
75
83
// Working directory should not be dirty
76
84
Assert . False ( repo . Index . RetrieveStatus ( ) . IsDirty ) ;
85
+
86
+ // Assert reflog entry is created
87
+ var reflogEntry = repo . Refs . Log ( repo . Refs . Head ) . First ( ) ;
88
+ Assert . Equal ( master . Tip . Id , reflogEntry . From ) ;
89
+ Assert . Equal ( repo . Branches [ branchName ] . Tip . Id , reflogEntry . To ) ;
90
+ Assert . NotNull ( reflogEntry . Commiter . Email ) ;
91
+ Assert . NotNull ( reflogEntry . Commiter . Name ) ;
92
+ Assert . Equal ( string . Format ( "checkout: moving from master to {0}" , branchName ) , reflogEntry . Message ) ;
77
93
}
78
94
}
79
95
@@ -111,6 +127,14 @@ public void CanCheckoutAnArbitraryCommit(string commitPointer)
111
127
Assert . Equal ( "(no branch)" , detachedHead . CanonicalName ) ;
112
128
113
129
Assert . False ( master . IsCurrentRepositoryHead ) ;
130
+
131
+ // Assert reflog entry is created
132
+ var reflogEntry = repo . Refs . Log ( repo . Refs . Head ) . First ( ) ;
133
+ Assert . Equal ( master . Tip . Id , reflogEntry . From ) ;
134
+ Assert . Equal ( commitSha , reflogEntry . To . Sha ) ;
135
+ Assert . NotNull ( reflogEntry . Commiter . Email ) ;
136
+ Assert . NotNull ( reflogEntry . Commiter . Name ) ;
137
+ Assert . Equal ( string . Format ( "checkout: moving from master to {0}" , commitPointer ) , reflogEntry . Message ) ;
114
138
}
115
139
}
116
140
@@ -572,6 +596,14 @@ public void CheckingOutRemoteBranchResultsInDetachedHead()
572
596
// Verify that HEAD is detached.
573
597
Assert . Equal ( repo . Refs [ "HEAD" ] . TargetIdentifier , repo . Branches [ "origin/master" ] . Tip . Sha ) ;
574
598
Assert . True ( repo . Info . IsHeadDetached ) ;
599
+
600
+ // Assert reflog entry is created
601
+ var reflogEntry = repo . Refs . Log ( repo . Refs . Head ) . First ( ) ;
602
+ Assert . Equal ( master . Tip . Id , reflogEntry . From ) ;
603
+ Assert . Equal ( repo . Branches [ "origin/master" ] . Tip . Id , reflogEntry . To ) ;
604
+ Assert . NotNull ( reflogEntry . Commiter . Email ) ;
605
+ Assert . NotNull ( reflogEntry . Commiter . Name ) ;
606
+ Assert . Equal ( "checkout: moving from master to origin/master" , reflogEntry . Message ) ;
575
607
}
576
608
}
577
609
@@ -601,6 +633,136 @@ public void CheckingOutABranchDoesNotAlterBinaryFiles()
601
633
}
602
634
}
603
635
636
+ [ Theory ]
637
+ [ InlineData ( "a447ba2ca8" ) ]
638
+ [ InlineData ( "refs/tags/lw" ) ]
639
+ [ InlineData ( "e90810^{}" ) ]
640
+ public void CheckoutFromDetachedHead ( string commitPointer )
641
+ {
642
+ string path = CloneStandardTestRepo ( ) ;
643
+ using ( var repo = new Repository ( path ) )
644
+ {
645
+ // Set the working directory to the current head
646
+ ResetAndCleanWorkingDirectory ( repo ) ;
647
+ Assert . False ( repo . Index . RetrieveStatus ( ) . IsDirty ) ;
648
+
649
+ var commitSha = repo . Lookup ( commitPointer ) . Sha ;
650
+
651
+ Branch initialHead = repo . Checkout ( "6dcf9bf" ) ;
652
+
653
+ repo . Checkout ( commitPointer ) ;
654
+
655
+ // Assert reflog entry is created
656
+ var reflogEntry = repo . Refs . Log ( repo . Refs . Head ) . First ( ) ;
657
+ Assert . Equal ( initialHead . Tip . Id , reflogEntry . From ) ;
658
+ Assert . Equal ( commitSha , reflogEntry . To . Sha ) ;
659
+ Assert . NotNull ( reflogEntry . Commiter . Email ) ;
660
+ Assert . NotNull ( reflogEntry . Commiter . Name ) ;
661
+ Assert . Equal ( string . Format ( "checkout: moving from {0} to {1}" , initialHead . Tip . Sha , commitPointer ) , reflogEntry . Message ) ;
662
+ }
663
+ }
664
+
665
+ [ Fact ]
666
+ public void CheckoutBranchFromDetachedHead ( )
667
+ {
668
+ string path = CloneStandardTestRepo ( ) ;
669
+ using ( var repo = new Repository ( path ) )
670
+ {
671
+ // Set the working directory to the current head
672
+ ResetAndCleanWorkingDirectory ( repo ) ;
673
+ Assert . False ( repo . Index . RetrieveStatus ( ) . IsDirty ) ;
674
+
675
+ Branch initialHead = repo . Checkout ( "6dcf9bf" ) ;
676
+
677
+ Assert . True ( repo . Info . IsHeadDetached ) ;
678
+
679
+ Branch newHead = repo . Checkout ( repo . Branches [ "master" ] ) ;
680
+
681
+ // Assert reflog entry is created
682
+ var reflogEntry = repo . Refs . Log ( repo . Refs . Head ) . First ( ) ;
683
+ Assert . Equal ( initialHead . Tip . Id , reflogEntry . From ) ;
684
+ Assert . Equal ( newHead . Tip . Id , reflogEntry . To ) ;
685
+ Assert . NotNull ( reflogEntry . Commiter . Email ) ;
686
+ Assert . NotNull ( reflogEntry . Commiter . Name ) ;
687
+ Assert . Equal ( string . Format ( "checkout: moving from {0} to {1}" , initialHead . Tip . Sha , newHead . Name ) , reflogEntry . Message ) ;
688
+ }
689
+ }
690
+
691
+
692
+ [ Fact ( Skip = "Current libgit2 revparse implementation only returns the object being pointed at, not the reference pointing at it." ) ]
693
+ public void CheckoutPreviousCheckedOutBranch ( )
694
+ {
695
+ string path = CloneStandardTestRepo ( ) ;
696
+ using ( var repo = new Repository ( path ) )
697
+ {
698
+ // Set the working directory to the current head
699
+ ResetAndCleanWorkingDirectory ( repo ) ;
700
+ Assert . False ( repo . Index . RetrieveStatus ( ) . IsDirty ) ;
701
+
702
+ Branch previousHead = repo . Checkout ( "i-do-numbers" ) ;
703
+ Branch newHead = repo . Checkout ( "diff-test-cases" ) ;
704
+
705
+ //Go back to previous branch checked out
706
+ repo . Checkout ( @"@{-1}" ) ;
707
+
708
+ // Assert reflog entry is created
709
+ var reflogEntry = repo . Refs . Log ( repo . Refs . Head ) . First ( ) ;
710
+ Assert . Equal ( newHead . Tip . Id , reflogEntry . From ) ;
711
+ Assert . Equal ( previousHead . Tip . Id , reflogEntry . To ) ;
712
+ Assert . NotNull ( reflogEntry . Commiter . Email ) ;
713
+ Assert . NotNull ( reflogEntry . Commiter . Name ) ;
714
+ Assert . Equal ( "checkout: moving from diff-test-cases to i-do-numbers" , reflogEntry . Message ) ;
715
+ }
716
+ }
717
+
718
+ [ Fact ]
719
+ public void CheckoutCurrentReference ( )
720
+ {
721
+ string path = CloneStandardTestRepo ( ) ;
722
+ using ( var repo = new Repository ( path ) )
723
+ {
724
+ Branch master = repo . Branches [ "master" ] ;
725
+ Assert . True ( master . IsCurrentRepositoryHead ) ;
726
+
727
+ ResetAndCleanWorkingDirectory ( repo ) ;
728
+ Assert . False ( repo . Index . RetrieveStatus ( ) . IsDirty ) ;
729
+
730
+ var reflogEntriesCount = repo . Refs . Log ( repo . Refs . Head ) . Count ( ) ;
731
+
732
+ // Checkout branch
733
+ repo . Checkout ( master ) ;
734
+
735
+ Assert . Equal ( reflogEntriesCount , repo . Refs . Log ( repo . Refs . Head ) . Count ( ) ) ;
736
+
737
+ // Checkout in detached mode
738
+ repo . Checkout ( master . Tip . Sha ) ;
739
+
740
+ Assert . True ( repo . Info . IsHeadDetached ) ;
741
+ var reflogEntry = repo . Refs . Log ( repo . Refs . Head ) . First ( ) ;
742
+ Assert . True ( reflogEntry . To == reflogEntry . From ) ;
743
+ Assert . Equal ( string . Format ( "checkout: moving from master to {0}" , master . Tip . Sha ) , reflogEntry . Message ) ;
744
+
745
+ // Checkout detached "HEAD" => nothing should happen
746
+ reflogEntriesCount = repo . Refs . Log ( repo . Refs . Head ) . Count ( ) ;
747
+
748
+ repo . Checkout ( repo . Head ) ;
749
+
750
+ Assert . Equal ( reflogEntriesCount , repo . Refs . Log ( repo . Refs . Head ) . Count ( ) ) ;
751
+
752
+ // Checkout attached "HEAD" => nothing should happen
753
+ repo . Checkout ( "master" ) ;
754
+ reflogEntriesCount = repo . Refs . Log ( repo . Refs . Head ) . Count ( ) ;
755
+
756
+ repo . Checkout ( repo . Head ) ;
757
+
758
+ Assert . Equal ( reflogEntriesCount , repo . Refs . Log ( repo . Refs . Head ) . Count ( ) ) ;
759
+
760
+ repo . Checkout ( "HEAD" ) ;
761
+
762
+ Assert . Equal ( reflogEntriesCount , repo . Refs . Log ( repo . Refs . Head ) . Count ( ) ) ;
763
+ }
764
+ }
765
+
604
766
[ Fact ]
605
767
public void CheckoutLowerCasedHeadThrows ( )
606
768
{
0 commit comments