Git clean

Sometimes I find myself saying WTF, why isn’t something behaving the way I expect it do, and then get frustrated. “This is not how I’d have designed it, if I was writing it”, I guess you can call this the mantra of the OSS developer 😛

But as normal, when you blaming something like git or Linux, it just means your doing something wrong or you don’t have a complete understanding of the situation. A lesson I have learnt time and time again, you’d think I’d learn but I don’t.

He’s what happened, we use git at work. Git has some very useful commands.
To return ALL repo tracked files to the state they were in at last checkout:
git reset --hard
To remove all untracked files:
git clean -df

Usually running these two allows out to go back to the point you were at last checkout, removing all compiled files, logs, etc. This is extremely useful for testing.
Also as most revision control systems have, git allows you to create ignore files (.gitignore), so you can tell git try and add certain files or folders to the repository.

OK, so for most people who use git, you’d be saying yeah of course. Well some of my work colleagues noticed that the ‘git clean’ wasn’t actually cleaning all untracked files. It was ignoring the compiled .class files and a heap of other stuff. This seemed weird, we could go to the root directory of the repository create a file, and ‘git clean’ would remove it, put it a few subdirectories down and nope wouldn’t be removed.
In fact running a dry run would return nothing.. so why wasn’t git removing these untracked files.

Well it turns out, and if you haven’t guessed by the fact I mentioned ignore files in the lead up, git is smarter then we gave it credit for. We have ignore files, so what does git do? …it ignores them!
It turns out the ignore files don’t just stop git from adding or wanting to add (telling us about hundreds of untracked files) certain files to the repo, but also, and the file suggests, ignores them in other git commands. This behaviour actually makes sense, if you wanted to keep some notes, wanted to keep them with your code, but not delete them during a ‘git clean’, then just add your notes directory to  a .gitignore file.

Turns out ‘git clean’ has another switch, created to solve the “problem” we were having:

  • -x: Don’t use the ignore rules. This allows removing all untracked files, including build products. This can be used (possibly in conjunction with git reset) to create a pristine
    working directory to test a clean build.
  • -X: Remove only files ignored by git. This may be useful to rebuild everything from scratch, but keep manually created files.

So all we needed to do is run:
git clean -dfx

NOTE: git clean, cleans from the current directory, so if you want to clean the entire repo then make sure your in the root folder of it.

This is actually an awesome feature, so yup, lesson learned again. It wasn’t a problem with git, it was a problem with my understanding! Maybe this time I’ll remember 😛