From e0cbbf8d065ce6eb73b5b71ce20e02f06b388b7d Mon Sep 17 00:00:00 2001 From: Wang Can Date: Fri, 13 Dec 2024 10:29:37 +0800 Subject: [PATCH] Fix opening repos when `.git` is a soft link (#21153) Closes #ISSUE ## background If a project is big, some times it will be splited into many small git repos. [google repo](https://gerrit.googlesource.com/git-repo/) is a tool to manage a group of git repos. But, any small git repo manged by this tool, have a difference with normal git repo. That is , the path `.git` in the root of the git repo, is not a normal directory, but a soft link to real git bare dir. ### zed can not recognize the `git-repo` managed git repos you can use the procedure to genreate this problem ```bash # tested on linux mkdir -p bad_git_repo_project cd bad_git_repo_project git init echo "hello" > hi.txt git add . git commit -m "init commit" echo "hello world" >> hi.txt # modify the repo mv .git ../.real_git_repo ln -sf ../.real_git_repo .git ``` with vscode, after opening this project, git works well. but for Zed, git not work(not git status, no git blame) ## how to fix libgit2 can recognize git repo from the root of the project(dir that have `.git`). so, we can recognize the git project by opening from the project root dir, but not the `.git` dir This fix also works with normal git project. ### before fix ![image](https://github.com/user-attachments/assets/1fb53ff4-4ab1-402e-9640-608ca79e12a4) ### after fix ![image](https://github.com/user-attachments/assets/6b16bc54-34f0-4436-b642-3c5fa8b669bd) Release Notes: - Fix opening repos when .git is a soft link --- crates/fs/src/fs.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/fs/src/fs.rs b/crates/fs/src/fs.rs index 0706c0e41c..0a0d2be6cd 100644 --- a/crates/fs/src/fs.rs +++ b/crates/fs/src/fs.rs @@ -780,7 +780,10 @@ impl Fs for RealFs { } fn open_repo(&self, dotgit_path: &Path) -> Option> { - let repo = git2::Repository::open(dotgit_path).log_err()?; + // with libgit2, we can open git repo from an existing work dir + // https://libgit2.org/docs/reference/main/repository/git_repository_open.html + let workdir_root = dotgit_path.parent()?; + let repo = git2::Repository::open(workdir_root).log_err()?; Some(Arc::new(RealGitRepository::new( repo, self.git_binary_path.clone(),