【发布时间】:2019-11-08 14:55:02
【问题描述】:
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();
}
但是虽然 clone 和 reset 有效,但看起来 pull 无效。
我做错了什么?
【问题讨论】:
-
你能清楚地说明“不起作用”是什么意思吗?您期望会发生什么以及实际会发生什么?
-
我希望来自外部存储库的更改将被拉到本地存储库。与我在控制台中键入“git pull”的方式完全相同。但是在我运行此代码后,本地仓库中的 nothing 根本没有改变。
-
它确实有效,不是吗?
-
@edwardw 我在两个系统 Win10 和 Ubuntu 18.10 上试过。步骤 1) 构建一次并克隆 repo。 2) 在 repo 中执行“git reset --hard HEAD^^^”。检查 HEAD 是否已更改。 3) 再运行一次“cargo build”。 4) 检查结果:HEAD 仍在同一位置。 5) 通过手动运行“git pull”来仔细检查 - HEAD 在与 #1 之后的相同位置更改。所以,这段代码和 git pull 的工作方式肯定不同。
-
@JussiKukkonen 我忘了提——这段代码是“build.rs”的一部分。所以它适用于“cargo build”。