恢复git合并冲突标志 [英] Restoring git merge conflict flags
问题描述
我最近找到了
git checkout --conflict = merge - (file)
命令对于本地分支很有效,但尽快当它被推送到远程时,这个命令不再用于恢复合并标志。
有没有办法强制git重新标记文件是否有冲突人们可以使用正常的合并工具来解决它们吗?
有没有办法强制git重新标记文件为冲突,以便人们可以使用正常的合并工具来解决它们?
不,没有写你自己的代码无论如何。 (有人应该编写一些代码,也许应该是这样的 - 现在是时候为此提供一个工具了。虽然有一些很难的角落案例。)
这里的问题是,在Git中,冲突的合并是由存储在Git的索引中的状态表示的。
暂时退回,让我们定义索引以及当前提交或 当前提交,也称为HEAD或 HEAD
和工作树(或工作树,工作树和一些类似的变体):
HEAD
,非常简单。 (我喜欢使用 HEAD
,像这样的计算机文本格式,特别指Git名称 HEAD
。也可以在Git 1.8.5或更高版本中使用 @
,如果存在当前分支,则此特殊名称指当前分支,并且然后当前分支定位该分支的 tip commit ,即当前提交。或者,在分离的HEAD模式下,直接包含 HEAD
当前提交的哈希ID,无论哪种方式,都会命名为当前提交。)
工作树还可以保存尚未提交但不想提交的文件。这些是 Git倾向于抱怨没有跟踪的未跟踪文件;您可以通过在 索引位于这两者之间。通常,当您第一次签出提交或分支时,索引内容与 因此, index基本上代表你将做的 next commit 。当你运行 如果您从不进行任何合并,或者从来没有任何合并冲突,我们可以停在这里,并完成索引。当然,你正在进行合并,并且它们正在发生冲突,所以我们需要仔细观察。 索引按工作树中的路径名记录文件。如果您修改了这些文件中的一部分,并且 全零值的列表示每个文件都位于零槽中。 在冲突合并期间, 这些槽中的几个槽可以是空的。 (我曾经说过,其中至多有一个可能是空的,但我错了:通过重命名/重命名或重命名/删除冲突,我们实际上可以看到多个空插槽。)空插槽指示 no 文件在合并的三个输入中的一个或多个输入中具有该名称。然而,任何存在较高编号的条目,表示存在冲突的合并。 正如您所见,你的工作来解决这些冲突。指定文件的工作树版本通常包含Git尝试解决此问题的最佳尝试,但由于Git无法解决冲突,因此工作树版本中存在冲突标记。解决冲突后,您应该像往常一样在路径上运行 如果您处于合并过程中,尚未提交结果,并且已编辑或甚至解析文件,但希望恢复如果你注意到,你可以使用: (或者与 在任何情况下,只有解决了所有更高阶段的索引条目后,您才能 进行新的提交。也就是说,如果 ...只要它被推送到远程,这个[ 实际上,它早在那之前。一旦提交,恢复冲突的能力就会消失。这将永久清除所有较高阶段的索引条目。但是,您无法推送索引,也无法推送文件:只能推送提交。这意味着要推进部分合并(让其他人处理它),必须解决合并和提交。现在它已不再进行,不能再进行了。 所需要的是一个可以保存完整索引状态的工具,工作树文件,合并状态包括两个提交 I am trying to work out a method of sharing merge conflicts with other members of my team. We have some very large branches and merging them creates a lot of conflicts. I have tried several different methods, and my current attempt involves pushing the files in a conflicted state to the remote repo (leaving the merge markers in the files), and then running an annoyingly long alias to grep through the files and re-create the merge files manually (LOCAL, BASE, REMOTE). I recently found the git checkout --conflict=merge -- (file) command, which works great on a local branch, but as soon as it gets pushed to a remote, this command no longer works to restore the merge flags. Is there a way to force git to re-flag a file as conflicted so people can use the normal merge tools to resolve them? Is there a way to force git to re-flag a file as conflicted so people can use the normal merge tools to resolve them? No, not without writing your own code anyway. (Someone should write some code, and maybe that should be be—it's time to have a tool for this. There are a bunch of corner cases that are hard, though.) The problem here is that a conflicted merge, in Git, is represented by state stored in Git's index. Stepping back for a moment, let's define the index, along with current commit or The current commit, known also as HEAD or The work tree is, quite simply, where you do your work. Git's internal data structures that hold commits and versioned copies of files are not suitable for anything else, so Git extracts the versions into ordinary files, which you can then read and manipulate as usual. The work tree can also hold files that you have not yet, and do not want to, commit. These are untracked files. (Technically, an untracked file is any file in the work-tree that is not already in the index, but we haven't defined the index yet. :-) ) Git tends to complain about untracked files being untracked; you can shut off these complaints by listing the files, or their path name patterns, in The index sits halfway between these two. Normally, when you first check out a commit or branch, the index contents match the As such, the index essentially represents the next commit you will make. When you run If you never do any merges, or never have any merge conflicts, we could stop here and be done with the index. Of course, you're doing merges, and they are hitting conflicts, so we need to look closer. The index records files by their path names in the work-tree. If you modify some of these files, and The column of all-zero values indicates that each of these files is in slot zero. During a conflicted merge, though, Several of these slots can be empty. (I used to say that at most one of them could be empty, but I was wrong: with rename/rename or rename/delete conflicts, we can in fact see more than one empty slot.) The empty slot or slots indicate that no file had that name in one or more of the three inputs to the merge. The existence of any higher-numbered entry, though, indicates that there is a conflicted merge going on. It is, as you have seen, your job to resolve these conflicts. The work tree version of the named file normally contains Git's best attempt to resolve the merge as of this point, but since Git was not able to resolve the conflict, the work tree version has conflict markers in it. After you resolve the conflict, you should run If you are in the middle of a merge, have not committed the result yet, and have edited or even resolved a file but wish to restore it to its original unmerged state, you can, as you noted, use: (or the same with In any case, you cannot make a new commit until all higher-stage index entries are resolved. That is, if ... as soon as it gets pushed to a remote, this [ In fact, it's long before that. The ability to restore the conflict goes away once you commit. This permanently cleans out all the higher-stage index entries. But you cannot push an index, and you cannot push a file: you can only push commits. This means that to push a partial merge (to let someone else deal with it), you must resolve the merge and commit. Now it's no longer in progress and cannot be made to be in progress any more. What is needed is a tool that can save the full index state, the work-tree files, the merge state including the IDs of the two commits 这篇关于恢复git合并冲突标志的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
.gitignore
文件中列出文件或路径名称模式来关闭这些投诉。请注意,将文件名添加到 .gitignore
不会使文件未被跟踪。如果文件被跟踪,它将保持跟踪。 .gitignore
条目主要是关闭投诉,并且当您说添加所有文件时,Git不会自动添加这些未跟踪文件。
HEAD
提交内容相匹配,Git也会将其提取到工作树中。然后,您可以随意修改所有您喜欢的工作树,但索引会继续匹配HEAD。您必须 git add
文件将它们从工作树复制回索引。
git commit
时,Git将索引变成一个新的提交(它会自动成为新的HEAD提交)。只有你将复制回到索引中的东西才会被提交,这意味着你可以通过 git add
几个文件将更改分成几个提交一次。 (而且,您可以使用 git add -p
来仅添加文件的部分,而不是整个文件,以便索引版本本身)
索引每个索引条目有四个阶段插槽 h3>
git add
它们准备好进行下一次提交,则会更新这些文件的索引版本。但是如果您在冲突合并期间运行 git ls-files --stage
,则会出现一个秘密。没有其他时间这通常显示出来 - 只是在冲突的合并期间。秘密在于每个文件可以在索引中高达三次,在 stage slots 中被编号。插槽零是正常的日常插槽:
$ git ls-files --stage
[snip]
100644 d8d18736e74c7a5f61d794770a2dd94786501d12 0 Makefile
100644 046dcab7645305cbf4b94adef54a859234ac3caa 0自述文件
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 lib / __ init__.py
README
或其他名称之一,在插槽1,2和3中最多可以有三个条目。在这种情况下,Git知道存在合并冲突。插槽1保存文件的合并基础版本。插槽2包含 HEAD
或 - 我们的
版本,插槽3包含 MERGE_HEAD
或 - 他们的
版本。 (根据定义,零槽位此时未被占用。)
git add
(或者如果分辨率为 git rm
删除文件)。这将清除较高阶段的插槽,同时还将工作树文件复制到第零个插槽,除非该文件真的被删除。现在冲突得到解决。
pre $ g $ checkout -m - < path>
相同 - 冲突
)。您可以添加 =< style>
,它允许您指定冲突风格: merge
或 diff3
(我更喜欢 diff3
,其中包括文件合并版本的文本)。这将删除阶段0条目(如果创建了条目),并恢复较高阶段的冲突条目。这种特殊形式的 git checkout
,但要求原始未合并条目在索引中可用。
git ls-files --stage
显示任何不是阶段零的条目,则可能不会进行新的提交。 p>
git checkout -m
]命令不再用于恢复合并标志。
HEAD
和 MERGE_HEAD
这两个提交的ID,这表示合并基础的ID - 也许甚至是未被跟踪和/或被忽略的文件(la git stash
)存储到非分支引用中存储的特殊提交或一组提交中。这个提交或这些提交可以从一个存储库传输到另一个存储库。相同工具的反向版本可以恢复合并状态,索引状态和工作树。所有构建这样的工具所需的组件都存在(因为 git ls-files --stage
和 git update-index
两者都存在)。但编写这个工具对会很复杂,可能至少与 git stash
脚本一样困难。
HEAD
, and work-tree (or work tree, working tree, and a bunch of similar variants):
HEAD
, is pretty straightforward. (I like to use HEAD
, in computer-text layout like this, to mean specifically the Git name HEAD
. You can also use @
in Git version 1.8.5 or later. This special name refers to the current branch, if there is a current branch, and the current branch then locates the tip commit of that branch, which is the current commit. Or, in "detached HEAD" mode, HEAD
directly contains the hash ID of the current commit. Either way, this names the current commit.).gitignore
files. Note that adding a file name to .gitignore
does not make the file untracked. If the file is tracked, it stays tracked. The .gitignore
entry primarily just shuts off complaints, and also makes Git not automatically add these untracked files when you say "add all files".HEAD
commit contents, which Git also extracts into the work tree. You can then modify the work-tree all you like, but the index continues to match HEAD. You must git add
files to copy them from the work tree, back into the index.git commit
, Git turns the index into a new commit (which automatically becomes the new HEAD commit). Only things you copied back into the index get committed, which means you can split up changes into several commits by just git add
ing a few files at a time. (And, you can use git add -p
to add just part of a file, rather than the whole file, so that the index version itself is partway between the HEAD commit version and the work-tree version.)The index has four "stage slots" per index entry
git add
them to be ready for the next commit, this updates the index version of the files. But there is a secret that shows up if you run git ls-files --stage
during a conflicted merge. There is no other time that this normally shows up—it's only during conflicted merges. The secret is that each file can be in the index up to three times, in stage slots that are numbered. Slot zero is the normal, everyday slot:$ git ls-files --stage
[snip]
100644 d8d18736e74c7a5f61d794770a2dd94786501d12 0 Makefile
100644 046dcab7645305cbf4b94adef54a859234ac3caa 0 README
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 lib/__init__.py
README
, or one of the other names, may have up to three entries in slots 1, 2, and 3. In this case, Git knows that there was a merge conflict. Slot 1 holds the merge base version of the file. Slot 2 holds the HEAD
or --ours
version, and slot 3 holds the MERGE_HEAD
or --theirs
version, of that same file. (Slot zero is, by definition, unoccupied at this time.)git add
on the path as usual (or git rm
if the resolution is to remove the file). This clears out the higher-stage slots, while also copying the work-tree file to slot zero unless the file is really removed. Now the conflict is resolved.git checkout -m -- <path>
--conflict
). You can add =<style>
, which allows you to specify the conflict style: merge
or diff3
(I prefer diff3
, which includes text from the merge base version of the file). This removes the stage-zero entry, if you made one, and restores the higher-stage conflicting entries. This particular form of git checkout
, though, requires that the original unmerged entries be available in the index.git ls-files --stage
shows any entries that are not stage zero, you may not make a new commit.
git checkout -m
] command no longer works to restore the merge flags.HEAD
and MERGE_HEAD
—this implies the ID of the merge base—and perhaps even untracked and/or ignored files (a la git stash
) into a special commit or set of of commits stored on a non-branch reference. This commit, or these commits, can then be transferred from one repository to another. A reverse version of the same tool can restore the merge state, index state, and work-tree. All the components necessary to build such a tool exist (because git ls-files --stage
and git update-index
both exsit). But writing this tool-pair would be complicated, probably at least as difficult as the git stash
script.