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
This commit is contained in:
Wang Can 2024-12-13 10:29:37 +08:00 committed by GitHub
parent 4eaa1c2514
commit e0cbbf8d06
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -780,7 +780,10 @@ impl Fs for RealFs {
}
fn open_repo(&self, dotgit_path: &Path) -> Option<Arc<dyn GitRepository>> {
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(),