@@ -38,6 +38,7 @@ use tracing::instrument;
38
38
/// What should `split` do with the extracted changes?
39
39
pub enum SplitMode {
40
40
DetachAfter ,
41
+ Discard ,
41
42
InsertAfter ,
42
43
}
43
44
@@ -128,12 +129,14 @@ pub fn split(
128
129
let ( parent_tree, mut remainder_tree) = match ( & split_mode, parent_commits. as_slice ( ) ) {
129
130
// split the commit by removing the changes from the target, and then
130
131
// cherry picking the orignal target as the "extracted" commit
131
- ( SplitMode :: InsertAfter , [ only_parent] ) | ( SplitMode :: DetachAfter , [ only_parent] ) => {
132
+ ( SplitMode :: InsertAfter , [ only_parent] )
133
+ | ( SplitMode :: Discard , [ only_parent] )
134
+ | ( SplitMode :: DetachAfter , [ only_parent] ) => {
132
135
( only_parent. get_tree ( ) ?, target_commit. get_tree ( ) ?)
133
136
}
134
137
135
138
// no parent: use an empty tree for comparison
136
- ( SplitMode :: InsertAfter , [ ] ) | ( SplitMode :: DetachAfter , [ ] ) => {
139
+ ( SplitMode :: InsertAfter , [ ] ) | ( SplitMode :: Discard , [ ] ) | ( SplitMode :: DetachAfter , [ ] ) => {
137
140
( make_empty_tree ( & repo) ?, target_commit. get_tree ( ) ?)
138
141
}
139
142
@@ -218,9 +221,9 @@ pub fn split(
218
221
let target_entry = target_tree. get_path ( path) ?;
219
222
let temp_tree_oid = match ( parent_entry, target_entry, & split_mode) {
220
223
// added => remove from remainder commit
221
- ( None , Some ( _) , SplitMode :: InsertAfter ) | ( None , Some ( _ ) , SplitMode :: DetachAfter ) => {
222
- remainder_tree . remove ( & repo , path ) ?
223
- }
224
+ ( None , Some ( _) , SplitMode :: InsertAfter )
225
+ | ( None , Some ( _ ) , SplitMode :: DetachAfter )
226
+ | ( None , Some ( _ ) , SplitMode :: Discard ) => remainder_tree . remove ( & repo , path ) ? ,
224
227
225
228
// deleted or modified => replace w/ parent content in split commit
226
229
( Some ( parent_entry) , _, _) => {
@@ -280,6 +283,7 @@ pub fn split(
280
283
} ] ) ?;
281
284
282
285
let extracted_commit_oid = match split_mode {
286
+ SplitMode :: Discard => None ,
283
287
SplitMode :: InsertAfter | SplitMode :: DetachAfter => {
284
288
let extracted_tree = repo. cherry_pick_fast (
285
289
& target_commit,
@@ -354,6 +358,7 @@ pub fn split(
354
358
struct CleanUp {
355
359
checkout_target : Option < CheckoutTarget > ,
356
360
rewritten_oids : Vec < ( NonZeroOid , MaybeZeroOid ) > ,
361
+ reset_index : bool ,
357
362
}
358
363
359
364
let cleanup = match ( target_state, & split_mode, extracted_commit_oid) {
@@ -363,26 +368,36 @@ pub fn split(
363
368
CleanUp {
364
369
checkout_target : None ,
365
370
rewritten_oids : vec ! [ ( target_oid, MaybeZeroOid :: NonZero ( extracted_commit_oid) ) ] ,
371
+ reset_index : false ,
366
372
}
367
373
}
368
374
375
+ ( TargetState :: CurrentBranch , SplitMode :: Discard , None ) => CleanUp {
376
+ checkout_target : None ,
377
+ rewritten_oids : vec ! [ ( target_oid, MaybeZeroOid :: NonZero ( remainder_commit_oid) ) ] ,
378
+ reset_index : true ,
379
+ } ,
380
+
369
381
// commit to split checked out as detached HEAD, don't extend any
370
382
// branches, but explicitly check out the newly split commit
371
383
( TargetState :: DetachedHead , _, _) => CleanUp {
372
384
checkout_target : Some ( CheckoutTarget :: Oid ( remainder_commit_oid) ) ,
373
385
rewritten_oids : vec ! [ ( target_oid, MaybeZeroOid :: NonZero ( remainder_commit_oid) ) ] ,
386
+ reset_index : false ,
374
387
} ,
375
388
376
389
// some other commit or branch was checked out, default behavior is fine
377
- ( TargetState :: CurrentBranch , _ , _ ) | ( TargetState :: Other , _, _) => CleanUp {
390
+ ( TargetState :: CurrentBranch | TargetState :: Other , _, _) => CleanUp {
378
391
checkout_target : None ,
379
392
rewritten_oids : vec ! [ ( target_oid, MaybeZeroOid :: NonZero ( remainder_commit_oid) ) ] ,
393
+ reset_index : false ,
380
394
} ,
381
395
} ;
382
396
383
397
let CleanUp {
384
398
checkout_target,
385
399
rewritten_oids,
400
+ reset_index,
386
401
} = cleanup;
387
402
388
403
move_branches (
@@ -410,6 +425,11 @@ pub fn split(
410
425
) ?) ;
411
426
}
412
427
428
+ if reset_index {
429
+ let mut index = repo. get_index ( ) ?;
430
+ index. update_from_tree ( & remainder_tree) ?;
431
+ }
432
+
413
433
let mut builder = RebasePlanBuilder :: new ( & dag, permissions) ;
414
434
let children = dag. query_children ( CommitSet :: from ( target_oid) ) ?;
415
435
for child in dag. commit_set_to_vec ( & children) ? {
0 commit comments