summaryrefslogtreecommitdiff
path: root/src/bin/git-diff-autosave.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/git-diff-autosave.rs')
-rw-r--r--src/bin/git-diff-autosave.rs81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/bin/git-diff-autosave.rs b/src/bin/git-diff-autosave.rs
new file mode 100644
index 0000000..63aa130
--- /dev/null
+++ b/src/bin/git-diff-autosave.rs
@@ -0,0 +1,81 @@
+use auth_git2::GitAuthenticator;
+use git_autosave::{Config, authenticate::Inquirer, inquire::AutosaveFilters};
+use git2::{DiffOptions, RemoteCallbacks, Repository};
+
+fn main() -> Result<(), anyhow::Error> {
+ let all_users = std::env::args().any(|arg| arg == "--all-users");
+ let all_branches = std::env::args().any(|arg| arg == "--all-branches");
+ let all_devices = std::env::args().any(|arg| arg == "--all-devices");
+ let anytime = std::env::args().any(|arg| arg == "--anytime");
+
+ let repository = Repository::discover(".")?;
+ let repo_id = git_autosave::repository_id(&repository)?;
+ let signature = repository.signature()?;
+ let branch = git_autosave::utils::current_branch(&repository)?;
+ let earliest_time = repository.head()?.peel_to_commit()?.time();
+
+ let gitconfig = repository.config()?;
+ let config: &'static _ = Box::leak(Box::new(Config::load()?));
+ let auth = GitAuthenticator::new().set_prompter(Inquirer(config));
+ let mut callbacks = RemoteCallbacks::new();
+ callbacks.credentials(auth.credentials(&gitconfig));
+ git_autosave::fetch_autosaves(&repository, callbacks)?;
+
+ let autosaves = git_autosave::autosaves(&repository)?;
+ let autosaves = git_autosave::inquire::filter_autosaves(
+ autosaves,
+ AutosaveFilters {
+ signature: &signature,
+ branch: &branch,
+ earliest_time,
+ repo_id: &repo_id,
+ all_users,
+ all_branches,
+ anytime,
+ all_devices,
+ },
+ )
+ .collect::<Vec<_>>();
+
+ if autosaves.is_empty() {
+ eprintln!("ERROR: There are no available autosaves for the given filters.");
+ if !all_users || !all_branches || !anytime {
+ eprintln!(
+ "hint: Use --all-users, --all-branches, --all-devices, or --anytime to include more options."
+ );
+ }
+ std::process::exit(1);
+ }
+
+ let autosave = git_autosave::inquire::select_autosave(autosaves, all_branches, all_users)?;
+ let autosaved_commit = repository.find_commit(autosave.commit_id)?;
+ let workdir = repository.find_tree(git_autosave::utils::workdir_to_tree(&repository)?)?;
+ let new_tree = repository.find_tree(git_autosave::utils::merge_commit_with_tree(
+ &repository,
+ &autosaved_commit,
+ &workdir,
+ )?)?;
+ let diff = repository.diff_tree_to_tree(
+ Some(&workdir),
+ Some(&new_tree),
+ Some(DiffOptions::new().include_unmodified(false).patience(true)),
+ )?;
+ diff.print(git2::DiffFormat::Patch, |_, _, line| {
+ let origin = match line.origin_value() {
+ git2::DiffLineType::Context => " ",
+ git2::DiffLineType::Addition => "+",
+ git2::DiffLineType::Deletion => "-",
+ git2::DiffLineType::ContextEOFNL => "=",
+ git2::DiffLineType::AddEOFNL => ">",
+ git2::DiffLineType::DeleteEOFNL => "<",
+ git2::DiffLineType::FileHeader => "",
+ git2::DiffLineType::HunkHeader => "",
+ git2::DiffLineType::Binary => "",
+ };
+ let content = String::from_utf8_lossy(line.content());
+ println!("{origin}{content}");
+ true
+ })?;
+
+ Ok(())
+}