1
1
use crate :: error:: { Error , Result } ;
2
2
3
+ use super :: CommitId ;
4
+
3
5
/// rebase attempt which aborts and undo's rebase if any conflict appears
4
6
pub fn conflict_free_rebase (
5
7
repo : & git2:: Repository ,
6
8
commit : & git2:: AnnotatedCommit ,
7
- ) -> Result < ( ) > {
9
+ ) -> Result < CommitId > {
8
10
let mut rebase = repo. rebase ( None , Some ( commit) , None , None ) ?;
9
11
let signature =
10
12
crate :: sync:: commit:: signature_allow_undefined_name ( repo) ?;
13
+ let mut last_commit = None ;
11
14
while let Some ( op) = rebase. next ( ) {
12
15
let _op = op?;
13
16
// dbg!(op.id());
@@ -17,12 +20,68 @@ pub fn conflict_free_rebase(
17
20
return Err ( Error :: RebaseConflict ) ;
18
21
}
19
22
20
- rebase. commit ( None , & signature, None ) ?;
23
+ let c = rebase. commit ( None , & signature, None ) ?;
24
+
25
+ last_commit = Some ( CommitId :: from ( c) ) ;
21
26
}
27
+
22
28
if repo. index ( ) ?. has_conflicts ( ) {
23
29
rebase. abort ( ) ?;
24
30
return Err ( Error :: RebaseConflict ) ;
25
31
}
32
+
26
33
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
+ }
28
87
}
0 commit comments