Skip to content

Commit f51d556

Browse files
committed
Remove Merge Step in but-rebase to remove gitbutler-repo dependency.
There is no use of it yet and it doesn't look like it's needed since `Pick` can re-merge merge-commits. With the dependency gone, the new `but-rebase::cherry_pick` can be used in `gitbutler-repo` to assure all tests still work. From there certain crucial tests can be ported to `but-rebase` as cherry-pick tests.
1 parent 06ef8ef commit f51d556

File tree

8 files changed

+66
-416
lines changed

8 files changed

+66
-416
lines changed

Cargo.lock

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/but-rebase/Cargo.toml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@ gix = { workspace = true, features = ["revision", "merge"]}
1313
anyhow.workspace = true
1414
tracing.workspace = true
1515
but-core.workspace = true
16-
gitbutler-repo.workspace = true
1716
gitbutler-oxidize.workspace = true
1817
gitbutler-error.workspace = true
1918
bstr.workspace = true
20-
git2.workspace = true
2119
tempfile.workspace = true
2220
serde = { version = "1.0.217", features = ["derive"] }
2321
toml.workspace = true
@@ -26,6 +24,3 @@ toml.workspace = true
2624
but-testsupport.workspace = true
2725
insta = "1.42.1"
2826
but-core = { workspace = true, features = ["testing"] }
29-
# for stable hashes in `gitbuter-` crates while we use them.
30-
# TODO: remove once `gitbutler-repo` isn't needed anymore.
31-
gitbutler-commit = { workspace = true, features = ["testing"] }

crates/but-rebase/src/cherry_pick.rs

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,39 +33,13 @@ pub(crate) mod function {
3333
use serde::Serialize;
3434
use std::collections::HashSet;
3535
use std::path::PathBuf;
36-
use tracing::instrument;
3736

38-
/// Place `commits_to_rebase` onto `base` in-order, i.e. `base -> 0 -> 1 -> N`, so that that last
39-
/// commit in `commits_to_rebase` is the last commit to rebase.
40-
/// If `commits_to_rebase` is empty, `base` is returned unaltered.
37+
/// Place `commit_to_rebase` onto `base`.
4138
///
4239
/// `pick_mode` and `empty_commit` control how to deal with no-ops and epty commits.
40+
/// Returns the id of the cherry-picked commit.
4341
///
44-
/// Returns the id of the top-most, rebased commit.
45-
///
46-
/// Note that each rewritten commit will have headers injected, among which is a change id.
47-
#[instrument(level = tracing::Level::DEBUG, skip(repo, commits_to_rebase))]
48-
pub fn cherry_pick_many(
49-
repo: &gix::Repository,
50-
base: gix::ObjectId,
51-
commits_to_rebase: impl IntoIterator<Item = gix::ObjectId>,
52-
pick_mode: PickMode,
53-
empty_commit: EmptyCommit,
54-
) -> anyhow::Result<gix::ObjectId> {
55-
let mut cursor = but_core::Commit::from_id(base.attach(repo))?;
56-
for to_rebase_id in commits_to_rebase {
57-
let to_rebase = but_core::Commit::from_id(to_rebase_id.attach(repo))?;
58-
cursor = but_core::Commit::from_id(cherry_pick_one_inner(
59-
cursor,
60-
to_rebase,
61-
pick_mode,
62-
empty_commit,
63-
)?)?;
64-
}
65-
Ok(cursor.id.detach())
66-
}
67-
68-
/// Like [`cherry_pick_many()`], but only handles a single `commit_to_rebase` onto `base`.
42+
/// Note that the rewritten commit will have headers injected, among which is a change id.
6943
pub fn cherry_pick_one(
7044
repo: &gix::Repository,
7145
base: gix::ObjectId,

crates/but-rebase/src/lib.rs

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55

66
use crate::commit::CommitterMode;
77
use anyhow::{anyhow, bail, Context, Ok, Result};
8-
use bstr::{BString, ByteSlice};
8+
use bstr::BString;
99
use gix::objs::Exists;
1010
use gix::prelude::ObjectIdExt;
11+
use tracing::instrument;
1112

1213
/// Types for use with cherry-picking
1314
pub mod cherry_pick;
1415
use crate::cherry_pick::{EmptyCommit, PickMode};
15-
pub use cherry_pick::function::{cherry_pick_many, cherry_pick_one};
16+
pub use cherry_pick::function::cherry_pick_one;
1617

1718
/// Utilities to create commits (and deal with signing)
1819
pub mod commit;
@@ -32,14 +33,6 @@ pub enum RebaseStep {
3233
// for multi-branch rebasing. It would keep the previous cursor, to allow the last
3334
// branch to contain a pick of the merge commit on top, which it can then correctly re-merge.
3435
},
35-
/// Merge an existing commit and it's parents producing a new merge commit.
36-
// TODO: figure out what this is used for, and add tests for it/port it over.
37-
Merge {
38-
/// Id of an already existing commit
39-
commit_id: gix::ObjectId,
40-
/// Message to use for newly produced commit
41-
new_message: BString,
42-
},
4336
/// Squashes an existing commit into the one in the first `Pick` or `Merge` RebaseStep that precedes it.
4437
///
4538
/// If there are neither `Pick` nor `Merge` steps preceding this operation (e.g. only `Reference` steps), the execution will halt with an error.
@@ -63,7 +56,6 @@ impl RebaseStep {
6356
fn commit_id(&self) -> Option<&gix::oid> {
6457
match self {
6558
RebaseStep::Pick { commit_id, .. }
66-
| RebaseStep::Merge { commit_id, .. }
6759
| RebaseStep::SquashIntoPreceding { commit_id, .. } => Some(commit_id),
6860
RebaseStep::Reference { .. } => None,
6961
}
@@ -145,12 +137,17 @@ impl<'repo> Rebase<'repo> {
145137
if self.steps.is_empty() {
146138
return Err(anyhow!("No rebase steps provided"));
147139
}
140+
let pick_mode = if self.rebase_noops {
141+
PickMode::Unconditionally
142+
} else {
143+
PickMode::SkipIfNoop
144+
};
148145
rebase(
149146
self.repo,
150147
self.base,
151148
self.base_substitute,
152149
std::mem::take(&mut self.steps),
153-
self.rebase_noops,
150+
pick_mode,
154151
)
155152
}
156153
}
@@ -177,12 +174,6 @@ impl Rebase<'_> {
177174
} => {
178175
self.assure_unique_step_and_existing_non_base(commit_id, "Picked")?;
179176
}
180-
RebaseStep::Merge {
181-
commit_id,
182-
new_message: _,
183-
} => {
184-
self.assure_unique_step_and_existing_non_base(commit_id, "Merge")?;
185-
}
186177
RebaseStep::SquashIntoPreceding {
187178
commit_id,
188179
new_message: _,
@@ -222,12 +213,13 @@ impl Rebase<'_> {
222213
}
223214
}
224215

216+
#[instrument(level = tracing::Level::DEBUG, skip(repo))]
225217
fn rebase(
226218
repo: &gix::Repository,
227219
base: Option<gix::ObjectId>,
228220
base_substitute: Option<gix::ObjectId>,
229221
steps: Vec<RebaseStep>,
230-
rebase_noops: bool,
222+
pick_mode: PickMode,
231223
) -> Result<RebaseOutput> {
232224
let (mut references, mut commit_mapping) = (
233225
vec![],
@@ -270,11 +262,6 @@ fn rebase(
270262
} else {
271263
match &mut cursor {
272264
Some(cursor) => {
273-
let pick_mode = if rebase_noops {
274-
PickMode::Unconditionally
275-
} else {
276-
PickMode::SkipIfNoop
277-
};
278265
let mut new_commit = cherry_pick_one(
279266
repo,
280267
*cursor,
@@ -302,21 +289,6 @@ fn rebase(
302289
}
303290
last_seen_commit = Some(commit_id);
304291
}
305-
RebaseStep::Merge {
306-
commit_id,
307-
new_message,
308-
} => {
309-
let Some(cursor) = &mut cursor else {
310-
bail!("Can't merge without history present yet");
311-
};
312-
last_seen_commit = Some(commit_id);
313-
*cursor = gitbutler_repo::rebase::merge_commits(
314-
repo,
315-
*cursor,
316-
commit_id,
317-
&new_message.to_str_lossy(),
318-
)?;
319-
}
320292
RebaseStep::SquashIntoPreceding {
321293
commit_id,
322294
new_message,

crates/but-rebase/tests/rebase/error_handling.rs

Lines changed: 0 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,6 @@ fn non_existing_commit_in_pick_step() -> anyhow::Result<()> {
3333
Ok(())
3434
}
3535

36-
#[test]
37-
fn non_existing_commit_in_merge_step() -> anyhow::Result<()> {
38-
let (repo, commits) = four_commits()?;
39-
let mut builder = Rebase::new(&repo, commits.base, None)?;
40-
let result = builder.steps([RebaseStep::Merge {
41-
commit_id: non_existing_commit(),
42-
new_message: "merge commit".into(),
43-
}]);
44-
assert_eq!(
45-
result.unwrap_err().to_string(),
46-
"An object with id eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee could not be found"
47-
);
48-
Ok(())
49-
}
50-
5136
#[test]
5237
fn non_existing_commit_in_fixup_step() -> anyhow::Result<()> {
5338
let (repo, commits) = four_commits()?;
@@ -78,21 +63,6 @@ fn using_base_in_pick_step() -> anyhow::Result<()> {
7863
Ok(())
7964
}
8065

81-
#[test]
82-
fn using_base_in_merge_step() -> anyhow::Result<()> {
83-
let (repo, commits) = four_commits()?;
84-
let mut builder = Rebase::new(&repo, commits.base, None)?;
85-
let result = builder.steps([RebaseStep::Merge {
86-
commit_id: commits.base,
87-
new_message: "merge commit".into(),
88-
}]);
89-
assert_eq!(
90-
result.unwrap_err().to_string(),
91-
"Merge commit cannot be the base commit"
92-
);
93-
Ok(())
94-
}
95-
9666
#[test]
9767
fn using_base_in_fixup_step() -> anyhow::Result<()> {
9868
let (repo, commits) = four_commits()?;
@@ -129,27 +99,6 @@ fn using_picked_commit_in_a_pick_step() -> anyhow::Result<()> {
12999
Ok(())
130100
}
131101

132-
#[test]
133-
fn using_merged_commit_in_a_pick_step() -> anyhow::Result<()> {
134-
let (repo, commits) = four_commits()?;
135-
let mut builder = Rebase::new(&repo, commits.base, None)?;
136-
let result = builder.steps([
137-
RebaseStep::Merge {
138-
commit_id: commits.a,
139-
new_message: "merge commit".into(),
140-
},
141-
RebaseStep::Pick {
142-
commit_id: commits.a,
143-
new_message: None,
144-
},
145-
]);
146-
assert_eq!(
147-
result.unwrap_err().to_string(),
148-
"Picked commit already exists in a previous step"
149-
);
150-
Ok(())
151-
}
152-
153102
#[test]
154103
fn using_fixup_commit_in_a_pick_step() -> anyhow::Result<()> {
155104
let (repo, commits) = four_commits()?;
@@ -175,73 +124,6 @@ fn using_fixup_commit_in_a_pick_step() -> anyhow::Result<()> {
175124
Ok(())
176125
}
177126

178-
#[test]
179-
fn using_picked_commit_in_a_merge_step() -> anyhow::Result<()> {
180-
let (repo, commits) = four_commits()?;
181-
let mut builder = Rebase::new(&repo, commits.base, None)?;
182-
let result = builder.steps([
183-
RebaseStep::Pick {
184-
commit_id: commits.a,
185-
new_message: None,
186-
},
187-
RebaseStep::Merge {
188-
commit_id: commits.a,
189-
new_message: "merge commit".into(),
190-
},
191-
]);
192-
assert_eq!(
193-
result.unwrap_err().to_string(),
194-
"Picked commit already exists in a previous step"
195-
);
196-
Ok(())
197-
}
198-
199-
#[test]
200-
fn using_merged_commit_in_a_merge_step() -> anyhow::Result<()> {
201-
let (repo, commits) = four_commits()?;
202-
let mut builder = Rebase::new(&repo, commits.base, None)?;
203-
let result = builder.steps([
204-
RebaseStep::Merge {
205-
commit_id: commits.a,
206-
new_message: "merge commit".into(),
207-
},
208-
RebaseStep::Merge {
209-
commit_id: commits.a,
210-
new_message: "merge commit".into(),
211-
},
212-
]);
213-
assert_eq!(
214-
result.unwrap_err().to_string(),
215-
"Picked commit already exists in a previous step"
216-
);
217-
Ok(())
218-
}
219-
220-
#[test]
221-
fn using_fixup_commit_in_a_merge_step() -> anyhow::Result<()> {
222-
let (repo, commits) = four_commits()?;
223-
let mut builder = Rebase::new(&repo, commits.base, None)?;
224-
let result = builder.steps([
225-
RebaseStep::Pick {
226-
commit_id: commits.a,
227-
new_message: None,
228-
},
229-
RebaseStep::SquashIntoPreceding {
230-
commit_id: commits.b,
231-
new_message: None,
232-
},
233-
RebaseStep::Merge {
234-
commit_id: commits.b,
235-
new_message: "merge commit".into(),
236-
},
237-
]);
238-
assert_eq!(
239-
result.unwrap_err().to_string(),
240-
"Picked commit already exists in a previous step"
241-
);
242-
Ok(())
243-
}
244-
245127
#[test]
246128
fn using_picked_commit_in_a_fixup_step() -> anyhow::Result<()> {
247129
let (repo, commits) = four_commits()?;
@@ -263,27 +145,6 @@ fn using_picked_commit_in_a_fixup_step() -> anyhow::Result<()> {
263145
Ok(())
264146
}
265147

266-
#[test]
267-
fn using_merged_commit_in_a_fixup_step() -> anyhow::Result<()> {
268-
let (repo, commits) = four_commits()?;
269-
let mut builder = Rebase::new(&repo, commits.base, None)?;
270-
let result = builder.steps([
271-
RebaseStep::Merge {
272-
commit_id: commits.a,
273-
new_message: "merge commit".into(),
274-
},
275-
RebaseStep::SquashIntoPreceding {
276-
commit_id: commits.a,
277-
new_message: None,
278-
},
279-
]);
280-
assert_eq!(
281-
result.unwrap_err().to_string(),
282-
"Picked commit already exists in a previous step"
283-
);
284-
Ok(())
285-
}
286-
287148
#[test]
288149
fn using_fixup_commit_in_a_fixup_step() -> anyhow::Result<()> {
289150
let (repo, commits) = four_commits()?;

0 commit comments

Comments
 (0)