Red Green Repeat Adventures of a Spec Driven Junkie

git: clean up untracked files

I want to teach you how to clean up untracked files in a git repository. I will describe the clean up process directly showing how to use git commands, but also show you how to create files and practice on another repository.

You will learn how to clean up any git repository of untracked files in a single command! Think how popular you will be, all for less than five minutes of your time.

Jean Henri Riesener - Side Table source & more details

Introduction

As I am doing work, I like to experiment. Try out new things in different files. Overtime, the repository I am working on starts to build up files that are not tracked.

Instead of getting a clean response from $ git status:

vagrant@ubuntu-xenial:~/sample$ git status
On branch master
nothing to commit, working tree clean

This is the response I start to get:

vagrant@ubuntu-xenial:~/sample$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        blah.fz8UXZ
        work/sample.9cqzzFw
        work/t6Hnq3AqEMLh
        work/ta70LE
        work/vDqVmauTodc8/
        work/yHTxnTDmjG6R

Tracked files and untracked files intermingled together and there’s no consistent naming to things so a simple * operator won’t work. (These frameworks really love their folders!)

git to the rescue!

How can I deal with untracked files while leaving the tracked files alone simply?

git ls-files

Yup, this is where we start using core git commands to solve git problems.

From the man page: $ man git ls-files

git-ls-files - Show information about files in the index and the working tree

This merges the file listing in the directory cache index with the actual working directory list, and shows different combinations of the two.

And the option we want to solve our problem:

  -o, --others
      Show other (i.e. untracked) files in the output

Solution: git ls-files --others

With this information, the easiest way to move all untracked files in a folder to a drafts folder:

git ls-files --others | xargs -I file mv file drafts/

That way, the tracked files are in a drafts folder, add that folder to gitignore and $ git status returns:

vagrant@ubuntu-xenial:~/sample$ git status
On branch master
Your branch is up to date with 'origin/master'

nothing to commit, working tree clean

and all is right in the world.

Practice

If you want to practice this command on a separate git repository, follow these steps:

  1. Make a new folder and make that the working directory - I will use sample
    • $ mkdir sample
    • $ cd sample
  2. Add a folder inside - I made work - so it’s sample/work
    • $ mkdir work
  3. Add a file: I made sample/work/file_1.txt
    • $ touch file_1.txt
  4. Initialize git within the first folder, sample and add those files:
    • $ git init
    • $ git add .
    • $ git commit -m 'commit some work'

Now, this is the fun part, let’s make a mess! If you need help or want to know how I did it, I used: mktemp with some loops:

  1. to make random files at the base directory, use:
    • $ mktemp ./XXXXXXX
  2. to make random folders, use
    • $ mktemp -d ./XXXXXXXX
  3. to make random files in random folders, use:
    • ls -l --time-style="long-iso" work | egrep '^d' | awk '{print $8}' | xargs -I dir mktemp ./dir/XXXXXXXXX
  4. for bonus points, combine using a for loop, in bash:
    • for i in {1..5}; do mktemp work/XXXXXXXXXXXX; done

Eventually, the response from git status will be:

vagrant@ubuntu-xenial:~/sample$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        blah.fz8UXZ
        work/1pv3UGYH4vqQ/
        work/A0C8eNvWe3LZ
        work/AGzRCq
        work/H7vSJl
        work/WNE2se3klE8d
        work/Wah7Js
        work/XXuydRfQ4BMT/
        work/ateMEwjNqgKj
        work/eQV2qX
        work/fJ1bPEvqgtHb/
        work/pIP29t8uvwbP/
        work/sample.9cqzzFw
        work/t6Hnq3AqEMLh
        work/ta70LE
        work/vDqVmauTodc8/
        work/yHTxnTDmjG6R

Solutions

If you want to keep the files, move the files and folders into an untracked git directory.

For example, I will move the file into an untracked directory named: drafts:

  1. Create directory: $ mkdir drafts
  2. Add directory to .gitignore: $ echo 'drafts/*' > .gitignore
  3. Move untracked items into the folder: git ls-files --others | xargs -I file mv file drafts/
  4. Done.

If you want to remove the files, just run the following command:

git ls-files --others | xargs rm -rf`

Conclusion

Having ways to a clean repository of untracked files will bring peace of mind while allowing one to try out new things.

Using git ls-files --others makes cleaning any repository easy!

References used

Sites consulted in developing this article

  • http://moinne.com/blog/ronald/bash/list-directory-names-in-bash-shell
  • https://www.cyberciti.biz/faq/linux-unix-bash-for-loop-one-line-command/
  • https://www.cyberciti.biz/tips/shell-scripting-bash-how-to-create-temporary-random-file-name.html
  • https://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/