Search code examples
gitbackupgitignore

backup all gitignored files from a working copy


I am workin on a git repository. I have a working copy, with huge file list.

My .gitignore looks like

roo/output*  # ignore set of folders
*.pyc           # ignore a filetype
root/a_folder   # ignore a folder
root/filemame*.txt # ignore a set of files
root/**/.bin # ignore an extension within a folder

Now I would like to create a new working copy. In order for it to work, I also need the files which are gitignored in the original wc.

I have tried some of the answers here:

Git command to show which specific files are ignored by .gitignore

git check-ignore * # return only folders for me

git status --ignored # takes forever to run
git ls-files --others -i --exclude-standard # returns empty for me

I would need to get this list with the original path names, so that I can create a zip file keeping the folder structure so that I can unzip it seamlessly in the new working copy.


Solution

  • Well, we can look at how to make git check-ignore work better, but this seems like a bit of over-engineering. If you only need to do it once, just figure out what to include form the patterns you know are in the ignore file. (I'm ignoring this directory, so I'll zip up this directory. etc.) If you need to do this routinely, you might want to revisit how you're using ignore rules.

    Anyway, the check-ignore command may output files and/or directories, with two caveats:

    First, you need to tell it if you want to search subdirectories. If you just say git check-ignore * then it will only search the current directory. Instead you might want

    git check-ignore * **/*
    

    But even then, the second problem comes up when you exclude a directory a/, and that directory contains another directory a/b/. There's bad news and worse news.

    The bad news is, it doesn't search inside a/b/ even with the **/* pattern; once it sees that a/b/ is excluded, it just lists that and moves on.

    The worse news is, if any non-excluded paths exist inside a/b/ (e.g. because they were added before the path was ignored, or because they were added with -f), then a/b/ is not listed, and it still doesn't search under a/b/ to find if more specific paths really are excluded. This seems to me like a bug. As a partial work-around, you can say

    git check-ignore --no-index **/* *
    

    and it will list the directory, but still won't search inside the directory - which means you have some implicit false positives (since some things in that directory are not ignored files).

    So... if you either (a) know that the index contain no entries for files at paths that would otherwise be ignored, or (b) can get by with possibly picking up some non-ignored files by using --no-index, then you could use the `check-ignore output. In cases where you see a directory, you'd just include that entire directory (and its contents, recursively) in the ZIP.

    In the case where this would copy a file that isn't really ignored, I guess doing something like

    git checkout -- a/b
    

    after extracting your ZIP should address that. (You can always use git status after extracting the ZIP to verify if there are any non-ignored changes you'd want to undo.)