How to resolve git stash conflict without commit?
git, git-stash
Solution
Clean solution
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):
- Manually (or ideally using some merge tool, see below) resolve the conflict(s).
- Use `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.
- Finally, remove the stash with `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
Explanation of the default behavior
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.
Merge tools
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!
Problem
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.
Related problems
- What is `git restore` and how is it different from `git reset`?
- How do I delete unpushed git commits?
- How to undo git stash clear
- git stash blunder: git stash pop and ended up with merge conflicts
- What's the best three-way merge tool?
- git stash questions
- Git Merge Conflict (UU): How do I resolve conflict without adding file to next commit?