How to reliably convert a .gitignore file into a list of pathspec strings that can be passed to individual git commands?
I want to have a javascript function that can take any .gitignore file as input, and output a long string that can then be passed to the git diff --numstat <commit1> <commit2> command as pathspec to act as a temporary gitignore only for that operation. So the resulting strings should mimic the original gitignore rules as closely as possible in functionality.
It's not just enough to append the rules to :(exclude), since the rules are different for git pathspec compared to gitignore (e.g. not recursive by default). And lines with negation patterns would just be ignored since I found out that those aren't supported when you're also using the :(exclude) magic word.
Example .gitignore:
docs
Assumed pathspec conversion:
:(exclude,glob)**/docs :(exclude,glob)**/docs/**
Since pathspec can't match a path for both files and folders but needs separate entries for each, and when you specify glob, all patterns aren't recursive/relative by default.
But glob allows for magic characters like *![] to be used.
Rules would also need to be properly escaped since they will be passed to the command line.
The goal is to covnert rules used in .gitignore to pathspec equivalents as closely as possible. AFAIK there is no existing tool for this?
1 Answer 1
I think one easier way to implement this(ignore files that match patterns in .gitignore) is using ATTR in pathspec.
Use new ATTR like ignore in .gitattributes, something like the following:
weekly/25_01* ignore
weekly/25_01*/** ignore
And use git diff ... -- ':(attr:!ignore)' which mean use files that is unspefied in attribute ignore. So any files not matched by weekly/25_01* and weekly/25_01*/** is included, which has the same meaning as weekly/25_01* in .gitignore
I think both .gitignore and .gitattributes use almost the same pattern specification except for some minor differences like the above. weekly/25_01* matches files and directories in .gitignore but it matches only files in .gitattributes
.gitignorefile, then run your command, then undo the.gitignorefile? If yes, this may be a decent workaround, or at least it may help guide testing for a solution to your question as asked.git diffcompares commits;.gitignoreignores untracked files, it shouldn't work withgit diffand I don't know any way to makegit diffto take.gitignoreinto account.git diffis the changes between commit1 and commit2.) Now write a temporary .gitignore, then rungit diffagain to see the 'filtered" diff. (Actually this doesn't work either for modified files...only new ones.)/path/to/foo. Rungit diff --name-only <commit1> <commit2> | git -C /path/to/foo -c core.excludesFile=/path/to/gitignore check-ignore --stdinto get the ignored files. Then you can either convert these ignored files toexcludepathspecs and pass them togit diff --numstat, or parse the output ofgit diff --numstatand remove the ignored files. This process can be adjusted and improved.