Closed pythys closed 1 year ago
Perhaps we can add a flag to the above idea if performance is an issue. I will investigate the code to see if I can contribute to that bit
Hey, I saw your other issue and agree that it's a use case makes sense to support.
I share your concern about performance. For the most common use case, I expect the repositories to usually be quite "high" in the file tree, so they will be found quickly and recursion stops. Also, repositories may contain a lot of files and directories to search through.
I thought about only going through paths that are part of .gitignore
, but this has two issues:
.gitignore
). Too many what-ifs in my view.I think having a command line flag, as you suggested, would be the best option.
I will investigate the code to see if I can contribute to that bit
Awesome!
The relevant code would be in the find_repo_paths()
function. As you can see, it's recursive, but stops as soon as a git repository is found.
Adding a command line flag would be straightforward.
Let me know if you need any more information. Otherwise, just go for it, we can discuss implementation details on a PR!
On my first attempt, I got nesting to work perfectly well. BUT I think two things are missing to make a PR:
diff --git a/src/tree.rs b/src/tree.rs
index c53882f..3f818c0 100644
--- a/src/tree.rs
+++ b/src/tree.rs
@@ -100,43 +100,43 @@ pub fn find_repo_paths(path: &Path) -> Result<Vec<PathBuf>, String> {
if git_dir.exists() || git_worktree.exists() {
repos.push(path.to_path_buf());
- } else {
- match fs::read_dir(path) {
- Ok(contents) => {
- for content in contents {
- match content {
- Ok(entry) => {
- let path = entry.path();
- if path.is_symlink() {
- continue;
- }
- if path.is_dir() {
- match find_repo_paths(&path) {
- Ok(ref mut r) => repos.append(r),
- Err(error) => return Err(error),
- }
- }
+ }
+
+ match fs::read_dir(path) {
+ Ok(contents) => {
+ for content in contents {
+ match content {
+ Ok(entry) => {
+ let path = entry.path();
+ if path.is_symlink() {
+ continue;
}
- Err(e) => {
- return Err(format!("Error accessing directory: {}", e));
+ if path.is_dir() {
+ match find_repo_paths(&path) {
+ Ok(ref mut r) => repos.append(r),
+ Err(error) => return Err(error),
+ }
}
- };
- }
- }
- Err(e) => {
- return Err(format!(
- "Failed to open \"{}\": {}",
- &path.display(),
- match e.kind() {
- std::io::ErrorKind::NotADirectory =>
- String::from("directory expected, but path is not a directory"),
- std::io::ErrorKind::NotFound => String::from("not found"),
- _ => format!("{:?}", e.kind()),
}
- ));
+ Err(e) => {
+ return Err(format!("Error accessing directory: {}", e));
+ }
+ };
}
- };
- }
+ }
+ Err(e) => {
+ return Err(format!(
+ "Failed to open \"{}\": {}",
+ &path.display(),
+ match e.kind() {
+ std::io::ErrorKind::NotADirectory =>
+ String::from("directory expected, but path is not a directory"),
+ std::io::ErrorKind::NotFound => String::from("not found"),
+ _ => format!("{:?}", e.kind()),
+ }
+ ));
+ }
+ };
Ok(repos)
}
I should note that with the above fix:
Pull request created
Great work, I really like the project and thank you for your initiative.
In reference to #48 it would be great if
grm repos find local
would not stop as soon as it finds a repository but it would continue to walk the directory tree to find other possible git repos. Some projects have a pattern of adding some directory to .gitignore and then putting sub repositories over there without adding them as submodules.