How do I save work in progress without using git-stash?

I have a git directory with this situation:

ProgSoul@PROGSOUL-LENOVO:~/esercizio3_2$ git status
Sul branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   A

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

        modified:   A

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


In this situation I have:

  • there is a file named A in the index with a string “AA” inside it
  • I modified the file A with “AAA” inside it but I didn’t add this change on the stage. So in the working directory I have A with a string “AAA” inside it
  • an untracked empty file B

My teacher wants me to temporarily suspend my work, create a BUGFIX file, commit it and restore my previous situation.

I achieved it through these commands:

git stash --include-untracked
touch BUGFIX
git add BUGFIX
git commit -m "Aggiunto file BUGFIX"
git stash pop --index

With these commands I saved my initial situation and restored it once my fix has been commited.
My teacher also asked me to reach this goal without using git-stash.

I followed the help in the stash documentation:

git checkout -b WIP
git commit -a -m "WIP"
git checkout master
touch BUGFIX
git add BUGFIX
git commit -a -m "BUGFIX"
git checkout WIP
git reset --soft HEAD^

With git reset –soft I restored the index but the changes not staged for commit have been lost.

With git reset –mixed I restored the changes not staged for commit but the index has been lost.

How can I restore the same initial situation once I commit the fix without using git stash?

  • How do you stash only files that have been added?
  • How to remove/avoid committed files to go to master Branch from remote branch
  • aborting a git merge and going back to uncommitted work
  • Git Branch is not a remote Branch in Stash
  • Why does `git stash -p` sometimes fail?
  • No changes for files visible after stashing/unstashing
  • Delete all Git Commit History
  • Does each branch have a separate stash?
  • 3 Solutions collect form web for “How do I save work in progress without using git-stash?”

    Let’s try it this way:

    • Q: How can you save something in Git?

    • A: Commit it.

    • Q: What about git stash, it seems to save things, how does it manage that?

    • A: It commits.

    • Q: But it doesn’t put any commits on my branch.1

    • A: They’re on the special “stash” thing, which is not a branch. But they’re still commits.

    1This is, technically, not a question. 🙂

    If you want to save something in Git, commit it

    This is the Git bottom line, as it were: a commit saves things. Otherwise all you have is stuff in your work-tree, and stuff in your index (staging-area). The staging-area stuff becomes permanent when you run git commit. The work-tree stuff is never permanent: you have to copy it to the staging area and then commit it.

    This is what git stash does. It actually makes two commits, one for the current index, and one for the work-tree.2 It just makes them both on something other than a branch, using the name stash to find them instead.

    There’s nothing stopping you from making your own commits, though. It’s just a bit of a pain to make two or more commits and then have to undo them, which is why git stash exists.

    2When you use --include-untracked as you did, it actually makes three commits: one for the index, a second for the work-tree, and a third one for the untracked files. That third commit is extra-tricky, both to make and to restore. The stash script uses a temporary index rather than trying to do the work in the main index.

    You can always use another clone

    Each Git repository is, in general, independent of all other Git repositories, but can peer with any related Git repository. So you can clone one repository to another, and thereby get another work-tree where you can do work. This work-tree also comes with its own (separate) index / staging-area.

    If you make the clone locally, on your local file system, Git is often able to avoid a lot of repository-file copying. So while this might seem expensive, it’s usually not that bad. The main problem is that you now have two repositories to remember to commit-to, and you must fetch and/or push between them and/or whatever upstream you originally cloned from.

    For quick side work, git worktree add (2.5 and newer only)

    Before Git 2.5 there was a “contributed” script to make alternate work-trees. As of 2.5 it became officially supported, though there were some important bug fixes since then (and even now it has some rough edges). You can now run git worktree add to create a new worktree that will use a different branch, but share the underlying repository.

    No two work-trees that share one underlying repository may use the same branch. (This is because of the way Git stores its idea of the “current branch” and “current commit”, and the way Git advances the current branch when you make a new commit.) If your goal, however, is to make a fix in some other branch than the one you are working on now, this is just what you need anyway.

    Git’s got a little-known feature just for this, built in.

    echo fix fix >> BUGFIX
    git add BUGFIX
    git commit BUGFIX

    … and if BUGFIX were already tracked, you wouldn’t even need the git add, it’d do that for you. See point 3 of the git commit description:

    listing files as arguments to the commit command (without –interactive or –patch switch), in which case the commit will ignore changes staged in the index, and instead record the current content of the listed files (which must already be known to Git);

    and although the description doesn’t say it, the current contents are added to the index as well as the commit.

    Thanks to every answer I received. I achieved two possible solutions:

    git worktree add -b BUGFIX ../bugfix_temp master
    pushd ../bugfix_temp
    touch BUGFIX
    git add BUGFIX
    git commit -a -m "emergency BUGFIX"
    rm -rf ../bugfix_temp
    git worktree prune


    touch BUGFIX
    git add BUGFIX
    git commit --only BUGFIX -m "emergency BUGFIX"
    Git Baby is a git and github fan, let's start git clone.