From 8d149e201c0b7c7cd1b66ba2552dba65b810d6ac Mon Sep 17 00:00:00 2001 From: Robin Gottschalk Date: Fri, 14 Mar 2025 09:05:20 +0100 Subject: [PATCH] Replaced git2 crate add to index, commit and push with calls to git cli and changed delay to 30 min --- Cargo.lock | 18 ------------ Cargo.toml | 1 - README.md | 2 ++ src/git.rs | 79 +++++++++++++++++++++-------------------------------- src/main.rs | 2 +- 5 files changed, 34 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2744ac0..6b2d0ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -168,12 +168,6 @@ version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" version = "1.9.0" @@ -1135,17 +1129,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "keyring" -version = "3.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f8fe839464d4e4b37d756d7e910063696af79a7e877282cb1825e4ec5f10833" -dependencies = [ - "byteorder", - "log", - "windows-sys 0.59.0", -] - [[package]] name = "kqueue" version = "1.0.8" @@ -1664,7 +1647,6 @@ version = "0.1.0" dependencies = [ "chrono", "git2", - "keyring", "notify", "tray-icon", "winit", diff --git a/Cargo.toml b/Cargo.toml index c31f49d..25be325 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,4 +9,3 @@ notify = "8.0.0" tray-icon = "0.19.2" git2 = "0.20.0" chrono = "0.4.39" -keyring = { version = "3.6.1", features = ["windows-native"] } diff --git a/README.md b/README.md index a52af7e..1707c8b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ This script automates the process of backing up your Obsidian vault to a Git rep - [x] Trigger backup after file changes with delay - [x] Maintain git repo in a seperate folder to not have the repo synced by syncthing (copy changed files over) - [x] Push changes to remote repository + - [x] Make adding and pushing LFS objects work with git - [x] Tray Menu - [x] Exit - [x] Backup now @@ -30,3 +31,4 @@ This script automates the process of backing up your Obsidian vault to a Git rep *.svg filter=lfs diff=lfs merge=lfs -text ``` - Link repository to origin as remote +- Make sure the underlying system has the git user set up with the corresponding access token diff --git a/src/git.rs b/src/git.rs index a1ae6fa..676fb1c 100644 --- a/src/git.rs +++ b/src/git.rs @@ -1,7 +1,7 @@ use chrono::Local; -use git2::{Cred, Error, IndexAddOption, PushOptions, RemoteCallbacks, Repository, StatusOptions}; -use keyring::Entry; +use git2::{Error, Repository, StatusOptions}; use std::path::Path; +use std::process::Command; pub fn current_change_count(repo_path: &Path) -> Result { // Open the repository at the provided path @@ -38,58 +38,41 @@ pub fn backup_changes(repo_path: &Path) -> Result<(), Box println!(" - {}: {:?}", path, status); } - // Add all changes to the index - let mut index = repo.index()?; - index.add_all(["*"].iter(), IndexAddOption::DEFAULT, None)?; - index.write()?; - - // Write the index to a tree - let tree_id = index.write_tree()?; - let tree = repo.find_tree(tree_id)?; - - // Use the repository signature for both author and committer - let signature = repo.signature()?; - - // Determine the parent commit - let parent_commit = repo.head()?.peel_to_commit()?; + // Stage all changes using the Git CLI + let status = Command::new("git") + .arg("add") + .arg("-A") + .current_dir(repo_path) + .status()?; + if !status.success() { + return Err("git add failed".into()); + } // Generate commit message with current timestamp let commit_message = format!("{} Autobackup", Local::now().format("%Y-%m-%d %H:%M:%S")); - // Create commit - repo.commit( - Some("HEAD"), - &signature, - &signature, - &commit_message, - &tree, - &[&parent_commit], - )?; + // Create a commit with a timestamped message + let status = Command::new("git") + .arg("commit") + .arg("-m") + .arg(&commit_message) + .current_dir(repo_path) + .status()?; + if !status.success() { + return Err("git commit failed".into()); + } - // Set up remote push with credentials callback - let mut callbacks = RemoteCallbacks::new(); - callbacks.credentials(move |_url, username, _allowed_types| { - let user = username.unwrap_or("git"); - let token = get_git_token(); - Cred::userpass_plaintext(user, &token) - }); - - // Push changes - let mut push_options = PushOptions::new(); - push_options.remote_callbacks(callbacks); - let mut remote = repo.find_remote("origin")?; - remote.push(&["refs/heads/main"], Some(&mut push_options))?; + // Push changes with Git CLI + let status = Command::new("git") + .arg("push") + .arg("origin") + .arg("main") + .current_dir(repo_path) + .status()?; + if !status.success() { + return Err("git push failed".into()); + } println!("Changes committed and pushed successfully."); Ok(()) } - -fn get_git_token() -> String { - // Get token from Windows Credential Manager - let service = "obsidian-git-backup"; // git.obsidian-git-backup in Credetial Manager - let username = "git"; - let entry = Entry::new(service, username).unwrap(); - entry - .get_password() - .expect("Git access token could not be retrieved from Windows Credential Manager") -} diff --git a/src/main.rs b/src/main.rs index 7f791b6..eac3330 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,7 @@ const PROTECT_PREFIX: &str = ".git"; // only at first directory level const SOURCE_VAULT: &str = "D:\\Cloud\\Syncthing\\obsidian-vault"; // syncthing vault folder const REPO_VAULT: &str = "C:\\Users\\robin\\AppData\\Roaming\\obsidian-git-backup\\obsidian-vault-clone"; // git repo folder -const GIT_COMMIT_DELAY_AFTER_FILE_CHANGE: Duration = Duration::from_secs(5 * 60); // 5 min +const GIT_COMMIT_DELAY_AFTER_FILE_CHANGE: Duration = Duration::from_secs(30 * 60); // 30 min #[derive(Debug)] enum UserEvent {