[git] git stash -> merge stashed change with current changes

I made some changes to my branch and realized I forgot I had stashed some other necessary changes to said branch. What I want is a way to merge my stashed changes with the current changes.

Is there a way to do this?

Its more for convenience, I eventually gave up and committed first my current changes, then my stashed changes, but I would have preferred to get them in with one fell swoop.

This question is related to git git-merge git-stash

The answer is


tl;dr

Run git add first.


I just discovered that if your uncommitted changes are added to the index (i.e. "staged", using git add ...), then git stash apply (and, presumably, git stash pop) will actually do a proper merge. If there are no conflicts, you're golden. If not, resolve them as usual with git mergetool, or manually with an editor.

To be clear, this is the process I'm talking about:

mkdir test-repo && cd test-repo && git init
echo test > test.txt
git add test.txt && git commit -m "Initial version"

# here's the interesting part:

# make a local change and stash it:
echo test2 > test.txt
git stash

# make a different local change:
echo test3 > test.txt

# try to apply the previous changes:
git stash apply
# git complains "Cannot apply to a dirty working tree, please stage your changes"

# add "test3" changes to the index, then re-try the stash:
git add test.txt
git stash apply
# git says: "Auto-merging test.txt"
# git says: "CONFLICT (content): Merge conflict in test.txt"

... which is probably what you're looking for.


The way I do this is to git add this first then git stash apply <stash code>. It's the most simple way.


you can easily

  1. Commit your current changes
  2. Unstash your stash and resolve conflicts
  3. Commit changes from stash
  4. Soft reset to commit you are comming from (last correct commit)

As suggested by @Brandan, here's what I needed to do to get around

error: Your local changes to the following files would be overwritten by merge:
       file.txt
Please, commit your changes or stash them before you can merge.
Aborting

Follow this process:

git status  # local changes to `file`
git stash list  # further changes to `file` we want to merge
git commit -m "WIP" file
git stash pop
git commit -m "WIP2" file
git rebase -i HEAD^^  # I always use interactive rebase -- I'm sure you could do this in a single command with the simplicity of this process -- basically squash HEAD into HEAD^
# mark the second commit to squash into the first using your EDITOR
git reset HEAD^

And you'll be left with fully merged local changes to file, ready to do further work/cleanup or make a single good commit. Or, if you know the merged contents of file will be correct, you could write a fitting message and skip git reset HEAD^.


May be, it is not the very worst idea to merge (via difftool) from ... yes ... a branch!

> current_branch=$(git status | head -n1 | cut -d' ' -f3)
> stash_branch="$current_branch-stash-$(date +%yy%mm%dd-%Hh%M)"
> git stash branch $stash_branch
> git checkout $current_branch
> git difftool $stash_branch

Running git stash pop or git stash apply is essentially a merge. You shouldn't have needed to commit your current changes unless the files changed in the stash are also changed in the working copy, in which case you would've seen this error message:

error: Your local changes to the following files would be overwritten by merge:
       file.txt
Please, commit your changes or stash them before you can merge.
Aborting

In that case, you can't apply the stash to your current changes in one step. You can commit the changes, apply the stash, commit again, and squash those two commits using git rebase if you really don't want two commits, but that may be more trouble that it's worth.


What I want is a way to merge my stashed changes with the current changes

Here is another option to do it:

git stash show -p|git apply
git stash drop

git stash show -p will show the patch of last saved stash. git apply will apply it. After the merge is done, merged stash can be dropped with git stash drop.


Another option is to do another "git stash" of the local uncommitted changes, then combine the two git stashes. Unfortunately git seems to not have a way to easily combine two stashes. So one option is to create two .diff files and apply them both--at lest its not an extra commit and doesn't involve a ten step process :|

how to: https://stackoverflow.com/a/9658688/32453


Examples related to git

Does the target directory for a git clone have to match the repo name? Git fatal: protocol 'https' is not supported Git is not working after macOS Update (xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools) git clone: Authentication failed for <URL> destination path already exists and is not an empty directory SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 GitLab remote: HTTP Basic: Access denied and fatal Authentication How can I switch to another branch in git? VS 2017 Git Local Commit DB.lock error on every commit How to remove an unpushed outgoing commit in Visual Studio?

Examples related to git-merge

Abort a Git Merge Git pull - Please move or remove them before you can merge Git: How configure KDiff3 as merge tool and diff tool Git: How to pull a single file from a server repository in Git? How to resolve git error: "Updates were rejected because the tip of your current branch is behind" error: Your local changes to the following files would be overwritten by checkout Please enter a commit message to explain why this merge is necessary, especially if it merges an updated upstream into a topic branch How to merge specific files from Git branches git remove merge commit from history The following untracked working tree files would be overwritten by merge, but I don't care

Examples related to git-stash

What is the intended use-case for git stash? How to recover stashed uncommitted changes How to Git stash pop specific stash in 1.8.3? Difference between git stash pop and git stash apply How to unstash only certain files? Stashing only staged changes in git - is it possible? How do I ignore an error on 'git pull' about my local changes would be overwritten by merge? git stash and git pull Stash just a single file git stash -> merge stashed change with current changes