Skip to content

Commit 78df3a9

Browse files
committed
Extract commit helper methods to repo_utils
1 parent db6c9c6 commit 78df3a9

File tree

3 files changed

+91
-74
lines changed

3 files changed

+91
-74
lines changed

src/lib.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ mod tests {
532532

533533
use super::*;
534534
mod log_utils;
535-
mod repo_utils;
535+
pub mod repo_utils;
536536

537537
#[test]
538538
fn multiple_fixups_per_commit() {
@@ -929,18 +929,9 @@ mod tests {
929929

930930
// create a fixup commit that 'git rebase' will act on if called
931931
let tree = repo_utils::stage_file_changes(&ctx, &path);
932-
let signature = ctx.repo.signature().unwrap();
933932
let head_commit = ctx.repo.head().unwrap().peel_to_commit().unwrap();
934-
ctx.repo
935-
.commit(
936-
Some("HEAD"),
937-
&signature,
938-
&signature,
939-
&format!("fixup! {}\n", head_commit.id()),
940-
&tree,
941-
&[&head_commit],
942-
)
943-
.unwrap();
933+
let fixup_message = format!("fixup! {}\n", head_commit.id());
934+
repo_utils::commit(&ctx.repo, "HEAD", &fixup_message, &tree, &[&head_commit]);
944935

945936
// stage one more change so 'git-absorb' won't exit early
946937
repo_utils::stage_file_changes(&ctx, &path);

src/stack.rs

Lines changed: 9 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ where
123123
mod tests {
124124

125125
use super::*;
126+
use crate::tests::repo_utils;
126127

127128
fn empty_slog() -> slog::Logger {
128129
slog::Logger::root(slog::Discard, o!())
@@ -141,46 +142,6 @@ mod tests {
141142
(dir, repo)
142143
}
143144

144-
fn empty_commit<'repo>(
145-
repo: &'repo git2::Repository,
146-
update_ref: &str,
147-
message: &str,
148-
parents: &[&git2::Commit],
149-
) -> git2::Commit<'repo> {
150-
let sig = repo.signature().unwrap();
151-
let tree = repo
152-
.find_tree(repo.treebuilder(None).unwrap().write().unwrap())
153-
.unwrap();
154-
155-
repo.find_commit(
156-
repo.commit(Some(update_ref), &sig, &sig, message, &tree, parents)
157-
.unwrap(),
158-
)
159-
.unwrap()
160-
}
161-
162-
fn empty_commit_chain<'repo>(
163-
repo: &'repo git2::Repository,
164-
update_ref: &str,
165-
initial_parents: &[&git2::Commit],
166-
length: usize,
167-
) -> Vec<git2::Commit<'repo>> {
168-
let mut ret = Vec::with_capacity(length);
169-
170-
for idx in 0..length {
171-
let next = if let Some(last) = ret.last() {
172-
// TODO: how to deduplicate the rest of this call if last doesn't live long enough?
173-
empty_commit(repo, update_ref, &idx.to_string(), &[last])
174-
} else {
175-
empty_commit(repo, update_ref, &idx.to_string(), initial_parents)
176-
};
177-
ret.push(next)
178-
}
179-
180-
assert_eq!(ret.len(), length);
181-
ret
182-
}
183-
184145
fn assert_stack_matches_chain(length: usize, stack: &[git2::Commit], chain: &[git2::Commit]) {
185146
assert_eq!(stack.len(), length);
186147
for (chain_commit, stack_commit) in chain.iter().rev().take(length).zip(stack) {
@@ -191,7 +152,7 @@ mod tests {
191152
#[test]
192153
fn test_stack_hides_other_branches() {
193154
let (_dir, repo) = init_repo();
194-
let commits = empty_commit_chain(&repo, "HEAD", &[], 2);
155+
let commits = repo_utils::empty_commit_chain(&repo, "HEAD", &[], 2);
195156
repo.branch("hide", &commits[0], false).unwrap();
196157

197158
assert_stack_matches_chain(
@@ -204,7 +165,7 @@ mod tests {
204165
#[test]
205166
fn test_stack_uses_custom_base() {
206167
let (_dir, repo) = init_repo();
207-
let commits = empty_commit_chain(&repo, "HEAD", &[], 3);
168+
let commits = repo_utils::empty_commit_chain(&repo, "HEAD", &[], 3);
208169
repo.branch("hide", &commits[1], false).unwrap();
209170

210171
assert_stack_matches_chain(
@@ -224,7 +185,7 @@ mod tests {
224185
#[test]
225186
fn test_stack_stops_at_configured_limit() {
226187
let (_dir, repo) = init_repo();
227-
let commits = empty_commit_chain(&repo, "HEAD", &[], config::MAX_STACK + 2);
188+
let commits = repo_utils::empty_commit_chain(&repo, "HEAD", &[], config::MAX_STACK + 2);
228189
repo.config()
229190
.unwrap()
230191
.set_i64(
@@ -243,12 +204,13 @@ mod tests {
243204
#[test]
244205
fn test_stack_stops_at_foreign_author() {
245206
let (_dir, repo) = init_repo();
246-
let old_commits = empty_commit_chain(&repo, "HEAD", &[], 3);
207+
let old_commits = repo_utils::empty_commit_chain(&repo, "HEAD", &[], 3);
247208
repo.config()
248209
.unwrap()
249210
.set_str("user.name", "nobody2")
250211
.unwrap();
251-
let new_commits = empty_commit_chain(&repo, "HEAD", &[old_commits.last().unwrap()], 2);
212+
let new_commits =
213+
repo_utils::empty_commit_chain(&repo, "HEAD", &[old_commits.last().unwrap()], 2);
252214

253215
assert_stack_matches_chain(
254216
2,
@@ -260,13 +222,8 @@ mod tests {
260222
#[test]
261223
fn test_stack_stops_at_merges() {
262224
let (_dir, repo) = init_repo();
263-
let first = empty_commit(&repo, "HEAD", "first", &[]);
264-
// equivalent to checkout --orphan
265-
repo.set_head("refs/heads/new").unwrap();
266-
let second = empty_commit(&repo, "HEAD", "second", &[]);
267-
// the current commit must be the first parent
268-
let merge = empty_commit(&repo, "HEAD", "merge", &[&second, &first]);
269-
let commits = empty_commit_chain(&repo, "HEAD", &[&merge], 2);
225+
let merge = repo_utils::merge_commit(&repo, &[]);
226+
let commits = repo_utils::empty_commit_chain(&repo, "HEAD", &[&merge], 2);
270227

271228
assert_stack_matches_chain(
272229
2,

src/tests/repo_utils.rs

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,7 @@ lines
3838
// make the borrow-checker happy by introducing a new scope
3939
{
4040
let tree = add(&repo, &path);
41-
let signature = repo.signature().unwrap();
42-
repo.commit(
43-
Some("HEAD"),
44-
&signature,
45-
&signature,
46-
"Initial commit.",
47-
&tree,
48-
&[],
49-
)
50-
.unwrap();
41+
commit(&repo, "HEAD", "Initial commit.", &tree, &[]);
5142
}
5243

5344
(Context { repo, dir }, path)
@@ -113,3 +104,81 @@ pub fn delete_branch(repo: &git2::Repository, branch_name: &str) {
113104
pub fn set_config_flag(repo: &git2::Repository, flag_name: &str) {
114105
repo.config().unwrap().set_str(flag_name, "true").unwrap();
115106
}
107+
108+
/// Make a trio of commits to form a merge:
109+
/// two parents and a child. The parents branch from the supplied grandparents.
110+
pub fn merge_commit<'repo>(
111+
repo: &'repo git2::Repository,
112+
grandparents: &[&git2::Commit],
113+
) -> git2::Commit<'repo> {
114+
let first_commit = empty_commit(repo, "HEAD", "first commit", grandparents);
115+
let second_commit = empty_commit(repo, "refs/heads/topic", "second commit", grandparents);
116+
empty_commit(
117+
repo,
118+
"HEAD",
119+
"merge commit",
120+
&[&first_commit, &second_commit],
121+
)
122+
}
123+
124+
/// Add a chain of empty commits to the repository.
125+
/// The first commit will have the given parents, and each subsequent commit will have the previous
126+
/// commit as its parent.
127+
/// Commit messages will be automatically generated.
128+
pub fn empty_commit_chain<'repo>(
129+
repo: &'repo git2::Repository,
130+
update_ref: &str,
131+
initial_parents: &[&git2::Commit],
132+
length: usize,
133+
) -> Vec<git2::Commit<'repo>> {
134+
let mut ret = Vec::with_capacity(length);
135+
136+
for idx in 0..length {
137+
let next = if let Some(last) = ret.last() {
138+
// TODO: how to deduplicate the rest of this call if last doesn't live long enough?
139+
empty_commit(repo, update_ref, &idx.to_string(), &[last])
140+
} else {
141+
empty_commit(repo, update_ref, &idx.to_string(), initial_parents)
142+
};
143+
ret.push(next)
144+
}
145+
146+
assert_eq!(ret.len(), length);
147+
ret
148+
}
149+
150+
/// Add an empty commit to the repository.
151+
pub fn empty_commit<'repo>(
152+
repo: &'repo git2::Repository,
153+
update_ref: &str,
154+
message: &str,
155+
parents: &[&git2::Commit],
156+
) -> git2::Commit<'repo> {
157+
let tree = if repo.is_empty().unwrap() {
158+
repo.find_tree(repo.treebuilder(None).unwrap().write().unwrap())
159+
.unwrap()
160+
} else {
161+
let head = repo.head().unwrap();
162+
let head_commit = head.peel_to_commit().unwrap();
163+
164+
// Get the tree of the current HEAD commit
165+
head_commit.tree().unwrap()
166+
};
167+
commit(repo, update_ref, message, &tree, parents)
168+
}
169+
170+
/// Add a new commit to the repository.
171+
pub fn commit<'repo>(
172+
repo: &'repo git2::Repository,
173+
update_ref: &str,
174+
message: &str,
175+
tree: &Tree,
176+
parents: &[&git2::Commit],
177+
) -> git2::Commit<'repo> {
178+
let sig = repo.signature().unwrap();
179+
repo.find_commit(
180+
repo.commit(Some(update_ref), &sig, &sig, message, &tree, parents)
181+
.unwrap(),
182+
)
183+
.unwrap()
184+
}

0 commit comments

Comments
 (0)