Paul Campbell
5ba5a126c3
Some checks failed
ci/woodpecker/cron/cron-docker-builder Pipeline was successful
ci/woodpecker/cron/push-next Pipeline was successful
ci/woodpecker/cron/tag-created Pipeline was successful
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
ci/woodpecker/push/push-next Pipeline failed
The `git push` command requires a git directory (bare at a minimum) before it can work. The git dir must also be up-to-date with the relevant references from the remote, so we do a `git fetch` before a `git push`. Closes kemitix/git-next#51
72 lines
2.4 KiB
Rust
72 lines
2.4 KiB
Rust
use std::ops::Deref;
|
|
|
|
use tracing::info;
|
|
|
|
use crate::server::config::RepoDetails;
|
|
|
|
#[derive(Debug, derive_more::From, derive_more::Display)]
|
|
pub enum Error {
|
|
UnableToOpenRepo(Box<gix::open::Error>),
|
|
NoFetchRemoteFound,
|
|
Connect(Box<gix::remote::connect::Error>),
|
|
Fetch(String),
|
|
}
|
|
impl std::error::Error for Error {}
|
|
|
|
#[tracing::instrument]
|
|
pub fn fetch(repo_details: &RepoDetails) -> Result<(), Error> {
|
|
// INFO: gitdir validate tests that the default fetch remote matches the configured remote
|
|
let repository = gix::ThreadSafeRepository::open(repo_details.gitdir.deref())
|
|
.map_err(Box::new)?
|
|
.to_thread_local();
|
|
info!(?repository, "opened repo");
|
|
let Some(remote) = repository.find_default_remote(gix::remote::Direction::Fetch) else {
|
|
return Err(Error::NoFetchRemoteFound);
|
|
};
|
|
info!(?remote, "fetch remote");
|
|
|
|
remote
|
|
.map_err(|e| Error::Fetch(e.to_string()))?
|
|
.connect(gix::remote::Direction::Fetch)
|
|
.map_err(Box::new)?
|
|
.prepare_fetch(gix::progress::Discard, Default::default())
|
|
.map_err(|e| Error::Fetch(e.to_string()))?
|
|
.receive(gix::progress::Discard, &Default::default())
|
|
.map_err(|e| Error::Fetch(e.to_string()))?;
|
|
|
|
info!("fetched");
|
|
|
|
Ok(())
|
|
|
|
// INFO: never log the command as it contains the API token within the 'origin'
|
|
// let command: secrecy::Secret<String> = format!(
|
|
// "/usr/bin/git push {} {to_commit}:{branch_name} {force}",
|
|
// origin.expose_secret()
|
|
// )
|
|
// .into();
|
|
// info!("Resetting {branch_name} to {to_commit}");
|
|
// let ctx = gix::diff::command::Context {
|
|
// git_dir: Some(repo_details.gitdir.deref().clone()),
|
|
// ..Default::default()
|
|
// };
|
|
// // info!(?ctx, command = command.expose_secret(), "prepare");
|
|
// match gix::command::prepare(command.expose_secret())
|
|
// .with_context(ctx)
|
|
// .with_shell_allow_argument_splitting()
|
|
// // .stdout(std::process::Stdio::null())
|
|
// // .stderr(std::process::Stdio::null())
|
|
// .spawn()
|
|
// {
|
|
// Ok(mut child) => match child.wait() {
|
|
// Ok(_) => Ok(()),
|
|
// Err(err) => {
|
|
// warn!(?err, "Failed (wait)");
|
|
// Err(())
|
|
// }
|
|
// },
|
|
// Err(err) => {
|
|
// warn!(?err, "Failed (spawn)");
|
|
// Err(())
|
|
// }
|
|
// }
|
|
}
|