Skip to content

Commit 617499d

Browse files
authored
Added some low- and high-level bindings for creating branches, settin… (#543)
* Added some low- and high-level bindings for creating branches, setting the repository HEAD, and getting reference names pointed to by annotated commits. * Fixed rustfmt issue. * Truly fix rustfmt issue.
1 parent 45ba1b8 commit 617499d

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

libgit2-sys/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,6 +1806,10 @@ extern "C" {
18061806
repo: *mut git_repository,
18071807
commitish: *const git_oid,
18081808
) -> c_int;
1809+
pub fn git_repository_set_head_detached_from_annotated(
1810+
repo: *mut git_repository,
1811+
commitish: *const git_annotated_commit,
1812+
) -> c_int;
18091813
pub fn git_repository_set_bare(repo: *mut git_repository) -> c_int;
18101814
pub fn git_repository_is_worktree(repo: *const git_repository) -> c_int;
18111815
pub fn git_repository_is_bare(repo: *const git_repository) -> c_int;
@@ -2528,6 +2532,13 @@ extern "C" {
25282532
target: *const git_commit,
25292533
force: c_int,
25302534
) -> c_int;
2535+
pub fn git_branch_create_from_annotated(
2536+
ref_out: *mut *mut git_reference,
2537+
repository: *mut git_repository,
2538+
branch_name: *const c_char,
2539+
commit: *const git_annotated_commit,
2540+
force: c_int,
2541+
) -> c_int;
25312542
pub fn git_branch_delete(branch: *mut git_reference) -> c_int;
25322543
pub fn git_branch_is_head(branch: *const git_reference) -> c_int;
25332544
pub fn git_branch_iterator_free(iter: *mut git_branch_iterator);
@@ -2891,6 +2902,7 @@ extern "C" {
28912902

28922903
// merge
28932904
pub fn git_annotated_commit_id(commit: *const git_annotated_commit) -> *const git_oid;
2905+
pub fn git_annotated_commit_ref(commit: *const git_annotated_commit) -> *const c_char;
28942906
pub fn git_annotated_commit_from_ref(
28952907
out: *mut *mut git_annotated_commit,
28962908
repo: *mut git_repository,

src/merge.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use libc::c_uint;
22
use std::marker;
33
use std::mem;
4+
use std::str;
45

56
use crate::call::Convert;
67
use crate::util::Binding;
@@ -26,6 +27,18 @@ impl<'repo> AnnotatedCommit<'repo> {
2627
pub fn id(&self) -> Oid {
2728
unsafe { Binding::from_raw(raw::git_annotated_commit_id(self.raw)) }
2829
}
30+
31+
/// Get the refname that the given git_annotated_commit refers to
32+
///
33+
/// Returns None if it is not valid utf8
34+
pub fn refname(&self) -> Option<&str> {
35+
str::from_utf8(self.refname_bytes()).ok()
36+
}
37+
38+
/// Get the refname that the given git_annotated_commit refers to.
39+
pub fn refname_bytes(&self) -> &[u8] {
40+
unsafe { crate::opt_bytes(self, raw::git_annotated_commit_ref(&*self.raw)).unwrap() }
41+
}
2942
}
3043

3144
impl Default for MergeOptions {

src/repo.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,27 @@ impl Repository {
742742
Ok(())
743743
}
744744

745+
/// Make the repository HEAD directly point to the commit.
746+
///
747+
/// If the provided committish cannot be found in the repository, the HEAD
748+
/// is unaltered and an error is returned.
749+
/// If the provided commitish cannot be peeled into a commit, the HEAD is
750+
/// unaltered and an error is returned.
751+
/// Otherwise, the HEAD will eventually be detached and will directly point
752+
/// to the peeled commit.
753+
pub fn set_head_detached_from_annotated(
754+
&self,
755+
commitish: AnnotatedCommit<'_>,
756+
) -> Result<(), Error> {
757+
unsafe {
758+
try_call!(raw::git_repository_set_head_detached_from_annotated(
759+
self.raw,
760+
commitish.raw()
761+
));
762+
}
763+
Ok(())
764+
}
765+
745766
/// Create an iterator for the repo's references
746767
pub fn references(&self) -> Result<References<'_>, Error> {
747768
let mut ret = ptr::null_mut();
@@ -1053,6 +1074,34 @@ impl Repository {
10531074
}
10541075
}
10551076

1077+
/// Create a new branch pointing at a target commit
1078+
///
1079+
/// This behaves like `Repository::branch()` but takes
1080+
/// an annotated commit, which lets you specify which
1081+
/// extended sha syntax string was specified by a user,
1082+
/// allowing for more exact reflog messages.
1083+
///
1084+
/// See the documentation for `Repository::branch()`
1085+
pub fn branch_from_annotated_commit(
1086+
&self,
1087+
branch_name: &str,
1088+
target: &AnnotatedCommit<'_>,
1089+
force: bool,
1090+
) -> Result<Branch<'_>, Error> {
1091+
let branch_name = CString::new(branch_name)?;
1092+
let mut raw = ptr::null_mut();
1093+
unsafe {
1094+
try_call!(raw::git_branch_create_from_annotated(
1095+
&mut raw,
1096+
self.raw(),
1097+
branch_name,
1098+
target.raw(),
1099+
force
1100+
));
1101+
Ok(Branch::wrap(Binding::from_raw(raw)))
1102+
}
1103+
}
1104+
10561105
/// Lookup a branch by its name in a repository.
10571106
pub fn find_branch(&self, name: &str, branch_type: BranchType) -> Result<Branch<'_>, Error> {
10581107
let name = CString::new(name)?;

0 commit comments

Comments
 (0)