Skip to content

Commit a82f3f2

Browse files
committed
feat: add --tree-favor to gix merge tree|commit.
With it one can decide which side to favor in case of irreconcilable tree-conflicts.
1 parent 382aff9 commit a82f3f2

File tree

4 files changed

+66
-30
lines changed

4 files changed

+66
-30
lines changed

Diff for: gitoxide-core/src/repository/merge/commit.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub fn commit(
1717
Options {
1818
format,
1919
file_favor,
20+
tree_favor,
2021
in_memory,
2122
debug,
2223
}: Options,
@@ -31,7 +32,10 @@ pub fn commit(
3132
let (ours_ref, ours_id) = refname_and_commit(&repo, ours)?;
3233
let (theirs_ref, theirs_id) = refname_and_commit(&repo, theirs)?;
3334

34-
let options = repo.tree_merge_options()?.with_file_favor(file_favor);
35+
let options = repo
36+
.tree_merge_options()?
37+
.with_file_favor(file_favor)
38+
.with_tree_favor(tree_favor);
3539
let ours_id_str = ours_id.to_string();
3640
let theirs_id_str = theirs_id.to_string();
3741
let labels = gix::merge::blob::builtin_driver::text::Labels {

Diff for: gitoxide-core/src/repository/merge/tree.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::OutputFormat;
33
pub struct Options {
44
pub format: OutputFormat,
55
pub file_favor: Option<gix::merge::tree::FileFavor>,
6+
pub tree_favor: Option<gix::merge::tree::TreeFavor>,
67
pub in_memory: bool,
78
pub debug: bool,
89
}
@@ -29,6 +30,7 @@ pub(super) mod function {
2930
Options {
3031
format,
3132
file_favor,
33+
tree_favor,
3234
in_memory,
3335
debug,
3436
}: Options,
@@ -44,7 +46,10 @@ pub(super) mod function {
4446
let (ours_ref, ours_id) = refname_and_tree(&repo, ours)?;
4547
let (theirs_ref, theirs_id) = refname_and_tree(&repo, theirs)?;
4648

47-
let options = repo.tree_merge_options()?.with_file_favor(file_favor);
49+
let options = repo
50+
.tree_merge_options()?
51+
.with_file_favor(file_favor)
52+
.with_tree_favor(tree_favor);
4853
let base_id_str = base_id.to_string();
4954
let ours_id_str = ours_id.to_string();
5055
let theirs_id_str = theirs_id.to_string();

Diff for: src/plumbing/main.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,13 @@ pub fn main() -> Result<()> {
172172
},
173173
),
174174
merge::SubCommands::Tree {
175-
in_memory,
176-
file_favor,
177-
debug,
175+
opts:
176+
merge::SharedOptions {
177+
in_memory,
178+
file_favor,
179+
tree_favor,
180+
debug,
181+
},
178182
ours,
179183
base,
180184
theirs,
@@ -197,15 +201,20 @@ pub fn main() -> Result<()> {
197201
format,
198202
file_favor: file_favor.map(Into::into),
199203
in_memory,
204+
tree_favor: tree_favor.map(Into::into),
200205
debug,
201206
},
202207
)
203208
},
204209
),
205210
merge::SubCommands::Commit {
206-
in_memory,
207-
file_favor,
208-
debug,
211+
opts:
212+
merge::SharedOptions {
213+
in_memory,
214+
file_favor,
215+
tree_favor,
216+
debug,
217+
},
209218
ours,
210219
theirs,
211220
} => prepare_and_run(
@@ -225,6 +234,7 @@ pub fn main() -> Result<()> {
225234
core::repository::merge::tree::Options {
226235
format,
227236
file_favor: file_favor.map(Into::into),
237+
tree_favor: tree_favor.map(Into::into),
228238
in_memory,
229239
debug,
230240
},

Diff for: src/plumbing/options/mod.rs

+39-22
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,14 @@ pub mod merge {
375375
Theirs,
376376
}
377377

378+
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, clap::ValueEnum)]
379+
pub enum TreeFavor {
380+
/// Use only the previous tree entry in case of conflict.
381+
Ancestor,
382+
/// Use only ours tree entry in case of conflict.
383+
Ours,
384+
}
385+
378386
impl From<FileFavor> for gix::merge::tree::FileFavor {
379387
fn from(value: FileFavor) -> Self {
380388
match value {
@@ -384,6 +392,33 @@ pub mod merge {
384392
}
385393
}
386394

395+
impl From<TreeFavor> for gix::merge::tree::TreeFavor {
396+
fn from(value: TreeFavor) -> Self {
397+
match value {
398+
TreeFavor::Ancestor => gix::merge::tree::TreeFavor::Ancestor,
399+
TreeFavor::Ours => gix::merge::tree::TreeFavor::Ours,
400+
}
401+
}
402+
}
403+
404+
#[derive(Debug, clap::Parser)]
405+
pub struct SharedOptions {
406+
/// Keep all objects to be written in memory to avoid any disk IO.
407+
///
408+
/// Note that the resulting tree won't be available or inspectable.
409+
#[clap(long, short = 'm')]
410+
pub in_memory: bool,
411+
/// Decide how to resolve content conflicts in files. If unset, write conflict markers and fail.
412+
#[clap(long, short = 'f')]
413+
pub file_favor: Option<FileFavor>,
414+
/// Decide how to resolve conflicts in trees, i.e. modification/deletion. If unset, try to preserve both states and fail.
415+
#[clap(long, short = 't')]
416+
pub tree_favor: Option<TreeFavor>,
417+
/// Print additional information about conflicts for debugging.
418+
#[clap(long, short = 'd')]
419+
pub debug: bool,
420+
}
421+
387422
#[derive(Debug, clap::Parser)]
388423
#[command(about = "perform merges of various kinds")]
389424
pub struct Platform {
@@ -412,17 +447,8 @@ pub mod merge {
412447

413448
/// Merge a tree by specifying ours, base and theirs, writing it to the object database.
414449
Tree {
415-
/// Keep all objects to be written in memory to avoid any disk IO.
416-
///
417-
/// Note that the resulting tree won't be available or inspectable.
418-
#[clap(long, short = 'm')]
419-
in_memory: bool,
420-
/// Decide how to resolve content conflicts in files. If unset, write conflict markers and fail.
421-
#[clap(long, short = 'f')]
422-
file_favor: Option<FileFavor>,
423-
/// Print additional information about conflicts for debugging.
424-
#[clap(long, short = 'd')]
425-
debug: bool,
450+
#[clap(flatten)]
451+
opts: SharedOptions,
426452

427453
/// A revspec to our treeish.
428454
#[clap(value_name = "OURS", value_parser = crate::shared::AsBString)]
@@ -436,17 +462,8 @@ pub mod merge {
436462
},
437463
/// Merge a commits by specifying ours, and theirs, writing the tree to the object database.
438464
Commit {
439-
/// Keep all objects to be written in memory to avoid any disk IO.
440-
///
441-
/// Note that the resulting tree won't be available or inspectable.
442-
#[clap(long, short = 'm')]
443-
in_memory: bool,
444-
/// Decide how to resolve content conflicts in files. If unset, write conflict markers and fail.
445-
#[clap(long, short = 'f')]
446-
file_favor: Option<FileFavor>,
447-
/// Print additional information about conflicts for debugging.
448-
#[clap(long, short = 'd')]
449-
debug: bool,
465+
#[clap(flatten)]
466+
opts: SharedOptions,
450467

451468
/// A revspec to our committish.
452469
#[clap(value_name = "OURS", value_parser = crate::shared::AsBString)]

0 commit comments

Comments
 (0)