Commit a924d426 authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Complete the git implementation

All known ignore files should now be loaded by the git loader.
README.md has been updated to reflect all the known file locations
(including config file locations for the `core.excludesfile` value).
parent b13cef6b
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -44,11 +44,9 @@ Git ignore files are searched for at the following locations:

 * A `.gitignore` file in each ancestor of the target directory up to the top
   of the repository workspace.
 * `$GIT_DIR/info/excludes`
 * `$GIT_DIR/info/exclude`
 * A file named by the git config value `core.excludesfiles` which defaults to
 	 the first found of:
   - `$XDG_CONFIG_HOME/git/ignore`
   - `$HOME/.config/git/ignore`
   `$XDG_CONFIG_HOME/git/ignore`[^3]
 * A `.gitignore` file in each scanned directory within the target directory.
   (Directories that are excluded by a previous ignore file are not scanned.)

@@ -57,5 +55,12 @@ directories under the directory where the file was found.

Git configuration variables are searched for in the following files:

 * `$GIT_DIR/config`
 * `/etc/gitconfig`[^4]
 * `$XDG_CONFIG_HOME/git/config`[^3]
 * `$HOME/.gitconfig`
 * `$GIT_DIR/config`

[^3]: `$XDG_CONFIG_HOME` defaults to `$HOME/.config`
[^4]: This should be `$(prefix)/etc/gitconfig` but the `$(prefix)` value of git 
      is unknown, and many platforms & distributions override the location 
      anyway.
+31 −9
Original line number Diff line number Diff line
from os import path
from os import path, environ
from configparser import ConfigParser, NoOptionError

from .. import loaders, patterns, rules
from .. import loaders, patterns, rules, util


GIT_REPO = '.git'
EXCLUDE_FILE = '.git/info/exclude'
GITIGNORE_FILE = '.gitignore'


@@ -16,10 +16,37 @@ class GitLoader(loaders.Loader):
		self.rules = rules.Rule(project_root, '', pattern, with_path=False)
		self.tails = [self.rules, None]

		home = environ['HOME']
		home_config = environ.get('XDG_CONFIG_HOME', path.join(home, '.config'))
		git_dir = environ.get('GIT_DIR', path.join(project_root, GIT_REPO))

		# ancestor .gitignore files
		while target_path:
			target_path = path.dirname(target_path)
			self.load_from_dir(target_path)

		# $GIT_DIR/info/exclude files
		excludes_file = path.join(git_dir, 'info/exclude')
		with util.ignore_if_missing():
			self.load_patterns('', excludes_file)

		# core.excludesfile
		config_files = [
			'/etc/gitconfig',
			path.join(home_config, 'git/config'),
			path.join(home, '.gitconfig'),
			path.join(git_dir, 'config'),
		]
		config = ConfigParser()
		config.read(config_files)
		try:
			excludes_file = config.get('core', 'excludesfile')
		except NoOptionError:
			excludes_file = path.join(home_config, 'git/ignore')
		with util.ignore_if_missing():
			self.load_patterns('', excludes_file)


	@classmethod
	def is_project_root(cls, dirpath):
		return path.isdir(path.join(dirpath, GIT_REPO))
@@ -32,12 +59,7 @@ class GitLoader(loaders.Loader):
			return

		abs_dirpath = path.join(self.project_root, dirpath)

		if path.samefile(abs_dirpath, self.project_root) \
		and path.exists(path.join(abs_dirpath, EXCLUDE_FILE)):
			self.load_patterns(dirpath, EXCLUDE_FILE)

		if path.exists(path.join(abs_dirpath, GITIGNORE_FILE)):
		with util.ignore_if_missing():
			self.load_patterns(dirpath, GITIGNORE_FILE)


list_files/util.py

0 → 100644
+11 −0
Original line number Diff line number Diff line
import errno
from contextlib import contextmanager


@contextmanager
def ignore_if_missing():
	try:
		yield None
	except IOError as exc:
		if exc.errno != errno.ENOENT:
			raise