我正在构建一个应用程序,它在内部使用git2.rs来管理一个项目。
我正在尝试为基本用例实现测试,例如git init,git add,commit和push到远程,我在push部分遇到了问题。
我使用一个本地裸远程存储库实现了我的测试用例。我首先创建一个源代码库,在里面初始化git,然后创建一个哑文本文件,将其添加到索引并提交。
一切似乎都在那里工作。
然后我创建一个本地裸仓库,将其设置为源仓库的“origin”remote,并在远程仓库示例上调用push。我没有错误,但源代码库的内容似乎没有被推。
文档对学习者不是很友好,所以我很难理解我在做什么。
我希望在远程仓库目录中看到我的文本文件,但只有git结构。
当我尝试通过在推送后将远程克隆到新目录中来做出Assert时,我检查文本文件是否在那里,但它不在,它只是创建了一个空的存储库。
下面是我的代码的相关部分,它只是我在tests子模块中实现的一个trait。
源特性
use git2::Repository;
use std::path::PathBuf;
pub trait Git {
// ... other methods...
fn _set_remote<'a, T: Into<PathBuf>>(
repo_dir: T,
name: &str,
url: &str,
) -> Result<(), git2::Error> {
let repo = Self::_repo(repo_dir)?;
repo.remote(name, url)?;
Ok(())
}
fn git_init(&self) -> Result<Repository, git2::Error>;
fn git_add<'a, E: Into<&'a str>>(&self, expr: E) -> Result<git2::Index, git2::Error>;
fn git_commit<'a, M: Into<&'a str>>(&self, message: M) -> Result<git2::Oid, git2::Error>;
fn git_set_remote(&self, name: &str, url: &str) -> Result<(), git2::Error>;
}
字符串
测试实施
#[cfg(test)]
mod tests {
use super::*;
use std::io::Write;
struct TestGit {
pub dir: PathBuf,
pub state: String,
}
// Impl TestGit ...
impl Git for TestGit {
fn git_init(&self) -> Result<Repository, git2::Error> {
// ...
}
fn git_add<'a, E: Into<&'a str>>(&self, expr: E) -> Result<git2::Index, git2::Error> {
// ...
}
fn git_commit<'a, M: Into<&'a str>>(&self, message: M) -> Result<git2::Oid, git2::Error> {
// ...
}
fn git_set_remote(&self, name: &str, url: &str) -> Result<(), git2::Error> {
Self::_set_remote(&self.dir, name, url)
}
}
// Some first tests for init, add, commit, write file, etc.
// ...
#[test]
fn test_push() {
let testgit = TestGit {
dir: std::env::current_dir().unwrap().join("test/base"),
state: String::from("Hello"),
};
let base_repo = testgit.git_init().unwrap();
let testgitremote = create_testgit_instance("test/remote");
<TestGit as Git>::_init::<&PathBuf>(&testgitremote.dir, true).unwrap();
testgit
.git_set_remote(
"origin",
format!("file://{}", testgitremote.dir.to_str().unwrap()).as_str(),
)
.unwrap();
testgit.write_file("test.txt").unwrap(); // This creates a test.txt file with "Hello" in it at the root of the repo.
testgit.git_add(".").unwrap();
testgit.git_commit("test commit").unwrap();
// This works find until there becauses I tested it elsewhere, the index contains one more element after the commit.
let mut remote = base_repo.find_remote("origin").unwrap();
remote.push::<&str>(&[], None).unwrap(); // This is what I'm having troubles to understand, I'm guessing I'm just pushing nothing but I don't find anything clear in the docs and there is no "push" example it the git2.rs sources.
let mut clonebuilder = git2::build::RepoBuilder::new();
let clonerepo_dir = testgit.dir.parent().unwrap().join("clone");
clonebuilder
.clone(remote.url().unwrap(), &clonerepo_dir)
.unwrap();
assert!(clonerepo_dir.join("test.txt").exists()); // This fails...
std::fs::remove_dir_all(&testgit.dir.parent().unwrap()).unwrap();
}
}
型
我也试着像这样添加refspecs,但它并没有改变任何东西
let mut remote = base_repo.find_remote("origin").unwrap();
remote.push::<&str>(&["refs/heads/master:refs/heads/master")], None).unwrap();
型
或者像这样,同样的结果。
let mut remote = base_repo.find_remote("origin").unwrap();
base_repo
.remote_add_push("origin", "refs/heads/master:refs/heads/master")
.unwrap();
remote.push::<&str>(&[], None).unwrap();
型
非常感谢你的帮助。
1条答案
按热度按时间mf98qq941#
我在这个线程https://users.rust-lang.org/t/how-to-use-git2-push-correctly/97202/6中得到了一个解决方案,我在这里依赖它,以防它可能有用。
原来问题出在我的
git commit
实现上。我忘了用新提交更新分支指针。所以才没有推。这是给我解答的片段
字符串
如果有用的话,这里是我的add和commit的固定实现,以及推送测试。
的数据