mercurialhgignore

How to determine which rule is causing a file to be ignored in Mercurial?


Mercurial is presently ignoring a file which I believe shouldn't be ignored. The .hgignore file is remarkably large, and after a cursory read-through it's not obvious which rule(s) is/are the culprit.

Is there a way to get Mercurial to tell me which rules in the .hgignore (if any) match a file?


Solution

  • You can't do this out of the box, but you can write Mercurial extension for this.

    I've written extension hg-isignored that can show you which rules in .hgignore match specified folder or file.

    Installation

    Clone extension source somewhere, i.e. in ~/.hgrc.d/hg-isignored folder:

    hg clone https://hg@bitbucket.org/rpeshkov/hg-isignored ~/.hgrc.d/hg-isignored
    

    Add extension in extensions section of your .hgrc file:

    [extensions]
    isignored=~/.hgrc.d/hg-isignored/hg-isignored.py
    

    Now Mercurial will be able to use isignored command that's implemented by extension.

    Usage

    While you're in Mercurial repository, run command hg isignored PATH, where instead of PATH insert folder or file that you want to check, i.e. hg isignored readme.txt. Extension will tell you if specified PATH is ignored and will show you used rule.

    Testing

    Init

    [~/hgtest]% hg init
    

    No .hgignore

    [~/hgtest]% touch readme.txt
    [~/hgtest]% hg st  
    ? readme.txt
    [~/hgtest]% hg isignored readme.txt
    abort: .hgignore file not found
    

    Added .hgignore

    [~/hgtest]% echo "syntax: glob" > .hgignore
    [~/hgtest]% echo "readme.txt" >> .hgignore
    [~/hgtest]% hg st
    ? .hgignore
    [~/hgtest]% hg isignored readme.txt
    Path 'readme.txt' is ignored by:
    relglob:readme.txt
    

    Not ignored file

    [~/hgtest]% touch readme2.txt
    [~/hgtest]% hg isignored readme2.txt
    Path 'readme2.txt' is not ignored
    

    Ignore folder

    [~/hgtest]% mkdir build
    [~/hgtest]% touch build/keep.txt
    [~/hgtest]% echo "build/" >> .hgignore
    [~/hgtest]% hg st
    ? .hgignore
    ? readme2.txt
    [~/hgtest]% hg isignored build
    Path 'build' is ignored by:
    relglob:build/
    [~/hgtest]% hg isignored build/keep.txt
    Path 'build/keep.txt' is ignored by:
    relglob:build/
    

    Ignore everything in folder

    [~/hgtest]% echo "syntax: glob" > .hgignore
    [~/hgtest]% echo "build/*" >> .hgignore
    [~/hgtest]% hg st
    ? .hgignore
    ? readme.txt
    ? readme2.txt
    [~/hgtest]% hg isignored build
    Path 'build' is not ignored
    [~/hgtest]% hg isignored build/keep.txt
    Path 'build/keep.txt' is ignored by:
    relglob:build/*