Git:如何在合并冲突损坏后恢复

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22565184/
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-19 09:52:33  来源:igfitidea点击:

Git: how to revert after a merge conflict corruption

gitmerge

提问by John Little

OK, as a SVN and CVS expert of 20 years, I am finding git very challenging. I have read lots of guides, not found one which is comprehensible. Many apologies for my stupidity with git.

好吧,作为 20 年的 SVN 和 CVS 专家,我发现 git 非常具有挑战性。我读了很多指南,没有找到一个可以理解的。为我对 git 的愚蠢行为深表歉意。

We only use master, no branches. Git was forced on us.

我们只使用 master,不使用分支。Git是强加给我们的。

I have a js file which I "own" noone else should be touching it. But someone did, and checked it in. I tried to checkin my copy, and fails. So I pull the updated version, which "corrupts" my copy with a lot of <<< and >>> entries.

我有一个我“拥有”的 js 文件,其他人不应该接触它。但有人这样做了,并签入了。我试图签入我的副本,但失败了。所以我拉了更新的版本,它用很多 <<< 和 >>> 条目“破坏”了我的副本。

Basically, I wanted to reject all his changes, and overwrite them with mine. with SVN, I would simply make a copy of my local js file, delete it, checkout from the repo to get the offending one, copy my copy back, then check the result in. Really simple.

基本上,我想拒绝他的所有更改,并用我的覆盖它们。使用 SVN,我只需复制我的本地 js 文件,将其删除,从 repo 中检出以获取有问题的文件,复制我的副本,然后检查结果。真的很简单。

I haven't found a way to do this in git, as if you delete the file, it thinks you want to delete it.

我还没有在git中找到这样做的方法,就像你删除文件一样,它认为你想删除它。

So I tried editing the merged file, but got mixed up which lines are the new and which the old. So now the file is unusable. i have "lost" my local copy.

所以我尝试编辑合并的文件,但混淆了哪些行是新的,哪些是旧的。所以现在文件无法使用。我已经“丢失”了我的本地副本。

I read about this: "git push origin master --force" but:

我读到了这个:“git push origin master --force”但是:

  1. its too late, I've already lost my version.
  2. i read another post which says never do this as it breaks people's pulls, but they don't offer an alternative "correct" way reject someones checkin,, and replace one file with your own.
  1. 太晚了,我已经丢失了我的版本。
  2. 我读了另一篇文章,其中说永远不要这样做,因为它会破坏人们的吸引力,但他们没有提供另一种“正确”的方式拒绝某人签入,并用您自己的文件替换一个文件。

So I assume I have to go back to a previous local commit to recover that one file. The only way I can find to do this is "git checkout [revision] .". But if I do that, I'm not on master any more, and don't know how to get back to it. Also, I expect it wont let me, because I edited and saved the problem file so it wont let me checkout a prev. version. I assume I would have to commit the broken file, then try and go back two commits, backup the file, then in a new directory checkout master again, overwrite the file, then check this in.

所以我假设我必须回到以前的本地提交来恢复那个文件。我能找到的唯一方法是“git checkout [revision] .”。但如果我这样做了,我就不再是大师了,也不知道如何回到过去。另外,我希望它不会让我,因为我编辑并保存了问题文件,所以它不会让我结帐上一个。版本。我假设我必须提交损坏的文件,然后尝试返回两次提交,备份文件,然后再次在新目录中 checkout master,覆盖文件,然后将其签入。

So I have two problems:

所以我有两个问题:

  1. how to get my file back.
  2. once I have it back, how do I overwrite the file someone else checked in with my own, without affecting the other stuff they checked in & pushed?
  1. 如何取回我的文件。
  2. 一旦我取回它,我如何覆盖其他人用我自己签入的文件,而不影响他们签入和推送的其他内容?

回答by user3033893

Your two problems can be solved in the same way:

你的两个问题可以用同样的方法解决:

git checkout HEAD my/filename.js

Where HEAD is literal (git shorthand for current branch name) and my/filename.js should be replaced by the actual filename of your file. This will restore your file to how it was before the update, effectively "undoing" the changes from the other person. Commit this result locally and then push as normal (no --force should be necessary if you when you have updated from the central repo)

其中 HEAD 是文字(当前分支名称的 git 简写),而 my/filename.js 应替换为文件的实际文件名。这会将您的文件恢复到更新前的状态,有效地“撤消”其他人的更改。在本地提交此结果,然后正常推送(如果您从中央仓库更新,则不需要 --force)

In general, the way to resolve a merge conflict is to edit your file until it's the way you want it, and then run git add. The reason git (and svn for that matter) leave the "<<<" and ">>>" results in your file after a failed merge or update is to help you or your tools to resolve the merge. Setting up a tool to help you do this will probably be worth it, but it's a shame it doesn't come out of the box.

通常,解决合并冲突的方法是编辑您的文件,直到它符合您的要求,然后运行 ​​git add。在合并或更新失败后,git(以及 svn)在您的文件中留下“<<<”和“>>>”结果的原因是帮助您或您的工具解决合并问题。设置一个工具来帮助您执行此操作可能是值得的,但遗憾的是它不是开箱即用的。

By the way, your initial instinct from SVN to replace the unwanted file with your known good one would work just fine with one additional step: after deleting the file, restoring the good one and running git add my/filename.js. In this case checkout will also add it to the index (double-check with a git status), so you can immediately commit (locally) and then push the (now resolved) merge conflict back to the central repository.

顺便说一句,你从 SVN 开始的用已知好的文件替换不需要的文件的本能可以通过一个额外的步骤来正常工作:删除文件后,恢复好的文件并运行 git add my/filename.js。在这种情况下,checkout 也会将其添加到索引中(使用 git 状态仔细检查),因此您可以立即提交(本地),然后将(现已解决的)合并冲突推送回中央存储库。

回答by slobobaby

You probably just want to revert the other persons commit. It is important with git that you don't run a pull if you have uncommitted local changes. If you do you can end with a merge that is very difficult to back out of.

您可能只想恢复其他人的提交。如果您有未提交的本地更改,请不要使用 git 运行 pull ,这一点很重要。如果这样做,您可能会以很难退出的合并结束。

git merge --abort

will abort the merge you have started by pulling others changes into your code. This mayrecover the unchecked in changes you had before you started the pull. If you have large changes in the file then take a backup somewhere else and hand merge them afterwards if it doesn't work.

将通过将其他更改拖入您的代码来中止您已开始的合并。这可能会恢复您在开始拉取之前未经检查的更改。如果您对文件进行了大量更改,请在其他地方进行备份,然后在不起作用时手动合并它们。

run

git log --stat

and find the commit which changed your file. run

并找到更改文件的提交。跑

git revert <commit id>

where is the id of then commit changing your file. This will make a commit which rolls the other's commit back, push that change. If the other person had other things in the commit then they can rework their patch by reverting your revert and editing the commit to remove the changes in your file and then pushing the change again.

然后提交更改文件的 ID 在哪里。这将进行一次提交,将其他人的提交回滚,推动该更改。如果其他人在提交中有其他内容,那么他​​们可以通过还原您的还原并编辑提交以删除文件中的更改,然后再次推送更改来重新制作补丁。

In the future never have unchecked-in changes when you pull, it causes trouble.

以后在拉取时永远不要有未签入的更改,这会引起麻烦。

You could also consider a commit hook on the server which stops people other than you committing to that file in the future.

您还可以考虑在服务器上设置一个提交钩子,它会阻止除您将来提交该文件之外的其他人。

回答by blackbuild

To completly drop the foreign changes in a merge conflict, you can use

要完全删除合并冲突中的外部更改,您可以使用

git checkout --ours -- <path-to-file> && git add <path-to-file>

This resolves the conflict with the specific file using your version. The add is necessary to tell git that the conflict is resolved.

这解决了与使用您的版本的特定文件的冲突。add 是告诉 git 冲突已解决所必需的。