diff options
Diffstat (limited to 'src/util.rs')
| -rw-r--r-- | src/util.rs | 53 |
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)?; |
