@@ -17,6 +17,7 @@ public class RebaseFixture : BaseFixture
1717 const string topicBranch1Name = "T1" ;
1818 const string topicBranch2Name = "T2" ;
1919 const string conflictBranch1Name = "C1" ;
20+ const string topicBranch1PrimeName = "T1Prime" ;
2021
2122 [ Theory ]
2223 [ InlineData ( topicBranch2Name , topicBranch2Name , topicBranch1Name , masterBranch1Name , 3 ) ]
@@ -50,7 +51,7 @@ public void CanRebase(string initialBranchName,
5051 int afterStepCallCount = 0 ;
5152
5253 List < ObjectId > PreRebaseCommits = new List < ObjectId > ( ) ;
53- List < ObjectId > PostRebaseCommits = new List < ObjectId > ( ) ;
54+ List < CompletedRebaseStepInfo > PostRebaseResults = new List < CompletedRebaseStepInfo > ( ) ;
5455 ObjectId expectedParentId = upstream . Tip . Id ;
5556
5657 RebaseOptions options = new RebaseOptions ( )
@@ -63,7 +64,7 @@ public void CanRebase(string initialBranchName,
6364 RebaseStepCompleted = x =>
6465 {
6566 afterStepCallCount ++ ;
66- PostRebaseCommits . Add ( x . CommitId ) ;
67+ PostRebaseResults . Add ( new CompletedRebaseStepInfo ( x . CommitId , x . WasPatchAlreadyApplied ) ) ;
6768 } ,
6869 } ;
6970
@@ -91,19 +92,58 @@ public void CanRebase(string initialBranchName,
9192
9293 // Verify the chain of commits that resulted from the rebase.
9394 Commit expectedParent = expectedOntoCommit ;
94- foreach ( Commit rebasedCommit in PostRebaseCommits . Select ( id => repo . Lookup < Commit > ( id ) ) )
95+ foreach ( CompletedRebaseStepInfo stepInfo in PostRebaseResults )
9596 {
97+ Commit rebasedCommit = repo . Lookup < Commit > ( stepInfo . ObjectId ) ;
9698 Assert . Equal ( expectedParent . Id , rebasedCommit . Parents . First ( ) . Id ) ;
99+ Assert . False ( stepInfo . WasPatchAlreadyApplied ) ;
97100 expectedParent = rebasedCommit ;
98101 }
99102
100- Assert . Equal ( repo . Head . Tip . Id , PostRebaseCommits . Last ( ) ) ;
103+ Assert . Equal ( repo . Head . Tip . Id , PostRebaseResults . Last ( ) . ObjectId ) ;
101104 }
102105 }
103106
104- private class rebaseStepInfo
107+ private class CompletedRebaseStepInfo : IEqualityComparer < CompletedRebaseStepInfo >
105108 {
106- public Commit Commit { get ; set ; }
109+ public CompletedRebaseStepInfo ( ObjectId objectId , bool wasPatchAlreadyApplied )
110+ {
111+ ObjectId = objectId ;
112+ WasPatchAlreadyApplied = wasPatchAlreadyApplied ;
113+ }
114+
115+ public ObjectId ObjectId { get ; set ; }
116+
117+ public bool WasPatchAlreadyApplied { get ; set ; }
118+
119+ bool IEqualityComparer < CompletedRebaseStepInfo > . Equals ( CompletedRebaseStepInfo x , CompletedRebaseStepInfo y )
120+ {
121+ if ( x == null && y == null )
122+ {
123+ return true ;
124+ }
125+
126+ if ( ( x == null && y != null ) ||
127+ ( x != null && y == null ) )
128+ {
129+ return false ;
130+ }
131+
132+ return x . WasPatchAlreadyApplied == y . WasPatchAlreadyApplied &&
133+ ObjectId . Equals ( x . ObjectId , y . ObjectId ) ;
134+ }
135+
136+ int IEqualityComparer < CompletedRebaseStepInfo > . GetHashCode ( CompletedRebaseStepInfo obj )
137+ {
138+ int hashCode = obj . WasPatchAlreadyApplied . GetHashCode ( ) ;
139+
140+ if ( obj . ObjectId != null )
141+ {
142+ hashCode += obj . ObjectId . GetHashCode ( ) ;
143+ }
144+
145+ return hashCode ;
146+ }
107147 }
108148
109149 /// <summary>
@@ -335,7 +375,7 @@ public void RebaseWhileAlreadyRebasingThrows()
335375
336376 Assert . Throws < LibGit2SharpException > ( ( ) =>
337377 repo . Rebase . Start ( branch , upstream , onto , Constants . Signature , null ) ) ;
338- }
378+ }
339379 }
340380
341381 [ Fact ]
@@ -371,6 +411,57 @@ public void CurrentStepInfoIsNullWhenNotRebasing()
371411 }
372412 }
373413
414+ [ Fact ]
415+ public void CanHandlePatchAlreadyApplied ( )
416+ {
417+ SelfCleaningDirectory scd = BuildSelfCleaningDirectory ( ) ;
418+ var path = Repository . Init ( scd . DirectoryPath ) ;
419+ using ( Repository repo = new Repository ( path ) )
420+ {
421+ ConstructRebaseTestRepository ( repo ) ;
422+
423+ repo . Checkout ( topicBranch1Name ) ;
424+
425+ Branch topicBranch1Prime = repo . CreateBranch ( topicBranch1PrimeName , masterBranch1Name ) ;
426+
427+ string newFileRelativePath = "new_file.txt" ;
428+ Touch ( repo . Info . WorkingDirectory , newFileRelativePath , "New Content" ) ;
429+ repo . Stage ( newFileRelativePath ) ;
430+ Commit commit = repo . Commit ( "new commit 1" , Constants . Signature , Constants . Signature , new CommitOptions ( ) ) ;
431+
432+ repo . Checkout ( topicBranch1Prime ) ;
433+ var cherryPickResult = repo . CherryPick ( commit , Constants . Signature2 ) ;
434+ Assert . Equal ( CherryPickStatus . CherryPicked , cherryPickResult . Status ) ;
435+
436+ string newFileRelativePath2 = "new_file_2.txt" ;
437+ Touch ( repo . Info . WorkingDirectory , newFileRelativePath2 , "New Content for path 2" ) ;
438+ repo . Stage ( newFileRelativePath2 ) ;
439+ repo . Commit ( "new commit 2" , Constants . Signature , Constants . Signature , new CommitOptions ( ) ) ;
440+
441+ Branch upstreamBranch = repo . Branches [ topicBranch1Name ] ;
442+
443+ List < CompletedRebaseStepInfo > rebaseResults = new List < CompletedRebaseStepInfo > ( ) ;
444+
445+ RebaseOptions options = new RebaseOptions ( )
446+ {
447+ RebaseStepCompleted = x =>
448+ {
449+ rebaseResults . Add ( new CompletedRebaseStepInfo ( x . CommitId , x . WasPatchAlreadyApplied ) ) ;
450+ }
451+ } ;
452+
453+ repo . Rebase . Start ( null , upstreamBranch , null , Constants . Signature2 , options ) ;
454+
455+ List < CompletedRebaseStepInfo > expectedRebaseResults = new List < CompletedRebaseStepInfo > ( )
456+ {
457+ new CompletedRebaseStepInfo ( null , true ) ,
458+ new CompletedRebaseStepInfo ( new ObjectId ( "ebdea37ecf583fb7fa5c806a1c00b82f3987fbaa" ) , false ) ,
459+ } ;
460+
461+ Assert . Equal ( expectedRebaseResults , rebaseResults ) ;
462+ }
463+ }
464+
374465 private void ConstructRebaseTestRepository ( Repository repo )
375466 {
376467 // Constructs a graph that looks like:
@@ -425,7 +516,7 @@ private void ConstructRebaseTestRepository(Repository repo)
425516 repo . Stage ( filePathC ) ;
426517 commit = repo . Commit ( "commit 3" , Constants . Signature , Constants . Signature , new CommitOptions ( ) ) ;
427518
428- repo . CreateBranch ( masterBranch1Name , commit , Constants . Signature ) ;
519+ Branch masterBranch1 = repo . CreateBranch ( masterBranch1Name , commit , Constants . Signature ) ;
429520
430521 Touch ( workdir , filePathB , string . Join ( lineEnding , fileContentB1 , fileContentB2 ) ) ;
431522 repo . Stage ( filePathB ) ;
@@ -455,7 +546,7 @@ private void ConstructRebaseTestRepository(Repository repo)
455546
456547 repo . CreateBranch ( topicBranch2Name , commit , Constants . Signature ) ;
457548
458- repo . Checkout ( masterBranch1Name ) ;
549+ repo . Checkout ( masterBranch1 . Tip ) ;
459550 Touch ( workdir , filePathD , fileContentD1 ) ;
460551 repo . Stage ( filePathD ) ;
461552 commit = repo . Commit ( "commit 10" , Constants . Signature , Constants . Signature , new CommitOptions ( ) ) ;
0 commit comments