Skip to content

Commit c4e5ed4

Browse files
refactor(rebase): Allow RebaseCommand::Pick to apply multiple commits
This is just the basic data structure support for holding multiple commits. The actual implementation of applying multiple commits will come next.
1 parent a63d48d commit c4e5ed4

File tree

3 files changed

+85
-31
lines changed

3 files changed

+85
-31
lines changed

git-branchless-lib/src/core/rewrite/execute.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -558,11 +558,15 @@ mod in_memory {
558558

559559
RebaseCommand::Pick {
560560
original_commit_oid,
561-
commit_to_apply_oid,
561+
commits_to_apply_oids,
562562
} => {
563563
let current_commit = repo
564564
.find_commit_or_fail(current_oid)
565565
.wrap_err("Finding current commit")?;
566+
let commit_to_apply_oid = match commits_to_apply_oids.as_slice() {
567+
[commit_to_apply_oid] => commit_to_apply_oid,
568+
[..] => unimplemented!("Picking multiple commits"),
569+
};
566570
let commit_to_apply = repo
567571
.find_commit_or_fail(*commit_to_apply_oid)
568572
.wrap_err("Finding commit to apply")?;
@@ -1032,8 +1036,10 @@ mod on_disk {
10321036
if rebase_plan.commands.iter().any(|command| match command {
10331037
RebaseCommand::Pick {
10341038
original_commit_oid,
1035-
commit_to_apply_oid,
1036-
} => original_commit_oid != commit_to_apply_oid,
1039+
commits_to_apply_oids,
1040+
} => !commits_to_apply_oids
1041+
.iter()
1042+
.any(|oid| oid == original_commit_oid),
10371043
_ => false,
10381044
}) {
10391045
eyre::bail!("Not implemented: replacing commits in an on disk rebase");

git-branchless-lib/src/core/rewrite/plan.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,17 +52,22 @@ pub enum RebaseCommand {
5252
target: OidOrLabel,
5353
},
5454

55-
/// Apply the provided commit on top of the rebase head, and update the
55+
/// Apply the provided commits on top of the rebase head, and update the
5656
/// rebase head to point to the newly-applied commit.
5757
Pick {
5858
/// The original commit, which contains the relevant metadata such as
5959
/// the commit message.
6060
original_commit_oid: NonZeroOid,
6161

62-
/// The commit whose patch should be applied to the rebase head. This
63-
/// will be different from [`original_commit_oid`] when a commit is
64-
/// being replaced.
65-
commit_to_apply_oid: NonZeroOid,
62+
/// The commits whose patches should be applied to the rebase head.
63+
/// - This will be different from [`original_commit_oid`] when a commit
64+
/// is being replaced.
65+
/// - If this is a single commit, then the rebase will perform a normal
66+
/// `pick`.
67+
/// - If this is multiple commits, they will all be squashed into a
68+
/// single commit, reusing the metadata (message, author, timestamps,
69+
/// etc) from `original_commit_oid`.
70+
commits_to_apply_oids: Vec<NonZeroOid>,
6671
},
6772

6873
/// Merge two or more parent commits.
@@ -136,8 +141,11 @@ impl ToString for RebaseCommand {
136141
RebaseCommand::Reset { target } => format!("reset {target}"),
137142
RebaseCommand::Pick {
138143
original_commit_oid: _,
139-
commit_to_apply_oid: commit_oid,
140-
} => format!("pick {commit_oid}"),
144+
commits_to_apply_oids: commit_oids,
145+
} => match commit_oids.as_slice() {
146+
[commit_oid] => format!("pick {commit_oid}"),
147+
[..] => unimplemented!("Picking multiple commits"),
148+
},
141149
RebaseCommand::Merge {
142150
commit_oid,
143151
commits_to_merge,
@@ -837,7 +845,7 @@ impl<'a> RebasePlanBuilder<'a> {
837845
None => {
838846
acc.push(RebaseCommand::Pick {
839847
original_commit_oid,
840-
commit_to_apply_oid: original_commit_oid,
848+
commits_to_apply_oids: vec![original_commit_oid],
841849
});
842850
acc.push(RebaseCommand::DetectEmptyCommit {
843851
commit_oid: current_commit.get_oid(),
@@ -1109,8 +1117,12 @@ impl<'a> RebasePlanBuilder<'a> {
11091117
| RebaseCommand::DetectEmptyCommit { commit_oid: _ } => Vec::new(),
11101118
RebaseCommand::Pick {
11111119
original_commit_oid,
1112-
commit_to_apply_oid,
1113-
} => vec![*original_commit_oid, *commit_to_apply_oid],
1120+
commits_to_apply_oids,
1121+
} => {
1122+
let mut commit_oids = vec![*original_commit_oid];
1123+
commit_oids.extend(commits_to_apply_oids);
1124+
commit_oids
1125+
}
11141126
RebaseCommand::Merge {
11151127
commit_oid,
11161128
commits_to_merge: _,

git-branchless/tests/test_move.rs

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,18 @@ fn test_move_stick() -> eyre::Result<()> {
7171
},
7272
Pick {
7373
original_commit_oid: NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
74-
commit_to_apply_oid: NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
74+
commits_to_apply_oids: [
75+
NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
76+
],
7577
},
7678
DetectEmptyCommit {
7779
commit_oid: NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
7880
},
7981
Pick {
8082
original_commit_oid: NonZeroOid(355e173bf9c5d2efac2e451da0cdad3fb82b869a),
81-
commit_to_apply_oid: NonZeroOid(355e173bf9c5d2efac2e451da0cdad3fb82b869a),
83+
commits_to_apply_oids: [
84+
NonZeroOid(355e173bf9c5d2efac2e451da0cdad3fb82b869a),
85+
],
8286
},
8387
DetectEmptyCommit {
8488
commit_oid: NonZeroOid(355e173bf9c5d2efac2e451da0cdad3fb82b869a),
@@ -202,21 +206,27 @@ fn test_move_insert_stick() -> eyre::Result<()> {
202206
},
203207
Pick {
204208
original_commit_oid: NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
205-
commit_to_apply_oid: NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
209+
commits_to_apply_oids: [
210+
NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
211+
],
206212
},
207213
DetectEmptyCommit {
208214
commit_oid: NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
209215
},
210216
Pick {
211217
original_commit_oid: NonZeroOid(355e173bf9c5d2efac2e451da0cdad3fb82b869a),
212-
commit_to_apply_oid: NonZeroOid(355e173bf9c5d2efac2e451da0cdad3fb82b869a),
218+
commits_to_apply_oids: [
219+
NonZeroOid(355e173bf9c5d2efac2e451da0cdad3fb82b869a),
220+
],
213221
},
214222
DetectEmptyCommit {
215223
commit_oid: NonZeroOid(355e173bf9c5d2efac2e451da0cdad3fb82b869a),
216224
},
217225
Pick {
218226
original_commit_oid: NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
219-
commit_to_apply_oid: NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
227+
commits_to_apply_oids: [
228+
NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
229+
],
220230
},
221231
DetectEmptyCommit {
222232
commit_oid: NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
@@ -2280,14 +2290,18 @@ fn test_move_with_source_not_in_smartlog() -> eyre::Result<()> {
22802290
},
22812291
Pick {
22822292
original_commit_oid: NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
2283-
commit_to_apply_oid: NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
2293+
commits_to_apply_oids: [
2294+
NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
2295+
],
22842296
},
22852297
DetectEmptyCommit {
22862298
commit_oid: NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
22872299
},
22882300
Pick {
22892301
original_commit_oid: NonZeroOid(355e173bf9c5d2efac2e451da0cdad3fb82b869a),
2290-
commit_to_apply_oid: NonZeroOid(355e173bf9c5d2efac2e451da0cdad3fb82b869a),
2302+
commits_to_apply_oids: [
2303+
NonZeroOid(355e173bf9c5d2efac2e451da0cdad3fb82b869a),
2304+
],
22912305
},
22922306
DetectEmptyCommit {
22932307
commit_oid: NonZeroOid(355e173bf9c5d2efac2e451da0cdad3fb82b869a),
@@ -2388,7 +2402,9 @@ fn test_move_merge_conflict() -> eyre::Result<()> {
23882402
},
23892403
Pick {
23902404
original_commit_oid: NonZeroOid(e85d25c772a05b5c73ea8ec43881c12bbf588848),
2391-
commit_to_apply_oid: NonZeroOid(e85d25c772a05b5c73ea8ec43881c12bbf588848),
2405+
commits_to_apply_oids: [
2406+
NonZeroOid(e85d25c772a05b5c73ea8ec43881c12bbf588848),
2407+
],
23922408
},
23932409
DetectEmptyCommit {
23942410
commit_oid: NonZeroOid(e85d25c772a05b5c73ea8ec43881c12bbf588848),
@@ -2460,14 +2476,18 @@ fn test_move_base() -> eyre::Result<()> {
24602476
},
24612477
Pick {
24622478
original_commit_oid: NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
2463-
commit_to_apply_oid: NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
2479+
commits_to_apply_oids: [
2480+
NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
2481+
],
24642482
},
24652483
DetectEmptyCommit {
24662484
commit_oid: NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
24672485
},
24682486
Pick {
24692487
original_commit_oid: NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
2470-
commit_to_apply_oid: NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
2488+
commits_to_apply_oids: [
2489+
NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
2490+
],
24712491
},
24722492
DetectEmptyCommit {
24732493
commit_oid: NonZeroOid(70deb1e28791d8e7dd5a1f0c871a51b91282562f),
@@ -2596,7 +2616,9 @@ fn test_move_checkout_new_head() -> eyre::Result<()> {
25962616
},
25972617
Pick {
25982618
original_commit_oid: NonZeroOid(fe65c1fe15584744e649b2c79d4cf9b0d878f92e),
2599-
commit_to_apply_oid: NonZeroOid(fe65c1fe15584744e649b2c79d4cf9b0d878f92e),
2619+
commits_to_apply_oids: [
2620+
NonZeroOid(fe65c1fe15584744e649b2c79d4cf9b0d878f92e),
2621+
],
26002622
},
26012623
DetectEmptyCommit {
26022624
commit_oid: NonZeroOid(fe65c1fe15584744e649b2c79d4cf9b0d878f92e),
@@ -2670,7 +2692,9 @@ fn test_move_branch() -> eyre::Result<()> {
26702692
},
26712693
Pick {
26722694
original_commit_oid: NonZeroOid(98b9119d16974f372e76cb64a3b77c528fc0b18b),
2673-
commit_to_apply_oid: NonZeroOid(98b9119d16974f372e76cb64a3b77c528fc0b18b),
2695+
commits_to_apply_oids: [
2696+
NonZeroOid(98b9119d16974f372e76cb64a3b77c528fc0b18b),
2697+
],
26742698
},
26752699
DetectEmptyCommit {
26762700
commit_oid: NonZeroOid(98b9119d16974f372e76cb64a3b77c528fc0b18b),
@@ -2884,7 +2908,9 @@ fn test_move_in_memory_gc() -> eyre::Result<()> {
28842908
},
28852909
Pick {
28862910
original_commit_oid: NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
2887-
commit_to_apply_oid: NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
2911+
commits_to_apply_oids: [
2912+
NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
2913+
],
28882914
},
28892915
DetectEmptyCommit {
28902916
commit_oid: NonZeroOid(96d1c37a3d4363611c49f7e52186e189a04c531f),
@@ -3684,7 +3710,9 @@ fn test_move_merge_commit() -> eyre::Result<()> {
36843710
},
36853711
Pick {
36863712
original_commit_oid: NonZeroOid(fe65c1fe15584744e649b2c79d4cf9b0d878f92e),
3687-
commit_to_apply_oid: NonZeroOid(fe65c1fe15584744e649b2c79d4cf9b0d878f92e),
3713+
commits_to_apply_oids: [
3714+
NonZeroOid(fe65c1fe15584744e649b2c79d4cf9b0d878f92e),
3715+
],
36883716
},
36893717
DetectEmptyCommit {
36903718
commit_oid: NonZeroOid(fe65c1fe15584744e649b2c79d4cf9b0d878f92e),
@@ -4065,7 +4093,9 @@ fn test_move_merge_commit_issue_912() -> eyre::Result<()> {
40654093
},
40664094
Pick {
40674095
original_commit_oid: NonZeroOid(50eef922b99bc8a8829a1ded374231f9a025d28c),
4068-
commit_to_apply_oid: NonZeroOid(50eef922b99bc8a8829a1ded374231f9a025d28c),
4096+
commits_to_apply_oids: [
4097+
NonZeroOid(50eef922b99bc8a8829a1ded374231f9a025d28c),
4098+
],
40694099
},
40704100
DetectEmptyCommit {
40714101
commit_oid: NonZeroOid(50eef922b99bc8a8829a1ded374231f9a025d28c),
@@ -4075,7 +4105,9 @@ fn test_move_merge_commit_issue_912() -> eyre::Result<()> {
40754105
},
40764106
Pick {
40774107
original_commit_oid: NonZeroOid(00aa7adb4f38b8b1c04b062a1fdc897fcc6c471d),
4078-
commit_to_apply_oid: NonZeroOid(00aa7adb4f38b8b1c04b062a1fdc897fcc6c471d),
4108+
commits_to_apply_oids: [
4109+
NonZeroOid(00aa7adb4f38b8b1c04b062a1fdc897fcc6c471d),
4110+
],
40794111
},
40804112
DetectEmptyCommit {
40814113
commit_oid: NonZeroOid(00aa7adb4f38b8b1c04b062a1fdc897fcc6c471d),
@@ -4090,7 +4122,9 @@ fn test_move_merge_commit_issue_912() -> eyre::Result<()> {
40904122
},
40914123
Pick {
40924124
original_commit_oid: NonZeroOid(af1a4cee7c63ea7eba381967223d17a6386e5a4c),
4093-
commit_to_apply_oid: NonZeroOid(af1a4cee7c63ea7eba381967223d17a6386e5a4c),
4125+
commits_to_apply_oids: [
4126+
NonZeroOid(af1a4cee7c63ea7eba381967223d17a6386e5a4c),
4127+
],
40944128
},
40954129
DetectEmptyCommit {
40964130
commit_oid: NonZeroOid(af1a4cee7c63ea7eba381967223d17a6386e5a4c),
@@ -4113,7 +4147,9 @@ fn test_move_merge_commit_issue_912() -> eyre::Result<()> {
41134147
},
41144148
Pick {
41154149
original_commit_oid: NonZeroOid(7f5857ec34dab5bf7991da2512bf529789204413),
4116-
commit_to_apply_oid: NonZeroOid(7f5857ec34dab5bf7991da2512bf529789204413),
4150+
commits_to_apply_oids: [
4151+
NonZeroOid(7f5857ec34dab5bf7991da2512bf529789204413),
4152+
],
41174153
},
41184154
DetectEmptyCommit {
41194155
commit_oid: NonZeroOid(7f5857ec34dab5bf7991da2512bf529789204413),

0 commit comments

Comments
 (0)