Reputation: 7635
As asked in this question, I also want to know how to resolve a conflicting git stash pop
without adding all modifications to a commit (just like "git stash pop" without a conflict does).
My current approach is very uncool because I do it this way:
git stash pop # -> CONFLICT
git stash drop
# [resolve conflict]
# [add conflict files]
git reset HEAD # <all files that are in commit-mode>
How to reproduce:
mkdir foo; cd foo; git init
echo "1" > one
echo "2" > two
git add -A; git commit -m "first"
echo "1.1" > one
echo "2.1" > two
git stash
echo "2.2" > two
git commit -a -m "second"
echo "Only this file would stay in HEAD without the conflict" > third
git add third
git stash pop
git status
2016-06-27: Added a new file called 'third' to the example to show that workarounds like the solution from scy only work for empty HEADs but don't fix the initial problem that the HEAD doesn't have the same content like for a git stash pop
without a conflict.
Upvotes: 720
Views: 593692
Reputation: 5999
If you specifically want to choose the version of the files in your stash, use this:
git checkout stash -- .
worked for me.
Note: as implied by the emphasized text in the introduction, this can be dangerous since it doesn't try to merge the changes from the stash into your working copy, but overwrites it with the stashed files instead. So you can lose your uncommitted changes.
Upvotes: 50
Reputation: 25401
The following solution seems to be much cleaner to me and it's also suggested by the Git itself — try to execute git status
in the repository with a conflict:
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add <file>..." to mark resolution)
Note: The restore
command has been introduced in Git version 2.23.0. Older versions of Git suggested to use the command git reset HEAD <file>...
instead of git restore --staged <file>...
. You could also use git reset
to unstage any and all files in the staging area (called the index). Restore command's equivalent is git restore --staged .
(the dot is necessary and it specifies any file). Currently, any of those commands may be used and the outcome is the same. If you want to learn about the differences between those commands, check the documentation.
So let's do what Git suggests (without making and reverting any pointless commits):
git restore --staged .
to mark conflict(s) as resolved and unstage all files in the staging area. If you want to unstage only specific files, use the command git restore --staged <file>
instead. You don't have to execute git add
before.git stash drop
, because Git doesn't do that automatically on conflict.Translated to the command-line commands:
$ git stash pop
# ...resolve conflict(s)
$ git restore --staged .
$ git stash drop
There are two ways of marking conflicts as resolved: git add
and git restore --staged <file>...
. While git restore --staged <file>...
marks the conflicts as resolved and removes files from the index, git add
also marks the conflicts as resolved, but keeps files in the index.
Adding files to the index after a conflict is resolved is on purpose. This way you can differentiate the changes from the previous stash and changes you made after the conflict was resolved. If you don't like it, you can always use git restore --staged .
to remove everything from the index.
I highly recommend using any of 3-way merge tools for resolving conflicts, e.g. KDiff3, Meld, etc., instead of doing it manually. It usually solves all or the majority of conflicts automatically itself. It's huge time-saver!
Upvotes: 876
Reputation: 135
please make sure that if you are using source tree for git, they will say that commit your changes or conflicts. Please don't do that,
Instead of opening your terminal and type
git add .
git stash
this source tree is telling 'commit your changes because they don't know if this change is conflicted or not but they are trying to take a backup for safety.
This git stash command will delete your merged conflicts. Thank you.
Upvotes: 1
Reputation: 5415
Answer for people having trouble with git stash -u
not applying cleanly
What if you have a stash created with git stash -u
? Then most of the answers to this question are invalid! Because as soon as you follow the advice given in the highest ranked answer (this one: https://stackoverflow.com/a/27382210/816017) - i.e. using git stash drop
(my advice: don't do it) your unstaged files are gone.
That was a long-winded introduction to say the following:
If you have troubles with a Merge conflict
when doing git stash pop
, and you have used git stash -u
, then one way to get out of that situation is this:
git stash branch my-stash-branch
git restore myfile
, then apply the changes manuallyCargo.lock
or yarn.lock
just git restore Cargo.lock
.git stash -u
againgit checkout my-actual-branch
git stash pop
which should apply cleanly now, otherwise rinse & repeatmy-stash-branch
once you are confident your changes have been applied correctly.In short: the answer claiming "Don't follow other answers..." in a large bold font, is not the answer for everybody! ESPECIALLY not if you used git stash -u
. Your changes may be lost!
Footnotes:
git stash drop
can probably be found if you dig through git fsck
- they're not in the reflog
if I am not mistaken.Upvotes: 2
Reputation: 1317
No problem there. A simple git reset HEAD
is what you're looking for because it leaves your files as modified just like a non-conflicting git stash pop
.
The only problem is that your conflicting files will still have the conflict tags and git will no longer report them as conflicting with the "both_modified" flag which is useful.
To prevent this, just resolve the conflicts (edit and fix the conflicting files) before running git reset HEAD
and you're good to go...
At the end of this process your stash will remain in the queue, so just do a git stash drop
to clear it up.
This just happened to me and googled this question, so the solution has been tested.
I think that's as clean as it gets...
Upvotes: 11
Reputation: 1343
Its not the best way to do it but it works:
$ git stash apply
$ >> resolve your conflict <<
$ >> do what you want to do with your code <<
$ git checkout HEAD -- file/path/to/your/file
Upvotes: -2
Reputation: 929
git add .
git reset
git add .
will stage ALL the files telling git that you have resolved the conflict
git reset
will unstage ALL the staged files without creating a commit
Upvotes: 38
Reputation: 562
The fastest way I have found is to resolve the conflict, then do git add -u
, and then do git reset HEAD
, that doesn't even involve a commit.
Upvotes: 4
Reputation: 7281
Suppose you have this scenario where you stash your changes in order to pull from origin. Possibly because your local changes are just debug: true
in some settings file. Now you pull and someone has introduced a new setting there, creating a conflict.
git status
says:
# On branch master
# Unmerged paths:
# (use "git reset HEAD <file>..." to unstage)
# (use "git add/rm <file>..." as appropriate to mark resolution)
#
# both modified: src/js/globals.tpl.js
no changes added to commit (use "git add" and/or "git commit -a")
Okay. I decided to go with what Git suggested: I resolved the conflict and committed:
vim src/js/globals.tpl.js
# type type type …
git commit -a -m WIP # (short for "work in progress")
Now my working copy is in the state I want, but I have created a commit that I don't want to have. How do I get rid of that commit without modifying my working copy? Wait, there's a popular command for that!
git reset HEAD^
My working copy has not been changed, but the WIP commit is gone. That's exactly what I wanted! (Note that I'm not using --soft
here, because if there are auto-merged files in your stash, they are auto-staged and thus you'd end up with these files being staged again after reset
.)
But there's one more thing left: The man page for git stash pop
reminds us that "Applying the state can fail with conflicts; in this case, it is not removed from the stash list. You need to resolve the conflicts by hand and call git stash drop
manually afterwards." So that's exactly what we do now:
git stash drop
And done.
Upvotes: 308
Reputation: 11
According to git stash questions, after fixing the conflict, git add <file>
is the right course of action.
It was after reading this comment that I understood that the changes are automatically added to the index (by design). That's why git add <file>
completes the conflict resolution process.
Upvotes: 1
Reputation: 2669
It seems that this may be the answer you're looking for, I haven't tried this personally yet, but it seems like it may do the trick. With this command GIT will try to apply the changes as they were before, without trying to add all of them for commit.
git stash apply --index
here is the full explanation:
http://git-scm.com/book/en/Git-Tools-Stashing
Upvotes: 6
Reputation: 1400
git stash branch
will works, which creates a new branch for you, checks out
the commit you were on when you stashed your work, reapplies your work there, and
then drops the stash if it applies successfully. check this
Upvotes: 2
Reputation: 17586
Instead of adding the changes you make to resolve the conflict, you can use git reset HEAD file
to resolve the conflict without staging your changes.
You may have to run this command twice, however. Once to mark the conflict as resolved and once to unstage the changes that were staged by the conflict resolution routine.
It is possible that there should be a reset mode that does both of these things simultaneously, although there is not one now.
Upvotes: 94