@@ -10,6 +10,12 @@ namespace LibGit2Sharp
10
10
{
11
11
internal class RebaseOperationImpl
12
12
{
13
+ private enum RebaseAction
14
+ {
15
+ ApplyStep ,
16
+ Finish ,
17
+ Finished ,
18
+ } ;
13
19
14
20
/// <summary>
15
21
/// Run a rebase to completion, a conflict, or a requested stop point.
@@ -36,53 +42,31 @@ public static RebaseResult Run(RebaseSafeHandle rebaseOperationHandle,
36
42
GitCheckoutOpts gitCheckoutOpts = checkoutOptionsWrapper . Options ;
37
43
RebaseResult rebaseResult = null ;
38
44
39
- // stepBeingApplied indicates the step that will be applied by by git_rebase_next.
40
- // The current step does not get incremented until git_rebase_next (except on
41
- // the initial step), but we want to report the step that will be applied.
42
- long stepBeingApplied = Proxy . git_rebase_operation_current ( rebaseOperationHandle ) ;
43
- if ( ! isStarting )
44
- {
45
- stepBeingApplied ++ ;
46
- }
47
-
48
- long totalStepCount = Proxy . git_rebase_operation_entrycount ( rebaseOperationHandle ) ;
45
+ RebaseAction action ;
46
+ RebaseStepInfo stepToApplyInfo ;
49
47
50
48
// This loop will run until either:
51
49
// 1) All steps have been run or
52
50
// 2) rebaseResult is set - indicating that the current
53
51
// sequence should be stopped and a result needs to be
54
52
// reported.
55
- while ( stepBeingApplied < totalStepCount )
53
+ while ( ( action = NextRebaseAction ( out stepToApplyInfo , repository , rebaseOperationHandle , isStarting ) ) == RebaseAction . ApplyStep )
56
54
{
57
- GitRebaseOperation rebaseOp = Proxy . git_rebase_operation_byindex ( rebaseOperationHandle , stepBeingApplied ) ;
58
- ObjectId idOfCommitBeingRebased = new ObjectId ( rebaseOp . id ) ;
59
- RebaseStepInfo stepInfo = new RebaseStepInfo ( rebaseOp . type ,
60
- repository . Lookup < Commit > ( idOfCommitBeingRebased ) ,
61
- LaxUtf8NoCleanupMarshaler . FromNative ( rebaseOp . exec ) ,
62
- stepBeingApplied ,
63
- totalStepCount ) ;
55
+ isStarting = false ;
64
56
65
57
// Report the rebase step we are about to perform.
66
58
if ( options . RebaseStepStarting != null )
67
59
{
68
- options . RebaseStepStarting ( new BeforeRebaseStepInfo ( stepInfo ) ) ;
60
+ options . RebaseStepStarting ( new BeforeRebaseStepInfo ( stepToApplyInfo ) ) ;
69
61
}
70
62
71
63
// Perform the rebase step
72
64
GitRebaseOperation rebaseOpReport = Proxy . git_rebase_next ( rebaseOperationHandle , ref gitCheckoutOpts ) ;
73
65
74
- // The step reported via querying by index and the step returned from git_rebase_next
75
- // should be the same
76
- if ( rebaseOpReport == null ||
77
- new ObjectId ( rebaseOpReport . id ) != idOfCommitBeingRebased ||
78
- rebaseOpReport . type != rebaseOp . type )
79
- {
80
- // This is indicative of a program error - should never happen.
81
- throw new LibGit2SharpException ( "Unexpected step info reported by running rebase step." ) ;
82
- }
66
+ VerifyRebaseOp ( rebaseOpReport , stepToApplyInfo ) ;
83
67
84
68
// Handle the result
85
- switch ( rebaseOp . type )
69
+ switch ( stepToApplyInfo . Type )
86
70
{
87
71
case RebaseStepOperation . Pick :
88
72
// commit and continue.
@@ -95,19 +79,19 @@ public static RebaseResult Run(RebaseSafeHandle rebaseOperationHandle,
95
79
{
96
80
if ( rebase_commit_result . WasPatchAlreadyApplied )
97
81
{
98
- options . RebaseStepCompleted ( new AfterRebaseStepInfo ( stepInfo ) ) ;
82
+ options . RebaseStepCompleted ( new AfterRebaseStepInfo ( stepToApplyInfo ) ) ;
99
83
}
100
84
else
101
85
{
102
- options . RebaseStepCompleted ( new AfterRebaseStepInfo ( stepInfo , repository . Lookup < Commit > ( new ObjectId ( rebase_commit_result . CommitId ) ) ) ) ;
86
+ options . RebaseStepCompleted ( new AfterRebaseStepInfo ( stepToApplyInfo , repository . Lookup < Commit > ( new ObjectId ( rebase_commit_result . CommitId ) ) ) ) ;
103
87
}
104
88
}
105
89
}
106
90
else
107
91
{
108
92
rebaseResult = new RebaseResult ( RebaseStatus . Conflicts ,
109
- stepBeingApplied ,
110
- totalStepCount ,
93
+ stepToApplyInfo . CurrentStep ,
94
+ stepToApplyInfo . TotalStepCount ,
111
95
null ) ;
112
96
}
113
97
break ;
@@ -119,31 +103,27 @@ public static RebaseResult Run(RebaseSafeHandle rebaseOperationHandle,
119
103
// These operations are not yet supported by lg2.
120
104
throw new LibGit2SharpException ( string . Format (
121
105
"Rebase Operation Type ({0}) is not currently supported in LibGit2Sharp." ,
122
- rebaseOp . type ) ) ;
106
+ stepToApplyInfo . Type ) ) ;
123
107
default :
124
108
throw new ArgumentException ( string . Format (
125
- "Unexpected Rebase Operation Type: {0}" , rebaseOp . type ) ) ;
109
+ "Unexpected Rebase Operation Type: {0}" , stepToApplyInfo . Type ) ) ;
126
110
}
127
111
128
112
// If we have not generated a result that needs to be
129
113
// reported, move to the next step.
130
- if ( rebaseResult == null )
131
- {
132
- stepBeingApplied ++ ;
133
- }
134
- else
114
+ if ( rebaseResult != null )
135
115
{
136
116
break ;
137
117
}
138
118
}
139
119
140
120
// If the step being applied is equal to the total step count,
141
121
// that means all steps have been run and we are finished.
142
- if ( stepBeingApplied == totalStepCount )
122
+ if ( action == RebaseAction . Finish )
143
123
{
144
124
Debug . Assert ( rebaseResult == null ) ;
145
125
146
- // Done!
126
+ long totalStepCount = Proxy . git_rebase_operation_entrycount ( rebaseOperationHandle ) ;
147
127
GitRebaseOptions gitRebaseOptions = new GitRebaseOptions ( )
148
128
{
149
129
version = 1 ,
@@ -160,5 +140,63 @@ public static RebaseResult Run(RebaseSafeHandle rebaseOperationHandle,
160
140
return rebaseResult ;
161
141
}
162
142
}
143
+
144
+ /// <summary>
145
+ /// Verify that the information in a GitRebaseOperation and a RebaseStepInfo agree
146
+ /// </summary>
147
+ /// <param name="rebaseOpReport"></param>
148
+ /// <param name="stepInfo"></param>
149
+ private static void VerifyRebaseOp ( GitRebaseOperation rebaseOpReport , RebaseStepInfo stepInfo )
150
+ {
151
+ // The step reported via querying by index and the step returned from git_rebase_next
152
+ // should be the same
153
+ if ( rebaseOpReport == null ||
154
+ new ObjectId ( rebaseOpReport . id ) != stepInfo . Commit . Id ||
155
+ rebaseOpReport . type != stepInfo . Type )
156
+ {
157
+ // This is indicative of a program error - should never happen.
158
+ throw new LibGit2SharpException ( "Unexpected step info reported by running rebase step." ) ;
159
+ }
160
+ }
161
+
162
+ private static RebaseAction NextRebaseAction (
163
+ out RebaseStepInfo stepToApply ,
164
+ Repository repository ,
165
+ RebaseSafeHandle rebaseOperationHandle ,
166
+ bool isStarting )
167
+ {
168
+ RebaseAction action ;
169
+
170
+ // stepBeingApplied indicates the step that will be applied by by git_rebase_next.
171
+ // The current step does not get incremented until git_rebase_next (except on
172
+ // the initial step), but we want to report the step that will be applied.
173
+ long stepToApplyIndex = Proxy . git_rebase_operation_current ( rebaseOperationHandle ) ;
174
+ if ( ! isStarting )
175
+ {
176
+ stepToApplyIndex ++ ;
177
+ }
178
+
179
+ long totalStepCount = Proxy . git_rebase_operation_entrycount ( rebaseOperationHandle ) ;
180
+
181
+ if ( stepToApplyIndex == totalStepCount )
182
+ {
183
+ action = RebaseAction . Finish ;
184
+ stepToApply = null ;
185
+ }
186
+ else
187
+ {
188
+ action = RebaseAction . ApplyStep ;
189
+
190
+ GitRebaseOperation rebaseOp = Proxy . git_rebase_operation_byindex ( rebaseOperationHandle , stepToApplyIndex ) ;
191
+ ObjectId idOfCommitBeingRebased = new ObjectId ( rebaseOp . id ) ;
192
+ stepToApply = new RebaseStepInfo ( rebaseOp . type ,
193
+ repository . Lookup < Commit > ( idOfCommitBeingRebased ) ,
194
+ LaxUtf8NoCleanupMarshaler . FromNative ( rebaseOp . exec ) ,
195
+ stepToApplyIndex ,
196
+ totalStepCount ) ;
197
+ }
198
+
199
+ return action ;
200
+ }
163
201
}
164
202
}
0 commit comments