-
-
Notifications
You must be signed in to change notification settings - Fork 315
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
That way, Git can indicate what we need to match.
- Loading branch information
Showing
10 changed files
with
230 additions
and
16 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/// The error returned by [commit()](crate::commit()). | ||
#[derive(Debug, thiserror::Error)] | ||
#[allow(missing_docs)] | ||
pub enum Error {} | ||
|
||
pub(super) mod function { | ||
use crate::commit::Error; | ||
|
||
/// Like [`tree()`](crate::tree()), but it takes only two commits to automatically compute the | ||
/// merge-bases among them. | ||
pub fn commit(our_commit: &gix_hash::oid, their_commit: &gix_hash::oid) -> Result<(), Error> { | ||
todo!() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/// The error returned by [tree()](crate::tree()). | ||
#[derive(Debug, thiserror::Error)] | ||
#[allow(missing_docs)] | ||
pub enum Error {} | ||
|
||
/// The outcome produced by [tree()](crate::tree()). | ||
pub struct Outcome<'a> { | ||
/// The ready-made (but unwritten) tree if `conflicts` is empty, or the best-possible tree when facing `conflicts`. | ||
/// | ||
/// The tree may contain blobs with conflict markers, and will be missing directories or files that were conflicting | ||
/// without a resolution strategy. | ||
tree: gix_object::tree::Editor<'a>, | ||
/// The set of conflicts we encountered. Can be empty to indicate there was no conflict. | ||
conflicts: Vec<Conflict>, | ||
} | ||
|
||
/// A description of a conflict (i.e. merge issue without an auto-resolution) as seen during a [tree-merge](crate::tree()). | ||
pub struct Conflict; | ||
|
||
pub(super) mod function { | ||
use crate::tree::{Error, Outcome}; | ||
|
||
/// Perform a merge between `our_tree` and `their_tree`, using `base_trees` as merge-base. | ||
/// Note that if `base_trees` is empty, an empty tree is assumed to be the merge base. | ||
/// If there are more than one tree `base_trees`, it will merge them into one with the specialty that binary | ||
/// files will always be `our` side without conflicting. However, any other conflict will be fatal. | ||
/// | ||
/// `objects` provides access to trees when diffing them. | ||
pub fn tree<'a>( | ||
base_trees: &[gix_object::Object], | ||
our_tree: &gix_hash::oid, | ||
their_tree: &gix_hash::oid, | ||
objects: &'a dyn gix_object::FindExt, | ||
) -> Result<Outcome<'a>, Error> { | ||
todo!() | ||
} | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#!/usr/bin/env bash | ||
set -eu -o pipefail | ||
|
||
function tick () { | ||
if test -z "${tick+set}" | ||
then | ||
tick=1112911993 | ||
else | ||
tick=$(($tick + 60)) | ||
fi | ||
GIT_COMMITTER_DATE="$tick -0700" | ||
GIT_AUTHOR_DATE="$tick -0700" | ||
export GIT_COMMITTER_DATE GIT_AUTHOR_DATE | ||
} | ||
|
||
function write_lines () { | ||
printf "%s\n" "$@" | ||
} | ||
|
||
function baseline () ( | ||
local dir=${1:?the directory to enter} | ||
local output_name=${2:?the basename of the output of the merge} | ||
local our_committish=${3:?our side from which a commit can be derived} | ||
local their_committish=${4:?Their side from which a commit can be derived} | ||
|
||
cd "$dir" | ||
local our_commit_id | ||
local their_commit_id | ||
|
||
our_commit_id="$(git rev-parse "$our_committish")" | ||
their_commit_id="$(git rev-parse "$their_committish")" | ||
|
||
local merge_info="${output_name}.merge-info" | ||
git merge-tree -z --write-tree "$our_commit_id" "$their_commit_id" > "$merge_info" || : | ||
echo "$dir" "$our_commit_id" "$their_commit_id" "$merge_info" >> ../baseline.cases | ||
) | ||
|
||
git init simple | ||
(cd simple | ||
rm -Rf .git/hooks | ||
write_lines 1 2 3 4 5 >numbers | ||
echo hello >greeting | ||
echo foo >whatever | ||
git add numbers greeting whatever | ||
tick | ||
git commit -m initial | ||
|
||
git branch side1 | ||
git branch side2 | ||
git branch side3 | ||
git branch side4 | ||
|
||
git checkout side1 | ||
write_lines 1 2 3 4 5 6 >numbers | ||
echo hi >greeting | ||
echo bar >whatever | ||
git add numbers greeting whatever | ||
tick | ||
git commit -m modify-stuff | ||
|
||
git checkout side2 | ||
write_lines 0 1 2 3 4 5 >numbers | ||
echo yo >greeting | ||
git rm whatever | ||
mkdir whatever | ||
>whatever/empty | ||
git add numbers greeting whatever/empty | ||
tick | ||
git commit -m other-modifications | ||
|
||
git checkout side3 | ||
git mv numbers sequence | ||
tick | ||
git commit -m rename-numbers | ||
|
||
git checkout side4 | ||
write_lines 0 1 2 3 4 5 >numbers | ||
echo yo >greeting | ||
git add numbers greeting | ||
tick | ||
git commit -m other-content-modifications | ||
|
||
git switch --orphan unrelated | ||
>something-else | ||
git add something-else | ||
tick | ||
git commit -m first-commit | ||
) | ||
|
||
baseline simple without-conflict side1 side3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
extern crate core; | ||
|
||
#[cfg(feature = "blob")] | ||
mod blob; | ||
mod tree; | ||
|
||
pub use gix_testtools::Result; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#[test] | ||
fn run_baseline() -> crate::Result { | ||
let root = gix_testtools::scripted_fixture_read_only("tree-baseline.sh")?; | ||
let cases = std::fs::read_to_string(root.join("baseline.cases"))?; | ||
for case in baseline::Expectations::new(&root, &cases) {} | ||
|
||
Ok(()) | ||
} | ||
|
||
mod baseline { | ||
use std::path::Path; | ||
|
||
pub struct Conflict; | ||
|
||
pub struct Expectation { | ||
pub odb: gix_odb::Handle, | ||
pub our_commit_id: gix_hash::ObjectId, | ||
pub their_commit_id: gix_hash::ObjectId, | ||
pub merge_info: Result<gix_hash::ObjectId, Conflict>, | ||
} | ||
|
||
pub struct Expectations<'a> { | ||
root: &'a Path, | ||
lines: std::str::Lines<'a>, | ||
} | ||
|
||
impl<'a> Expectations<'a> { | ||
pub fn new(root: &'a Path, cases: &'a str) -> Self { | ||
Expectations { | ||
root, | ||
lines: cases.lines(), | ||
} | ||
} | ||
} | ||
|
||
impl Iterator for Expectations<'_> { | ||
type Item = Expectation; | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
let line = self.lines.next()?; | ||
let mut tokens = line.split(' '); | ||
let (Some(subdir), Some(our_commit_id), Some(their_commit_id), Some(merge_info_filename)) = | ||
(tokens.next(), tokens.next(), tokens.next(), tokens.next()) | ||
else { | ||
unreachable!("invalid line: {line:?}") | ||
}; | ||
assert_eq!(tokens.next(), None, "unexpected trailing tokens in line {line:?}"); | ||
|
||
let subdir = self.root.join(subdir); | ||
let objects = gix_odb::at(subdir.join(".git/objects")).expect("object dir exists"); | ||
let our_commit_id = gix_hash::ObjectId::from_hex(our_commit_id.as_bytes()).unwrap(); | ||
let their_commit_id = gix_hash::ObjectId::from_hex(their_commit_id.as_bytes()).unwrap(); | ||
let merge_info = parse_merge_info(std::fs::read_to_string(subdir.join(merge_info_filename)).unwrap()); | ||
Some(Expectation { | ||
odb: objects, | ||
our_commit_id, | ||
their_commit_id, | ||
merge_info, | ||
}) | ||
} | ||
} | ||
|
||
fn parse_merge_info(content: String) -> Result<gix_hash::ObjectId, Conflict> { | ||
let mut lines = content.split('\0').filter(|t| !t.is_empty()); | ||
let tree_id = gix_hash::ObjectId::from_hex(lines.next().unwrap().as_bytes()).unwrap(); | ||
assert_eq!(lines.next(), None, "TODO: implement multi-line answer"); | ||
Ok(tree_id) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters