Skip to content

Commit 3954d34

Browse files
authored
Merge pull request #893 from nasso/reference-symbolic-set-target
Add `Reference::symbolic_set_target`
2 parents ca6b334 + 96f5057 commit 3954d34

File tree

3 files changed

+56
-0
lines changed

3 files changed

+56
-0
lines changed

libgit2-sys/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2437,6 +2437,12 @@ extern "C" {
24372437
id: *const git_oid,
24382438
log_message: *const c_char,
24392439
) -> c_int;
2440+
pub fn git_reference_symbolic_set_target(
2441+
out: *mut *mut git_reference,
2442+
r: *mut git_reference,
2443+
target: *const c_char,
2444+
log_message: *const c_char,
2445+
) -> c_int;
24402446
pub fn git_reference_type(r: *const git_reference) -> git_reference_t;
24412447
pub fn git_reference_iterator_new(
24422448
out: *mut *mut git_reference_iterator,

src/reference.rs

+37
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,35 @@ impl<'repo> Reference<'repo> {
361361
Ok(Binding::from_raw(raw))
362362
}
363363
}
364+
365+
/// Create a new reference with the same name as the given reference but a
366+
/// different symbolic target. The reference must be a symbolic reference,
367+
/// otherwise this will fail.
368+
///
369+
/// The new reference will be written to disk, overwriting the given
370+
/// reference.
371+
///
372+
/// The target name will be checked for validity. See
373+
/// [`Repository::reference_symbolic`] for rules about valid names.
374+
///
375+
/// The message for the reflog will be ignored if the reference does not
376+
/// belong in the standard set (HEAD, branches and remote-tracking
377+
/// branches) and it does not have a reflog.
378+
pub fn symbolic_set_target(
379+
&mut self,
380+
target: &str,
381+
reflog_msg: &str,
382+
) -> Result<Reference<'repo>, Error> {
383+
let mut raw = ptr::null_mut();
384+
let target = CString::new(target)?;
385+
let msg = CString::new(reflog_msg)?;
386+
unsafe {
387+
try_call!(raw::git_reference_symbolic_set_target(
388+
&mut raw, self.raw, target, msg
389+
));
390+
Ok(Binding::from_raw(raw))
391+
}
392+
}
364393
}
365394

366395
impl<'repo> PartialOrd for Reference<'repo> {
@@ -512,6 +541,14 @@ mod tests {
512541
.reference_symbolic("refs/tags/tag1", "refs/heads/main", false, "test")
513542
.unwrap();
514543
assert_eq!(sym1.kind().unwrap(), ReferenceType::Symbolic);
544+
let mut sym2 = repo
545+
.reference_symbolic("refs/tags/tag2", "refs/heads/main", false, "test")
546+
.unwrap()
547+
.symbolic_set_target("refs/tags/tag1", "test")
548+
.unwrap();
549+
assert_eq!(sym2.kind().unwrap(), ReferenceType::Symbolic);
550+
assert_eq!(sym2.symbolic_target().unwrap(), "refs/tags/tag1");
551+
sym2.delete().unwrap();
515552
sym1.delete().unwrap();
516553

517554
{

src/repo.rs

+13
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,19 @@ impl Repository {
14801480

14811481
/// Create a new symbolic reference.
14821482
///
1483+
/// A symbolic reference is a reference name that refers to another
1484+
/// reference name. If the other name moves, the symbolic name will move,
1485+
/// too. As a simple example, the "HEAD" reference might refer to
1486+
/// "refs/heads/master" while on the "master" branch of a repository.
1487+
///
1488+
/// Valid reference names must follow one of two patterns:
1489+
///
1490+
/// 1. Top-level names must contain only capital letters and underscores,
1491+
/// and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
1492+
/// 2. Names prefixed with "refs/" can be almost anything. You must avoid
1493+
/// the characters '~', '^', ':', '\\', '?', '[', and '*', and the
1494+
/// sequences ".." and "@{" which have special meaning to revparse.
1495+
///
14831496
/// This function will return an error if a reference already exists with
14841497
/// the given name unless force is true, in which case it will be
14851498
/// overwritten.

0 commit comments

Comments
 (0)