add, stash, edit, apply and reset
This is mostly a note on how I work with git. A lot of people used to subversion wonder why I’m so enamored of Linus Torvald’s latest project and I usually only explain enough of it to convince them that git is an elaborate and complicated tool for replicating a subversion workflow. This is a good example of a situation in which svn would fail you.
I try as much as possible to create a new branch every time I decide to work on a new unit of work. Oftentimes, I will just absent-mindedly start coding and be 4 or 5 commits deep before realizing that I forgot to branch (which is a situation git has tools to fix as well), but for this particular stretch of coding I was on a clean branch without any untracked files.
Shortly after starting, I found myself with 4 classes, none of which compiled. In a minimalist vein, at home I work with only emacs and ant when hacking on Java code. ant can cause a bit of scroll blindness when your code has compile errors, and the situation is only exacerbated when you don’t quite get Java generics.
One class was named
WinLogicFactory, and it’s functionality was the end goal of this branch. The other 3 classes were support classes. They had resuable, general-purpose functionality that
WinLogicFactory would use, but contained nothing specifically related to the application I was writing. I stole the idea of them from Haskell and the classes were named
$ git status # On branch winlogic_factory # Untracked files: # (use "git add <file>..." to include in what will be committed) # # src/com/twoguys/rps/WinLogicFactory.java # src/com/twoguys/util/Either.java # src/com/twoguys/util/Left.java # src/com/twoguys/util/Right.java
Right were fixed and compiling, I couldn’t fix
WinLogicFactory, which would use them. A bit counter-intuitively I added
WinLogicFactory to the index. This allowed me to stash my current index. That left only the generic classes in my working tree:
$ git add src/com/twoguys/rps/WinLogic.java $ git stash $ git status # On branch winlogic_factory # Untracked files: # (use "git add <file>..." to include in what will be committed) # # src/com/twoguys/util/Either.java # src/com/twoguys/util/Left.java # src/com/twoguys/util/Right.java
Once I got
Right compiling I could now start working on
WinLogicFactory, so git stash apply restored the index with my broken factory in it. I had some more work to do to get it compiling and just to convince myself that I had really gotten my workspace back to it’s original state, so I ran a git reset, which effectively pulled any uncommitted changes out of staging in the index.
$ git stash apply $ git reset $ git status # On branch winlogic_factory # Untracked files: # (use "git add <file>..." to include in what will be committed) # # src/com/twoguys/rps/WinLogicFactory.java # src/com/twoguys/util/Either.java # src/com/twoguys/util/Left.java # src/com/twoguys/util/Right.java
At this point, I could fix
WinLogicFactory without worrying about simultaneous errors from
Things that are worth noting:
- staging content in git’s index is not simply another step that you have to perform before you can commit files you’ve edited. It’s how you tell git about any file you care about.
- git can manipulate code that isn’t committed. commits are merely a little extra information attached to otherwise generally useful structures that git was already creating for you.