fix: write .gitignore on vault init to exclude .DS_Store

macOS creates .DS_Store files in every folder which were being tracked
by git, causing constant conflicts when vaults are synced across machines.

init_repo() now writes a .gitignore before the first commit with:
- .DS_Store, .AppleDouble, .LSOverride
- ._ thumbnail files
- Common editor artifacts (.vscode/, .idea/, *.swp)

The file is only written if one doesn't already exist, so user-customized
.gitignore files are respected.

Two new Rust tests verify the behavior.
This commit is contained in:
Test
2026-03-06 15:19:25 +01:00
parent 5b1fda2279
commit 97be1d1ca3

View File

@@ -18,6 +18,18 @@ pub fn init_repo(path: &str) -> Result<(), String> {
run_git(dir, &["init"])?;
ensure_author_config(dir)?;
// Write .gitignore before the first commit so macOS metadata files
// are never tracked and don't cause conflicts across machines.
let gitignore_path = dir.join(".gitignore");
if !gitignore_path.exists() {
std::fs::write(
&gitignore_path,
"# macOS\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Thumbnails\n._*\n\n# Editors\n.vscode/\n.idea/\n*.swp\n*.swo\n",
)
.map_err(|e| format!("Failed to write .gitignore: {}", e))?;
}
run_git(dir, &["add", "."])?;
run_git(dir, &["commit", "-m", "Initial vault setup"])?;
@@ -927,6 +939,35 @@ mod tests {
);
}
#[test]
fn test_init_repo_creates_gitignore_with_ds_store() {
let dir = TempDir::new().unwrap();
let vault = dir.path().join("new-vault");
fs::create_dir_all(&vault).unwrap();
fs::write(vault.join("note.md"), "# Test\n").unwrap();
init_repo(vault.to_str().unwrap()).unwrap();
let gitignore = vault.join(".gitignore");
assert!(gitignore.exists(), ".gitignore should be created by init_repo");
let content = fs::read_to_string(&gitignore).unwrap();
assert!(content.contains(".DS_Store"), ".gitignore should exclude .DS_Store");
}
#[test]
fn test_init_repo_does_not_overwrite_existing_gitignore() {
let dir = TempDir::new().unwrap();
let vault = dir.path().join("new-vault");
fs::create_dir_all(&vault).unwrap();
fs::write(vault.join("note.md"), "# Test\n").unwrap();
fs::write(vault.join(".gitignore"), "custom-rule\n").unwrap();
init_repo(vault.to_str().unwrap()).unwrap();
let content = fs::read_to_string(vault.join(".gitignore")).unwrap();
assert_eq!(content, "custom-rule\n", "existing .gitignore should not be overwritten");
}
#[test]
fn test_get_file_history_with_commits() {
let dir = setup_git_repo();