gpt4 book ai didi

git - 如何使用 Rust git2 crate 执行 "git pull"?

转载 作者:行者123 更新时间:2023-11-29 08:17:25 25 4
gpt4 key购买 nike

git2 crate 没有直接执行“git pull”操作的方法。

我看过 this question并尝试以相同的方式进行操作(playground):

use std::fs;
use std::fs::File;
use std::io::{stderr, stdout, Write};
use std::path::Path;

use git2::{Commit, Error, Index, MergeOptions, ObjectType, Repository, ResetType};

struct Repo {
url: &'static str,
path: &'static str,
branch: &'static str,
}

impl Repo {
fn reset(&self, path: &Path) {
let repo = match Repository::open(path) {
Ok(repo) => repo,
Err(e) => panic!("Failed to open: {}", e),
};
repo.reset(
&repo.revparse_single("HEAD").unwrap(),
ResetType::Hard,
None,
)
.unwrap();
}

fn clone(&self) {
let repo = match Repository::clone(self.url, self.path) {
Ok(repo) => repo,
Err(e) => panic!("failed to init: {}", e),
};
}

fn find_last_commit<'repo>(&self, repo: &'repo Repository) -> Result<Commit<'repo>, Error> {
let obj = repo.head()?.resolve()?.peel(ObjectType::Commit)?;
match obj.into_commit() {
Ok(c) => Ok(c),
_ => Err(Error::from_str("commit error")),
}
}

fn pull(&self, path: &Path) -> Result<Index, Error> {
let repo = Repository::open(path)?;

repo.find_remote("origin")?
.fetch(&[self.branch], None, None)?;

let last_commit = self.find_last_commit(&repo)?;
let reference = repo.find_reference("FETCH_HEAD")?;
let fetched_commit = reference.peel_to_commit()?;
let index =
repo.merge_commits(&last_commit, &fetched_commit, Some(&MergeOptions::new()))?;

return Ok(index);
}

pub fn check(&self) {
let repo_path = Path::new(self.path);

if !repo_path.exists() {
self.clone();
return;
}

if repo_path.exists() && repo_path.is_dir() {
self.reset(repo_path);
let idx = match self.pull(repo_path) {
Ok(idx) => idx,
Err(e) => panic!("Failed to pull: {}", e),
};
}
}
}

fn main() {
let currencies = Repo {
url: "https://github.com/datasets/currency-codes",
path: "./resources/currency-codes",
branch: "master",
};

currencies.check();
}

但是虽然clonereset 起作用,但看起来pull 不起作用。

我做错了什么?

最佳答案

git2-rs 仓库确实有 a pending PR添加了一个 pull 示例。我在这里对其进行了一些调整,以展示如何进行快进,因为这正是您要寻找的:

fn fast_forward(&self, path: &Path) -> Result<(), Error> {
let repo = Repository::open(path)?;

repo.find_remote("origin")?
.fetch(&[self.branch], None, None)?;

let fetch_head = repo.find_reference("FETCH_HEAD")?;
let fetch_commit = repo.reference_to_annotated_commit(&fetch_head)?;
let analysis = repo.merge_analysis(&[&fetch_commit])?;
if analysis.0.is_up_to_date() {
Ok(())
} else if analysis.0.is_fast_forward() {
let refname = format!("refs/heads/{}", self.branch);
let mut reference = repo.find_reference(&refname)?;
reference.set_target(fetch_commit.id(), "Fast-Forward")?;
repo.set_head(&refname)?;
repo.checkout_head(Some(git2::build::CheckoutBuilder::default().force()))
} else {
Err(Error::from_str("Fast-forward only!"))
}
}

pub fn check(&self) {
...
if repo_path.exists() && repo_path.is_dir() {
self.reset(repo_path);
if let Err(e) = self.fast_forward(repo_path) {
panic!("Failed to pull: {}", e)
}
}
}

版权归原作者所有。您还可以检查它是否存在非平凡的 merge 情况,即当本地树变脏时。

关于git - 如何使用 Rust git2 crate 执行 "git pull"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58768910/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com