Merge pull request #27 from alexwlchan/ignore-dot-git-directory
- ID
3ff4e69- date
2024-12-01 20:54:05+00:00- author
Alex Chan <alex@alexwlchan.net>- parents
9bdfafa,ae450d5- message
Merge pull request #27 from alexwlchan/ignore-dot-git-directory Don't delete the `.git` directory or any subdirectories- changed files
5 files, 66 additions, 6 deletions
Changed files
CHANGELOG.md (759) → CHANGELOG.md (970)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e6e0fd8..e536447 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## v1.2.1 - 2024-12-01
+
+Don't delete the `.git` directory or any subdirectories.
+
+Messing with the internal structure `.git` can cause issues for Git, so just leave it as-is, even if it contains empty folders.
+
## v1.2.0 - 2024-08-21
Delete empty parent directories.
Cargo.lock (12734) → Cargo.lock (12734)
diff --git a/Cargo.lock b/Cargo.lock
index 6326bb4..323593c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -127,7 +127,7 @@ dependencies = [
[[package]]
name = "emptydir"
-version = "1.2.0"
+version = "1.2.1"
dependencies = [
"clap",
"colored",
Cargo.toml (200) → Cargo.toml (200)
diff --git a/Cargo.toml b/Cargo.toml
index 9d91b49..eda23c2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "emptydir"
-version = "1.2.0"
+version = "1.2.1"
edition = "2021"
[dependencies]
README.md (3224) → README.md (3575)
diff --git a/README.md b/README.md
index b823d46..ca454b6 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
This tool looks for empty directories and deletes them.
```console
-$ emptydir
+$ emptydir
```
More specifically, it deletes directories which are completely empty, or which only contain files/folders which I don't think are worth keeping (e.g. `.DS_Store` or `__pycache__`).
@@ -90,9 +90,18 @@ $ emptydir
Currently the list of files/folders which I consider safe to delete is hard-coded in `can_be_deleted.rs`:
-* `.DS_Store` stores some folder attributes used for showing the folder in the Finder, which I don't need to keep
-* `__pycache__` is the bytecode cache in Python projects, which is pointless if the original Python files have been removed
-* `.venv` is the name I use for virtual environments, which I can asily regenerate if necessary
+* .DS_Store stores some folder attributes used for showing the folder
+ in the Finder, which I don't need to keep
+* `.ipynb_checkpoints` is a folder used by Jupyter Notebooks, but not
+ important if I've deleted the notebooks
+* `.jekyll-cache` is a cache directory used by Jekyll sites, but
+ can be easily regenerated and will be rebuilt regularly as part
+ of the Jekyll build process
+* `.venv` is the name I use for virtual environments, which I can
+ easily regenerate if necessary
+* `__pycache__` is the bytecode cache in Python projects, which is
+ pointless if the original Python files have been removed
+* `Thumbs.db` is a file that contains thumbnails on Windows systems
If you want to change that list, you need to modify the source code and compile a new version -- it's not a configurable setting.
src/can_be_deleted.rs (4717) → src/can_be_deleted.rs (5954)
diff --git a/src/can_be_deleted.rs b/src/can_be_deleted.rs
index 285cdf1..22a9c94 100644
--- a/src/can_be_deleted.rs
+++ b/src/can_be_deleted.rs
@@ -19,6 +19,13 @@ fn get_names_in_directory(dir: &Path) -> io::Result<HashSet<OsString>> {
Ok(HashSet::from_iter(names))
}
+/// Returns True if this path any ancestor is a `.git` folder,
+/// False otherwise.
+pub fn is_in_git_folder(path: &Path) -> bool {
+ path.ancestors()
+ .any(|ancestor| ancestor.file_name().map_or(false, |name| name == ".git"))
+}
+
pub fn can_be_deleted(path: &Path) -> bool {
// This is a folder where I put files that I explicitly don't want
// to include in my backups.
@@ -30,6 +37,24 @@ pub fn can_be_deleted(path: &Path) -> bool {
_ => (),
};
+ // Don't delete subfolders of a `.git` directory.
+ //
+ // For example, if you delete `.git/refs`, then Git can't detect
+ // the Git directory any more. Observe:
+ //
+ // $ git init .
+ // Initialized empty Git repository in tmp.bTrs8ZaWjc/.git/
+ //
+ // $ rm -rf .git/refs
+ //
+ // $ git status
+ // fatal: not a git repository (or any of the parent directories): .git
+ //
+ // Skipping these folders is fine.
+ if is_in_git_folder(path) {
+ return false;
+ }
+
// This is the list of entries which I consider safe to delete.
//
// * .DS_Store stores some folder attributes used for showing the folder
@@ -156,4 +181,24 @@ mod test_can_be_deleted {
assert_eq!(can_be_deleted(&path), true);
}
+
+ #[test]
+ fn the_dot_git_folder_cannot_be_deleted() {
+ let path = test_dir();
+ let git_dir = path.join(".git");
+
+ create_dir(&git_dir);
+
+ assert_eq!(can_be_deleted(&git_dir), false);
+ }
+
+ #[test]
+ fn any_subdir_of_the_dot_git_folder_cannot_be_deleted() {
+ let path = test_dir();
+ let refs_dir = path.join(".git/refs");
+
+ create_dir(&refs_dir);
+
+ assert_eq!(can_be_deleted(&refs_dir), false);
+ }
}