Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,27 @@ Download build binary from the [releases](https://github.com/suin/git-remind/rel

## Configuration

Add `remind.paths` to your `.gitconfig`, using your own absolute path to the repository directories.
Add `remind.paths` to your `.gitconfig`, using your own absolute path to the repository directories.

```text:.gitconfig
[remind]
paths = /Users/you/projects/foo,/Users/you/projects/bar
```

If you have some git repositories (e.g. `~/projects/foo` and `~/projects/bar`) in the same directory (e.g. in `~/projects`) , you may specify the path using wildcard (e.g.`/Users/you/projects/*`):

If you have some git repositories (e.g. `~/projects/foo` and `~/projects/bar`) in the same directory (e.g. in `~/projects`) , you may specify the path using wildcard (e.g. `/Users/you/projects/*`):

```text:.gitconfig
[remind]
paths = /Users/you/projects/*
```

If you have a nested git repository structure (e.g. `~/projects/foobar/foo`, `~/projects/foobar/bar` and `~/projects/foo`), you may specify the path using a double asterisk (e.g. `/Users/you/projects/**`):

```text:.gitconfig
[remind]
paths = /Users/you/projects/**
```

You can also utilise the `git config` command to configure git-remind to avoid the manually editing of the `.gitconfig`.

```bash
Expand Down Expand Up @@ -76,7 +82,7 @@ C /Users/suin/projects/myapp1
CP /Users/suin/projects/myapp2
```

#### Show all status including up-to-date repositories
#### Show all status including up-to-date repositories

```
$ git-remind status -a
Expand Down
41 changes: 37 additions & 4 deletions infra/filesystem_repos.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package infra

import (
"github.com/suin/git-remind/domain"
"io/fs"
"os"
"path/filepath"
"strings"

"github.com/suin/git-remind/domain"
)

var FilesystemRepos domain.GetReposByPathPattern = func(patterns domain.GetPathPatterns) (repos []string, err error) {
Expand All @@ -12,9 +15,17 @@ var FilesystemRepos domain.GetReposByPathPattern = func(patterns domain.GetPathP
return
}
for _, pathPattern := range pathPatterns {
paths, err2 := filepath.Glob(string(pathPattern))
if err2 != nil {
return repos, err2
if strings.HasSuffix(string(pathPattern), "/**") {
path := strings.TrimSuffix(string(pathPattern), "/**")
dirs, err := searchForGitDirs(path)
if err != nil {
return repos, err
}
repos = append(repos, dirs...)
}
paths, err := filepath.Glob(string(pathPattern))
if err != nil {
return repos, err
}
for _, path := range paths {
isDir, _ := isDirectory(path + "/.git")
Expand All @@ -33,3 +44,25 @@ func isDirectory(path string) (bool, error) {
}
return fileInfo.IsDir(), err
}

func searchForGitDirs(root string) ([]string, error) {
var skipPath string
var matchedPaths []string
err := filepath.WalkDir(
root,
func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() && d.Name() == ".git" && skipPath != path {
skipPath = path
matchedPaths = append(matchedPaths, strings.TrimSuffix(path, "/.git"))
}
return nil
},
)
if err != nil {
return nil, err
}
return matchedPaths, nil
}