Skip to content
This repository has been archived by the owner on Sep 11, 2020. It is now read-only.

how to ignore files by global gitignore? #603

Open
tyru opened this issue Sep 22, 2017 · 6 comments
Open

how to ignore files by global gitignore? #603

tyru opened this issue Sep 22, 2017 · 6 comments

Comments

@tyru
Copy link

tyru commented Sep 22, 2017

I want to check if a repository has dirty worktree.
but Worktree.Status() lists up ignored files by global gitignore ($HOME/.gitconfig 's core.excludesfile).

I read COMPATIBILITY.md and it says:

Reading and modifying per-repository configuration (.git/config) is supported. Global configuration ($HOME/.gitconfig) is not.

so maybe I have to parse $HOME/.gitconfig manually, and get core.excludesfile, and check ignore files one by one.
but how?

@tyru
Copy link
Author

tyru commented Sep 22, 2017

now I can understand how to parse gitconfig, get core.excludesfile.

https://gist.github.com/tyru/75aadd7407bbff0fcc7e07a0e6095ea9/575637337368982c80063a4b4376993541c88e4b

But I cannot understand how to check ignored files.
In the above code, !m.Match(paths, false) always returns false (dirty),
regardless worktree has changed files or not.

https://gist.github.com/tyru/75aadd7407bbff0fcc7e07a0e6095ea9/575637337368982c80063a4b4376993541c88e4b#file-detect_dirty_worktree-go-L136

my $HOME/.gitconfig's core.excludesfile is ~/.gitignore.base.
and ~/.gitignore.base's content is:

tags
tags-ja

changed file paths are only doc/tags in this repository (https://github.com/tyru/open-browser.vim).

@tyru
Copy link
Author

tyru commented Sep 22, 2017

After some investigations, I confirmed gitignore.ParsePattern("tags").Match([]string{"doc/tags"}, false) returns gitignore.NoMatch here.

if match := m.patterns[i].Match(path, isDir); match > NoMatch {

and looking into that, simpleNameMatch() returns false because err == nil && !match where match, err := filepath.Match(p.pattern[0], name) (= filepath.Match("tags", "doc/tags")).

if match, err := filepath.Match(p.pattern[0], name); err != nil {

Is it expected behavior?

@tyru
Copy link
Author

tyru commented Sep 22, 2017

Wrote sample code to show my expected behavior, and filepath.Match() behavior.

func main() {
        p := gitignore.ParsePattern("tags", nil)
        res := p.Match([]string{"doc/tags"}, false)
        fmt.Println("expected 1 = Exclude but got 0 = NoMatch:", res)

        match, _ := filepath.Match("tags", "doc/tags")
        fmt.Println("this is false:", match)
}

@tyru
Copy link
Author

tyru commented Sep 23, 2017

@mcuadros @osklyar Should I send pull request? or am I wrong?

--- pattern.go	2017-09-23 12:51:41.396008300 +0900
+++ vendor/gopkg.in/src-d/go-git.v4/plumbing/format/gitignore/pattern.go	2017-09-23 12:52:39.995802400 +0900
@@ -89,7 +89,7 @@
 
 func (p *pattern) simpleNameMatch(path []string, isDir bool) bool {
 	for i, name := range path {
-		if match, err := filepath.Match(p.pattern[0], name); err != nil {
+		if match, err := filepath.Match(p.fixPattern(name), name); err != nil {
 			return false
 		} else if !match {
 			continue
@@ -102,6 +102,19 @@
 	return false
 }
 
+// Pattern which does not contain slash matches files in all subdirectories.
+//
+// pattern: "file"
+// path: "file", "path/to/file"
+func (p *pattern) fixPattern(path string) string {
+	pat := p.pattern[0]
+	if strings.Contains(pat, "/") {
+		return pat
+	}
+	dir, _ := filepath.Split(path)
+	return filepath.Join(dir, pat)
+}
+
 func (p *pattern) globMatch(path []string, isDir bool) bool {
 	matched := false
 	canTraverse := false

@osklyar
Copy link

osklyar commented Sep 23, 2017

I am sorry, but I do not quite understand what ignore pattern matching has to do with the presence of change in the repository. At best it maybe need to be applied to a different set of files, that is changed only, but the algorithm itself should not know if anything was changed or not. I also do not quite understand how your fix solves the above, that is your use case.

Do write a comprehensive test that covers the expected behaviour and goes ok with your fix while failing without. This, I would expect, you could submit as a PR.

@tyru
Copy link
Author

tyru commented Sep 25, 2017

At best it maybe need to be applied to a different set of files, that is changed only

Sorry, what else need to be applied?
I could not understand.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants