Search code examples
gitgitignoregit-plumbing

How to exclude files in Git while disregarding .gitignore?


Background

I'm migrating a VCS to git. This is done by checking out from the old VCS (TFSVC) and checking into a git repository via scripts.

Essentially in such a loop:

for x in $(seq 1 100)
do
  tf get $x  # get version x
  git add .  # add everything to index
  git commit # commit
done

Problem

The old VCS contains a .gitignore, as a part of the migration process, I don't want these patterns to apply. This can easily be fixed using git add . --force. The problem is that there are still things that I may want to ignore.

What I've tried

I was hoping to use .git/info/exclude for the purpose, but git-add --force apparently ignores this in addition to .gitignore rules. It seems the same goes for core.excludesFile.

Ideal solution

  • Exclude the rules of .gitignore
  • Use the rules in .git/info/exclude or some other exclude file or pattern
  • Somewhat performant, the process is slow enough as it is
  • Doesn't rely on modifying the working tree

An option is of-course to simply git restore --staged $EXCLUDE_PATH_SPEC after adding everything to the index but I'm wondering if there isn't a better solution.

I seem to recall seeing an option for specifying an ignore/exclude glob but I can't seem to be able to find it.

Maybe there's a way to achieve this using a plumbing commands, like git update-index?


Edit

I've added clarification that I'd rather not rely on a solution that modifies the working tree (ie: moving/modifying .gitignore) since it's been suggested multiple times. Mainly because of these reasons:

  1. There are nested .gitignore files
  2. Their existence and contents rely on the state of the other VCS, I want to be in full control
  3. There is another VCS tracking the files and so anything modifying the working tree, besides the incremental fetching from the other VCS complicates matters
  4. It's in all likelihood slower (although maybe not slow enough to be a major concern)

Solution

  • If the standard conveniences aren't what you want, make your own with core commands. git ls-files lets you build your exclusions as you like, and git update-index will take anything you want.

    git ls-files -ocX /path/to/my/excludes \
    | git update-index --add --remove --stdin
    
    git ls-files git update-index
    • --add If a specified file isn’t in the index already then it’s added.
    • --remove If a specified file is in the index but is missing then it’s removed.
    • --stdin Instead of taking list of paths from the command line, read list of paths from the standard input