Search code examples
gitgithubgithub-for-windows

How can I save my files without committing with Git?


I'm using git with Github as a de-facto backup solution in addition to source control and am working on a large feature. This feature has been pretty gnarly. I'm focused on finishing adding all the enhancements, but know that there will definitely be a ton of cleanup to do afterwards on all the code that I've added since the last commit.

Usually I make commits pretty frequently at logical checkpoints in the development process, but this time I've been holding off because committing would make it harder to find all the code that needs to be cleaned up. Right now I can see a list of uncommitted files + changes in the Github Client for windows, and my IDE, Android Studio, clearly shows files that have uncommitted changes as well.

I have an additional backup solution but was wondering if anyone has a good system in place for these situations - when you don't want to rubber-stamp/commit unfinished code but want to save it somehow in git?


Solution

  • If your question is about saving files in Git without making commits, the answer is easy: you can't.1

    If your question is how to save files outside of Git, the answer is also easy: just save them outside of Git. Git itself does not enter the picture here.

    The key to understanding this is a simple—but initially surprising—fact: the files that you can see and work on/with, when you use Git, are not in Git. The files that get saved inside a commit are in Git, but are not the files that you can see and work on/with. They're not even made directly from those files. Instead, when you run git add, Git copies the files that you can see-and-work-with to hidden, ready-to-commit copies. When you run git commit, that is when those hidden, ready-to-commit copies get saved.

    There are a couple of Git commands that are not spelled git commit that nonetheless do make commits, and therefore do save files in Git. For instance, the git stash command that austurist mentions makes either two or three commits (two is the normal setup; you get 3 if you use git stash -u or git stash -a).

    You mention in a comment:

    I still want my changes to be in the working directory to build off

    Your working tree is yours, to do with as you will. The files here are not in Git so you can do anything you like with them. Just remember that:

    • git checkout, and some other Git commands, act as explicit requests to replace the files in your working tree;
    • git add tells Git to copy some or all files, as they appear in your working tree, into Git's index aka staging area, so that they're ready to go into the next commit.

    The index / staging-area initially matches whatever commit you checked out, which is why the proposed next commit initially matches the current commit.


    1As implied by the above, this is not quite 100% true. You can, for instance, use non-committing commands to copy some individual files somewhere: git hash-object -w will take file contents (not a file, just its contents) and turn this into an internal blob object. This method is rather fraught, though: unreferenced blobs can be garbage collected. To prevent them from being garbage collected, you have some time—14 days by default—during which you can build tree objects that refer to them by name, and then build commit objects that refer to the tree objects, and use a reference, such as a branch or tag name, to make the commit object have an external name that keeps the whole assembly from being garbage collected.

    Alas, this is just a long-winded way of doing git commit. But you can break it down a bit, and hence get away without committing for 13 days (or longer if you tweak your GC age settings). It's not worth it, though. Just commit, or save files outside of Git.