Git – How to selectively clean a repository?



I have a git repo in which, during a build, several artifacts are produced. To make things simple:

  • Code generation produces e.g. .cpp, .h files and maybe some other types of files;
  • Build produces .o and .so files
    On top of that, the repo also stores, as tracked files, some other .cpp/.h/.o/.so files.

.gitignore is configured in such a way that a git clean -dxf effectively produces a clean repo.

However, on some occasions, i’d like to clean only build artifacts and keep generated artifacts. Sort of do a git clean -dxf but only if the file type is .foo.

I’ve look into the –exclude option of git clean, but i’m afraid it won’t do the job as I only know precisely the types of files that I want to include in the clean, but not the contrary.

For now, the closest I’d have would be something akin to (probably syntactically incorrect, but than gives the idea)

find -name "*.so" -or -name "*.os" | xargs -I {} sh -c "git ls-files --error-unmatch {} && rm {}"

Did i overlook a git command that would do the job ?




Consider just using git clean directly:

Sort of do a git clean -dxf but only if the file type is .foo.

This would be git clean -dxf -- "*.foo". The -- is not required here, it’s just generally good advice to put pathspecs behind -- in case a command might otherwise treat them as options. The double quotes are also not required in some cases, but they are in others, and they don’t hurt.1

(As an aside, .foo here is a file extension rather than a file type, at least on systems where the file’s type is determined by something other than its extension. MacOS gets some negative points here since its Unix underpinnings don’t believe in extension-based types, but so many of its apps do. 😀)

1The exact details depend on your command line interpreter, but apparently this works in CMD.EXE at least. I don’t know about PowerShell. In sh/bash, expressions like *.foo will match files—well, files and subdirectories, but directories are in many respects the same as files here—in the current directory whose names end with .foo, unless they are quoted or there are no such files. In those two cases, the literal string *.foo is passed on to Git, allowing Git to expand it in ways that are more appropriate to your task.

Answered By – torek

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave A Reply

Your email address will not be published.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More