10

In my work tree I have a mixture of files in .gitignore:

  1. Build outputs
  2. Sensitive files that shouldn't be part of the repo (e.g. passwords, connection details for local servers)

If I want to rebuild my project from scratch, I can do git clean -x to remove the build outputs in (1). But this also removes the sensitive files in (2).

Is there a way to mark a file so it's not affected by git clean while still being ignored by git commit?

Tim Robinson
  • 53,480
  • 10
  • 121
  • 138
  • I don't think there's a way to mark the file, you'll need to explicitly exclude it when running the clean command: http://stackoverflow.com/questions/11085795/git-exclude-a-file-with-git-clean – Rob Apr 28 '17 at 12:58
  • 1
    GNU Arch used to (well, it still does, but nobody uses it any more) distinguish between “junk” and “precious” files for precisely this purpose. Unfortunately, no other version control system added that distinction. – Jan Hudec Apr 28 '17 at 13:02
  • How about -X option. – Bittu Choudhary Apr 28 '17 at 13:23

3 Answers3

9

The documentation for git-clean says that -x:

-x

Don’t use the standard ignore rules read from .gitignore (per directory) and $GIT_DIR/info/exclude, but do still use the ignore rules given with -e options.

So if you want to keep, say, keys.pem, you would call

git clean -fdxe keys.pem

You can also create alias for the command.

Jan Hudec
  • 73,652
  • 13
  • 125
  • 172
  • 1
    This is nice... in my case, the files I want to keep happen to match a single pattern, so I have: `git clean -nxd -e ".*"` – Tim Robinson Apr 28 '17 at 14:44
0

Use git clean in Interactive mode:

choose filter by pattern subcommand:

This shows the files and directories to be deleted and issues an "Input ignore patterns>>" prompt. You can input space-separated patterns to exclude files and directories from deletion. E.g. "*.c *.h" will excludes files end with ".c" and ".h" from deletion. When you are satisfied with the filtered result, press ENTER (empty) back to the main menu.

RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
0

Take a look at this answer from @Borealid to the question Git - Difference Between 'assume-unchanged' and 'skip-worktree'.

It looks like using the skip-worktree flag is a good way to solve my problem. I got to your problem by looking for an answer to my problem, and I think they are essentially the same problem. However, using the skip-worktree flag, you still need to pay attention when performing certain operations and the file has changed either locally or on the remote.

Prior to learning about the skip-worktree flag, the best solution I could come up with is to use a combination of .gitignore plus an alias for git clean. It is a bit of a hack, but if your only option is to use the exclude option with git clean, then this may help.

  1. Add a consistent and unique prefix and/or postfix to any files you are modifying and do not want to commit. For example, add myusername. to the beginning of the filename.
  2. Always use git clean -dx --exclude=myusername.* (make an alias for this).
  3. Write a script that recursively walks your files and copies files beginning with myusername. to files without myusername..

Now, whenever you run cleanup, the files with the desired/true filename are going to get cleaned, but you can restore them by running the script. Also, treat the files with the true filename as readonly. Always edit the files with the kludged filenames and then run the script.

Combining these might also work to mitigate the edge cases when using the skip-worktree flag.

Mike
  • 1,227
  • 10
  • 15