git-cinnabar icon indicating copy to clipboard operation
git-cinnabar copied to clipboard

autogenerate .git/info/exclude from .hgignore when .hgignore uses syntax=glob?

Open anntzer opened this issue 5 years ago • 9 comments

It would be a nice usability improvement if, upon cloning a repository, git-cinnabar autogenerated .git/info/exclude (or offered an option to do so) from .hgignore, at least in the case where .hgignore uses syntax: glob (which should be straightforward to convert to a .gitignore).

anntzer avatar Aug 06 '19 13:08 anntzer

One thing that needs some extra thought is how to keep .git/info/exclude synchronized with .hgignore. A post-checkout hook?

glandium avatar Aug 07 '19 00:08 glandium

I guess that's way to make it optional: installing a post-checkout hook would be opt-in.

glandium avatar Aug 07 '19 00:08 glandium

What this also means is that this doesn't necessarily mean it needs to be part of git-cinnabar. Not that I would refuse the feature, but that means it can be developed completely independently.

glandium avatar Aug 07 '19 00:08 glandium

Ah, cute idea :) Now I only need to do an exegesis of the hgignore and gitignore man pages to check whether there's any subtle difference in semantics...

anntzer avatar Aug 07 '19 13:08 anntzer

Looks like the following post-commit hook does the trick (error handling could easily add more messages for the failing cases). I'm personally happy to just copy-paste it as needed, and don't know much about how it could be integrated with git-cinnabar, but feel free to adopt it.

#!/bin/sh
git cinnabar python <<EOF
from __future__ import print_function
import subprocess
import warnings
import mercurial.match
if subprocess.check_output(["git", "ls-files", ".gitignore"]):
    # There's already a tracked gitignore in the repo, don't overwrite it.
    sys.exit()
try:
    pats = mercurial.match.readpatternfile(".hgignore", warn=warnings.warn)
except IOError:
    sys.exit()
with open(".gitignore", "w") as file:
    print("# This file is autogenerated by .git/hooks/post-checkout.", file=file)
    print(".gitignore", file=file)
    for pat in pats:
        if pat.startswith("relglob:"):
            print(pat[len("relglob:"):], file=file)
        # We can't handle other patterns, so just skip them.
EOF
# vim: ft=python

anntzer avatar Aug 20 '19 18:08 anntzer

Sorry for the late reply. Somehow this got off my radar.

Why did you use .gitignore rather than .git/info/exclude?

glandium avatar Oct 08 '19 08:10 glandium

IIRC I was thinking something like "if an hg repo already has a gitignore then the repo owner must be intending it for dual use and so we shouldn't bother doing anything if a gitignore is already there" but that just seems overthinking it, so probably using .git/info/exclude is just fine.

anntzer avatar Oct 08 '19 08:10 anntzer

You could still avoid doing anything when there's already a .gitignore file...

glandium avatar Oct 08 '19 09:10 glandium

Certainly that would work too, my point was just that I wrote this a couple of weeks ago and only vaguely remember what was the rationale for the exact design I chose (which I'm not particularly wedded to).

anntzer avatar Oct 08 '19 13:10 anntzer