aboutsummaryrefslogtreecommitdiffstats
path: root/src/util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.rs')
-rw-r--r--src/util.rs53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/util.rs b/src/util.rs
index a829327..5394fb0 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -130,6 +130,59 @@ pub fn print_collected_packages(packages: &PackageList, message: &str) {
);
}
+pub fn pull_latest_tag(path: &Path) -> Result<(), git2::Error> {
+ let repo = Repository::open(path)?;
+
+ let head = repo.head()?;
+ let branch = head
+ .shorthand()
+ .ok_or_else(|| git2::Error::from_str("Could not determine current branch"))?
+ .to_string();
+
+ let mut callbacks = RemoteCallbacks::new();
+ callbacks.credentials(|_url, username_from_url, _allowed| {
+ Cred::ssh_key_from_agent(username_from_url.unwrap())
+ });
+
+ let mut fetch_options = FetchOptions::new();
+ fetch_options.remote_callbacks(callbacks);
+
+ let mut remote = repo.find_remote("origin")?;
+ remote.fetch(&["refs/tags/*:refs/tags/*"], Some(&mut fetch_options), None)?;
+
+ let tag_names = repo.tag_names(None)?;
+
+ let mut latest_commit = None;
+ let mut latest_time = 0;
+
+ for name in tag_names.iter().flatten() {
+ let obj = repo.revparse_single(&format!("refs/tags/{}", name))?;
+ let commit = obj.peel_to_commit()?;
+
+ let time = commit.time().seconds();
+ if time > latest_time {
+ latest_time = time;
+ latest_commit = Some(commit);
+ }
+ }
+
+ let latest_commit = latest_commit.ok_or_else(|| git2::Error::from_str("No tags found"))?;
+
+ let annotated = repo.find_annotated_commit(latest_commit.id())?;
+ let (analysis, _) = repo.merge_analysis(&[&annotated])?;
+
+ if analysis.is_fast_forward() {
+ let refname = format!("refs/heads/{}", branch);
+ let mut reference = repo.find_reference(&refname)?;
+ reference.set_target(latest_commit.id(), "Fast-Forward to latest tag")?;
+ repo.set_head(&refname)?;
+ repo.checkout_head(Some(CheckoutBuilder::default().force()))?;
+ } else if !analysis.is_up_to_date() {
+ println!("Cannot fast-forward to latest tag.");
+ }
+
+ Ok(())
+}
pub fn pull_repo(path: &Path) -> Result<(), git2::Error> {
let repo = Repository::open(path)?;