Skip to content

Git! Move!

Sometimes it's the little things... Every once in a while, we all have to rename a file in a git repo because as we've all learned -

There are only two hard things in Computer Science: cache invalidation and naming things. -- Phil Karlton

Until this morning, I'd always just gone into the file tree, right clicked on the file, and chose Rename. When you do that in a git repo though, you're "deleting" the file and creating a "new" untracked file. If you've never noticed this before, I don't blame you. For some reason I hadn't really though much about it either.

Let's say for instance that in your repo is the README.md file and (for some inexplicable reason) you rename it to test.md. When you check git status you'll see the following.

On branch develop
Your branch is up to date with 'origin/develop'.

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    README.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        test.md

no changes added to commit (use "git add" and/or "git commit -a")

You might think "ok that's weird". But it gets more interesting! if you do git reset hard you now get both files. Which I guess shouldn't come as too much of a surprise since git thinks you've created a new file and deleted the old one.

But if you use the git mv command, you can do both what you intend and something git understands. It works just like the "regular" mv command.

git mv README.md test.md

Now when you check git status you'll see this...

On branch develop
Your branch is up to date with 'origin/develop'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        renamed:    README.md -> test.md

The file still needs to be added and tracked, but git isn't confused by what you've done. How do you know? If you do git reset hard again, git correctly renames the file back to the previous commit's name.

The same approach can be applied to directories as well. In that case, git renames all the files in the directory and tracks them accordingly.

To be honest, I'm not sure how I've never noticed this before, but I'll defintely use it from now on!