Hi!
I'm a total Rust noob and I'm trying to build a software that will interact with repos that are hosted on Github and Gitlab.
I've followed the code from How to use git2::Remote::push correctly? but I'm still encountering an error.
Here's what I'm trying to accomplish
git clone https://github.com/Scoubi/test.git
git checkout -b test
echo Hello World > test.txt
git add test.txt
git commit -m "message"
git push origin test
Here's the code
use std::{thread, time};
use std::io::{self, BufReader};
use git2::{IndexAddOption, Repository, Signature};
use std::path::{Path, PathBuf};
fn main(){
let repo_url = "https://github.com/Scoubi/test.git";
let repo_path = "/tmp/test/";
let repo = match Repository::clone(repo_url, repo_path) {
Ok(repo) => repo,
Err(e) => panic!("failed to clone: {}", e),
};
let my_branch = "test";
let head = repo.head().unwrap();
let oid = head.target().unwrap();
let commit = repo.find_commit(oid).unwrap();
let branch = repo.branch(
my_branch,
&commit,
false,
);
let obj = repo.revparse_single(&("refs/heads/".to_owned() + my_branch)).unwrap();
repo.checkout_tree(
&obj,
None
);
repo.set_head(&("refs/heads/".to_owned() + my_branch));
// based on : https://github.com/rust-lang/git2-rs/issues/561
let file_name = "test.txt";
create_file(&repo_path, file_name);
git_add_all(&repo);
git_commit_push(&repo, repo_url, my_branch);
}
fn create_file(repo_path:&str, file_name: &str) {
// let file_path = repo_path.join(file_name);
let file_path= format!("{}{}", repo_path, file_name);
std::fs::File::create(file_path).unwrap();
// println!("{}", file_path)
}
fn git_add_all(repo: &git2::Repository) {
let mut index = repo.index().unwrap();
index
.add_all(&["."], git2::IndexAddOption::DEFAULT, None)
.unwrap();
index.write().unwrap();
}
fn git_commit_push(repo: &git2::Repository, repo_url: &str, my_branch: &str) {
let mut index = repo.index().unwrap();
let tree = repo
.find_tree(index.write_tree().unwrap())
.unwrap();
let author = Signature::now("x", "x@x.xxx").unwrap();
//let mut parents = vec![];
let mut update_ref = Some("HEAD");
if let Ok(head) = repo.head() {
update_ref = Some("HEAD");
} else {
update_ref = None; // no HEAD = first commit
}
let parent_commit = repo.head().unwrap().peel_to_commit().unwrap();
dbg!(&parent_commit);
dbg!(update_ref);
let commit_oid = repo
.commit(update_ref, &author, &author, "commit message", &tree, &[&parent_commit])
.unwrap();
//update branch pointer
let branch = repo
.branch(my_branch, &repo.find_commit(commit_oid).unwrap(), true)
.unwrap();
let branch_ref = branch.into_reference();
let branch_ref_name = branch_ref.name().unwrap();
repo.set_head(branch_ref_name).unwrap();
// add remote as "origin" and push the branch
let mut origin = repo.remote("origin", my_branch).unwrap();
origin.push(&[branch_ref_name], None).unwrap();
}
First time that I run it I get the error
404: Not Found
thread 'main' panicked at 'failed to clone: remote authentication required but no callback set; class=Http (34); code=Auth (-16)'
If I clone it manually once, delete the folder and run the code again I get the following error
update_ref = Some(
"HEAD",
)
thread 'main' panicked at 'called Result::unwrap()
on an Err
value: Error { code: -1, klass: 4, message: "cannot force update branch 'test' as it is the current HEAD of the repository." }', src/bin/main.rs:84:6
Any help would be appreciated, I've been running in circle for 2 days now
I'd like to fix the code and also know how I'm supposed to use the token to authenticate to github. I generated my token and it works when I use it in the shell, but haven't figured how to use it successfully in Rust.
Thanks