How to resolve git stash conflict without commit?

2019-01-20 21:14发布

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>

[Update] A way to reproduce it:

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.

标签: git git-stash
10条回答
Explosion°爆炸
2楼-- · 2019-01-20 21:18

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.

查看更多
干净又极端
3楼-- · 2019-01-20 21:21

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.

查看更多
来,给爷笑一个
4楼-- · 2019-01-20 21:26
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

查看更多
唯我独甜
5楼-- · 2019-01-20 21:29

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

查看更多
走好不送
6楼-- · 2019-01-20 21:30

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.

查看更多
再贱就再见
7楼-- · 2019-01-20 21:30
git checkout stash -- .

worked for me.

Note: 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.

查看更多
登录 后发表回答