Skip to content

Bind git_graph_* functions #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 6, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions libgit2-sys/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1830,6 +1830,15 @@ extern {
old_tree: *mut git_tree,
opts: *const git_diff_options)
-> c_int;

pub fn git_graph_ahead_behind(ahead: *mut size_t, behind: *mut size_t,
repo: *mut git_repository,
local: *const git_oid, upstream: *const git_oid)
-> c_int;

pub fn git_graph_descendant_of(repo: *mut git_repository,
commit: *const git_oid, ancestor: *const git_oid)
-> c_int;
}

#[test]
Expand Down
74 changes: 74 additions & 0 deletions src/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,35 @@ impl Repository {
Ok(Oid::from_raw(&raw))
}
}

/// Count the number of unique commits between two commit objects
///
/// There is no need for branches containing the commits to have any
/// upstream relationship, but it helps to think of one as a branch and the
/// other as its upstream, the ahead and behind values will be what git
/// would report for the branches.
pub fn graph_ahead_behind(&self, local: Oid, upstream: Oid)
-> Result<(uint, uint), Error> {
unsafe {
let mut ahead: size_t = 0;
let mut behind: size_t = 0;
try_call!(raw::git_graph_ahead_behind(&mut ahead, &mut behind,
self.raw(), local.raw(),
upstream.raw()));
Ok((ahead as uint, behind as uint))
}
}

/// Determine if a commit is the descendant of another commit
pub fn graph_descendant_of(&self, commit: Oid, ancestor: Oid)
-> Result<bool, Error> {
unsafe {
let rv = try_call!(raw::git_graph_descendant_of(self.raw(),
commit.raw(),
ancestor.raw()));
Ok(rv != 0)
}
}
}

#[unsafe_destructor]
Expand Down Expand Up @@ -1269,4 +1298,49 @@ mod tests {
let repo = Repository::discover(subdir.path()).unwrap();
assert!(repo.path() == *td.path());
}

fn graph_repo_init() -> (TempDir, Repository) {
let (_td, repo) = ::test::repo_init();
{
let head = repo.head().unwrap().target().unwrap();
let head = repo.find_commit(head).unwrap();

let mut index = repo.index().unwrap();
let id = index.write_tree().unwrap();

let tree = repo.find_tree(id).unwrap();
let sig = repo.signature().unwrap();
repo.commit(Some("HEAD"), &sig, &sig, "second",
&tree, &[&head]).unwrap();
}
(_td, repo)
}

#[test]
fn smoke_graph_ahead_behind() {
let (_td, repo) = graph_repo_init();
let head = repo.head().unwrap().target().unwrap();
let head = repo.find_commit(head).unwrap();
let head_id = head.id();
let head_parent_id = head.parent(0).unwrap().id();
let (ahead, behind) = repo.graph_ahead_behind(head_id,
head_parent_id).unwrap();
assert_eq!(ahead, 1);
assert_eq!(behind, 0);
let (ahead, behind) = repo.graph_ahead_behind(head_parent_id,
head_id).unwrap();
assert_eq!(ahead, 0);
assert_eq!(behind, 1);
}

#[test]
fn smoke_graph_descendant_of() {
let (_td, repo) = graph_repo_init();
let head = repo.head().unwrap().target().unwrap();
let head = repo.find_commit(head).unwrap();
let head_id = head.id();
let head_parent_id = head.parent(0).unwrap().id();
assert!(repo.graph_descendant_of(head_id, head_parent_id).unwrap());
assert!(!repo.graph_descendant_of(head_parent_id, head_id).unwrap());
}
}