Alex ChaffeeAlex Chaffee
git unadd
edit Posted by Alex Chaffee on Wednesday September 02, 2009 at 03:16PM

Sometimes I accidentally git add files. Or more often, I do git add . and get a huge changelist and then realize I want to move certain files to a different changelist or a different branch. I could do a git reset which, absent --soft or --hard, pulls all the changes out of the index (aka dircache aka staging area) but leaves them in the filesystem (aka working tree). But wouldn't it be nice to leave all the files in the index except the few I want to keep out?

Yes. Yes, it would. And believe it or not, git has been telling you how, every time you do a git status. Like me, you've probably seen this line often enough for it to be completely invisible:

#   (use "git reset HEAD <file>..." to unstage)

"Oh," I hear the whole Internet saying, "that's what that means.

"But why," you continue, "instead of documenting an obscure feature at runtime during a tangentially related operation, wouldn't they just provide a simple git unadd command?"

Fortunately, you can just run

git config --global alias.unadd "reset HEAD"

and now you can do

git unadd foo.txt bar.txt

and only those files will be pulled out of your index. (Unfortunately, the silly overcommunication is not removed this time.)

Comments

  1. Alex Chaffee Alex Chaffee on September 02, 2009 at 03:28PM
  2. Sebastian Sebastian on September 02, 2009 at 05:51PM

    Any particular reason you didn't go for "remove"? "unadd" seems almost as obscure as "reset HEAD".

  3. Alex Chaffee Alex Chaffee on September 02, 2009 at 06:10PM

    "remove" is an expansion of "rm" and means something else altogether in Gitistan -- see that FAQ link in my earlier comment. I agree that git terminology is hazy at best but I'm not in a position to fix it, and after browsing Google it seems many others share my intuition that you'd call undoing an add an "unadd".

  4. Tom Ward Tom Ward on September 02, 2009 at 11:49PM

    Nice little trick, now added to my aliases. Thanks for sharing.

  5. Brandon Thomson Brandon Thomson on September 04, 2009 at 12:11AM

    Thanks, this is useful... Now I'm worried my custom git configs might end up as long ad my vim config!

  6. grosser grosser on September 08, 2009 at 10:38PM

    I got this aliased to git unstage and more @ http://github.com/grosser/dotfiles/blob/master/gitconfig ;)

  7. Jack Dempsey Jack Dempsey on September 08, 2009 at 10:48PM

    Cool stuff Alex. For those who may not know, HEAD is the default:

    " Commit to make the current HEAD. If not given defaults to HEAD."

    So, its really just typing unadd instead of reset. I can see how that will work nicely and all, but sometimes I find myself in a land without personal aliases and wishing I hadn't used so many. ymmv.

  8. Mark Wilden Mark Wilden on October 15, 2009 at 10:05AM

    Even when I'm on a system without all my pretty aliases, it's useful to know that git is case-insensitive by default, so you can type 'head' instead of 'HEAD'.