How to combine multiple stashes in git

GitGit Stash

Git Problem Overview


This is a pipeline on branch frontend over the last two weeks.

| Stash@{3} is all code since Stash@{1} (excluding the two tiny commits)
| Tiny Commit
| Tiny commit
| Huge bulk commit two weeks ago, now rebased and moved to Stash@{1}

My working tree is currently clean.
Stash@{1} is the contents from a bulk commit of general development code two weeks ago (this should have been stashed in the first place). This commit was undone and moved to stash.
Stash@{3} is the newest work on that tree since Stash@{1} (minus a couple of changes that have been committed).

I need to combine these two stashes together in my working tree so I can make a number of commits from this huge pool of work.

I ran git stash apply stash@{1} then I tried:

git stash apply stash@{3}
git stash show -p | git stash apply stash@{3}

but I get 'dirty working tree' in both cases. How can I merge this work together? Because stash@{3} is newer, I want it to supersede stash@{1} wherever there are conflicts.

Git Solutions


Solution 1 - Git

It's a little involved, but this almost always works:

  1. Pop the first stash

     $ git stash pop
    
  2. Temporarily commit the changes from the first stash

     $ git add . && git commit -am 'WIP'
    
  3. Pop the second stash

     $ git stash pop
    
  4. Undo the temporary commit, keeping the changes it introduced

     $ git reset --soft HEAD^
    

Solution 2 - Git

You can only apply a stash if there are no conflicts with modified files in the working tree, so, first, ensure there are no modified files in git status, if there are, commit them. Then do:

git stash apply stash@{1}
git commit -a
# Enter your commit message
git stash apply stash@{3}

Then you can either make a new commit, or amend the previous one to combine them. You may need to resolve merge conflicts after each apply.

Also, if you ever decide to use git stash pop rather than apply, note that stash@{3} would become stash@{2} since the first one was popped off.

Solution 3 - Git

A better way is to just use git stash show -p stash@{whatever} > stash-{whatever}.diff and then use git apply for each one.

Solution 4 - Git

This worked for me.

  1. stage the current changes (if nothing in unstaged, skip this step)

    git add .
    
  2. apply the stash you wish

    git stash apply stash@{0}
    
  3. stage the current changes

    git add .
    

    or git add <stashed_filename>

  4. Continue step 2&3 multiple times

  5. then un stage everything

    git reset 
    

DONE!

Solution 5 - Git

I had a similar problem and solved it like this.

Use git stash pop to apply one of the stashes. Then create a patch of this stash with git diff -p > ../stash.diff. You can then reset your working tree (or stash the changes again), and pop the other stash with git stash pop stash@{1}. If you apply your patch at this moment you can 'merge' the two different stashes.

You'll probably have some conflicts to resolve. If all goes well you can then drop the stashed changes.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsscirrusView Question on Stackoverflow
Solution 1 - GitbkeepersView Answer on Stackoverflow
Solution 2 - GitAndrew MarshallView Answer on Stackoverflow
Solution 3 - GitsirideView Answer on Stackoverflow
Solution 4 - GitNIKHIL C MView Answer on Stackoverflow
Solution 5 - GitHenridvView Answer on Stackoverflow