如何在不提交的情况下解决 git stash 冲突?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7751555/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 12:03:59  来源:igfitidea点击:

How to resolve git stash conflict without commit?

gitgit-stash

提问by Sven

As asked in this question, I also want to know how to resolve a conflicting git stash popwithout adding all modifications to a commit (just like "git stash pop" without a conflict does).

正如在这个问题中问的那样,我还想知道如何在git stash pop不向提交添加所有修改的情况下解决冲突(就像没有冲突的“git stash pop”一样)。

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 popwithout a conflict.

2016-06-27:在示例中添加了一个名为“third”的新文件,以表明像 scy 的解决方案之类的解决方法仅适用于空 HEAD,但不能解决 HEAD 没有相同内容的初始问题,例如对于一个git stash pop没有冲突。

回答by David Ferenczy Rogo?an

Don't follow other answers

不要跟随其他答案

Well, you can follow them :). But I don't think that doing a commit and then resetting the branch to remove that commit and similar workarounds suggested in other answers are the clean way to solve this issue.

好吧,你可以关注他们:)。但我不认为进行提交然后重置分支以删除该提交以及其他答案中建议的类似解决方法是解决此问题的干净方法。

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 statusin the repository with a conflict:

以下解决方案对我来说似乎更清晰,而且Git 本身建议这样做- 尝试git status在有冲突的存储库中执行:

Unmerged paths:
  (use "git reset HEAD <file>..." to unstage)
  (use "git add <file>..." to mark resolution)

So let's do what Git suggests (without doing any useless commits):

所以让我们按照 Git 的建议去做(不要做任何无用的提交):

  1. Manually (or using some merge tool, see below) resolve the conflict(s).
  2. Use git resetto mark conflict(s) as resolved and unstage the changes. You can execute it without any parameters and Git will remove everything from the index. You don't have to execute git addbefore.
  3. Finally, remove the stash with git stash drop, because Git doesn't do that on conflict.
  1. 手动(或使用一些合并工具,见下文)解决冲突。
  2. git reset马克冲突(S)为解决和unstage的变化。您可以不带任何参数执行它,Git 将从索引中删除所有内容。您不必git add之前执行。
  3. 最后,使用 删除存储git stash drop,因为 Git 不会在发生冲突时执行此操作。

Translated to the command-line:

转换为命令行:

$ git stash pop

# ...resolve conflict(s)

$ git reset

$ git stash drop

Explanation of the default behavior

默认行为的解释

There are two ways of marking conflicts as resolved: git addand git reset. While git resetmarks the conflicts as resolved and removes files from the index, git addalso marks the conflicts as resolved, but keeps files in the index.

有两种方法可以将冲突标记为已解决:git addgit reset。虽然git reset将冲突标记为已解决并从索引中删除文件git add,但也将冲突标记为已解决,但将文件保留在索引中。

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 resetto remove everything from the index.

在解决冲突后将文件添加到索引是有意的。通过这种方式,您可以将更改与之前存储的更改以及冲突解决后所做的更改区分开来。如果您不喜欢它,您可以随时使用git reset删除索引中的所有内容。

Merge tools

合并工具

I highly recommend using any of 3-way merge toolsfor resolving conflicts, e.g. KDiff3, Meld, etc., instead of doing it manually. It usually solves all or majority of conflicts automatically itself. It's hugetime-saver!

我强烈建议使用任何一种三路合并工具来解决冲突,例如KDiff3Meld等,而不是手动进行。它通常会自动解决所有或大部分冲突。这是巨大的节省时间!

回答by scy

Suppose you have this scenario where you stash your changes in order to pull from origin. Possibly because your local changes are just debug: truein some settings file. Now you pull and someone has introduced a new setting there, creating a conflict.

假设您有这样的场景,您将更改隐藏起来以便从源中提取。可能是因为您的本地更改仅debug: true在某些设置文件中。现在你拉了,有人在那里引入了一个新的设置,造成了冲突。

git statussays:

git status说:

# 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:

好的。我决定按照 Git 的建议去做:我解决了冲突并提交了:

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 --softhere, 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.)

我的工作副本没有改变,但 WIP 提交消失了。这正是我想要的!(请注意,我没有--soft在这里使用,因为如果您的存储中有自动合并的文件,它们会自动暂存,因此您最终会在reset.之后再次暂存这些文件。)

But there's one more thing left: The man page for git stash popreminds 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 dropmanually afterwards."So that's exactly what we do now:

但是还有一件事:手册页git stash pop提醒我们“应用状态可能会因冲突而失败;在这种情况下,它不会从存储列表中删除。您需要git stash drop手动解决冲突,然后手动调用。” 所以这正是我们现在要做的:

git stash drop

And done.

并做了。

回答by ComputerDruid

Instead of adding the changes you make to resolve the conflict, you can use git reset HEAD fileto resolve the conflict without staging your changes.

无需添加您为解决冲突所做的更改,您可以使用git reset HEAD file来解决冲突,而无需暂存更改。

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.

可能应该有一种重置模式可以同时执行这两项操作,尽管现在还没有。

回答by stevenspiel

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 overwritesit with the stashed files instead. So you can lose your uncommitted changes.

注意:这可能很危险,因为它不会尝试将存储中的更改合并到您的工作副本中,而是用隐藏的文件覆盖它。因此,您可能会丢失未提交的更改。

回答by Aaron Goldman

git add .
git reset

git add .will stage ALL the files telling git that you have resolved the conflict

git add .将暂存所有文件,告诉 git 您已经解决了冲突

git resetwill unstage ALL the staged files without creating a commit

git reset将取消暂存所有暂存文件而不创建提交

回答by Marco Ponti

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 将尝试像以前一样应用更改,而不会尝试添加所有更改以进行提交。

git stash apply --index

git stash apply --index

here is the full explanation:

这是完整的解释:

http://git-scm.com/book/en/Git-Tools-Stashing

http://git-scm.com/book/en/Git-Tools-Stashing

回答by cherish

git stash branchwill 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

git stash branchwill works,它会为您创建一个新分支,检查您在存储工作时所做的提交,在那里重新应用您的工作,然后在成功应用时删除存储。检查这个

回答by Jammer

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.

我发现的最快方法是解决冲突,然后执行git add -u,然后执行git reset HEAD,这甚至不涉及提交。

回答by samgrigg

According to git stash questions, after fixing the conflict, git add <file>is the right course of action.

根据git stash questions,在解决冲突后,git add <file>是正确的行动方案。

It was after reading this commentthat I understood that the changes are automatically added to the index (by design). That's why git add <file>completes the conflict resolution process.

阅读此评论后,我了解到更改会自动添加到索引中(按设计)。这就是git add <file>完成冲突解决过程的原因。

回答by Bishwas Mishra

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