Skip to content

Commit cfea72d

Browse files
author
Stephan Dilly
committed
rebase returns generated commit + unittest
1 parent b70ea92 commit cfea72d

File tree

2 files changed

+69
-11
lines changed

2 files changed

+69
-11
lines changed

asyncgit/src/sync/merge.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,15 @@ pub fn merge_branch(repo_path: &str, branch: &str) -> Result<()> {
5454
}
5555

5656
///
57-
pub fn rebase_branch(repo_path: &str, branch: &str) -> Result<()> {
57+
pub fn rebase_branch(
58+
repo_path: &str,
59+
branch: &str,
60+
) -> Result<CommitId> {
5861
scope_time!("rebase_branch");
5962

6063
let repo = utils::repo(repo_path)?;
6164

62-
rebase_branch_repo(&repo, branch)?;
63-
64-
Ok(())
65+
rebase_branch_repo(&repo, branch)
6566
}
6667

6768
///
@@ -92,15 +93,13 @@ pub fn merge_branch_repo(
9293
pub fn rebase_branch_repo(
9394
repo: &Repository,
9495
branch_name: &str,
95-
) -> Result<()> {
96+
) -> Result<CommitId> {
9697
let branch = repo.find_branch(branch_name, BranchType::Local)?;
9798

9899
let annotated =
99100
repo.reference_to_annotated_commit(&branch.into_reference())?;
100101

101-
conflict_free_rebase(repo, &annotated)?;
102-
103-
Ok(())
102+
conflict_free_rebase(repo, &annotated)
104103
}
105104

106105
///

asyncgit/src/sync/rebase.rs

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
use crate::error::{Error, Result};
22

3+
use super::CommitId;
4+
35
/// rebase attempt which aborts and undo's rebase if any conflict appears
46
pub fn conflict_free_rebase(
57
repo: &git2::Repository,
68
commit: &git2::AnnotatedCommit,
7-
) -> Result<()> {
9+
) -> Result<CommitId> {
810
let mut rebase = repo.rebase(None, Some(commit), None, None)?;
911
let signature =
1012
crate::sync::commit::signature_allow_undefined_name(repo)?;
13+
let mut last_commit = None;
1114
while let Some(op) = rebase.next() {
1215
let _op = op?;
1316
// dbg!(op.id());
@@ -17,12 +20,68 @@ pub fn conflict_free_rebase(
1720
return Err(Error::RebaseConflict);
1821
}
1922

20-
rebase.commit(None, &signature, None)?;
23+
let c = rebase.commit(None, &signature, None)?;
24+
25+
last_commit = Some(CommitId::from(c));
2126
}
27+
2228
if repo.index()?.has_conflicts() {
2329
rebase.abort()?;
2430
return Err(Error::RebaseConflict);
2531
}
32+
2633
rebase.finish(Some(&signature))?;
27-
Ok(())
34+
35+
last_commit.ok_or_else(|| {
36+
Error::Generic(String::from("no commit rebased"))
37+
})
38+
}
39+
40+
#[cfg(test)]
41+
mod tests {
42+
use crate::sync::{
43+
checkout_branch, create_branch, rebase_branch,
44+
tests::{repo_init, write_commit_file},
45+
CommitId,
46+
};
47+
use git2::Repository;
48+
49+
fn parent_ids(repo: &Repository, c: CommitId) -> Vec<CommitId> {
50+
let foo = repo
51+
.find_commit(c.into())
52+
.unwrap()
53+
.parent_ids()
54+
.map(|id| CommitId::from(id))
55+
.collect();
56+
57+
foo
58+
}
59+
60+
#[test]
61+
fn test_smoke() {
62+
let (_td, repo) = repo_init().unwrap();
63+
let root = repo.path().parent().unwrap();
64+
let repo_path = root.as_os_str().to_str().unwrap();
65+
66+
let c1 =
67+
write_commit_file(&repo, "test1.txt", "test", "commit1");
68+
69+
create_branch(repo_path, "foo").unwrap();
70+
71+
let c2 =
72+
write_commit_file(&repo, "test2.txt", "test", "commit2");
73+
74+
assert_eq!(parent_ids(&repo, c2), vec![c1]);
75+
76+
checkout_branch(repo_path, "refs/heads/master").unwrap();
77+
78+
let c3 =
79+
write_commit_file(&repo, "test3.txt", "test", "commit3");
80+
81+
checkout_branch(repo_path, "refs/heads/foo").unwrap();
82+
83+
let r = rebase_branch(repo_path, "master").unwrap();
84+
85+
assert_eq!(parent_ids(&repo, r), vec![c3]);
86+
}
2887
}

0 commit comments

Comments
 (0)