Git 合并是否已经完成 - 或者如何使用 kdiff3 完成它?
Is this Git merge already complete - or how to complete it with kdiff3?
背景
我是 Git 的新手,正在解决我的第一个合并冲突。我在 C# 中工作,在 Scott Lilly C# SuperAdventure tutorial 上使用 Visual Studio。在构建教程时,我正在使用 Github 来学习 SCM 和 Git。作为这个过程的一部分,我学会了有一个clean master,直接按照教程不走偏,为每一章创建一个b运行ch,最后合并回master,然后单独保留任何实验b运行ches - 这样我的实验在创建新功能或重构现有代码时就不会与教程冲突。
到目前为止,还不错。我的一项实验是添加一些单元测试。我开始了一个单独的 unittesting
b运行ch,并决定将更改从 master 引入到这个 b运行ch 以使其保持最新。在第一次合并时,由于安装了不同的包,我在要添加单元测试的项目的 Visual Studio 项目文件中发生了冲突。这没什么大不了的,但机械师让我失望了。添加冲突有5个,都可以直接合并,真正冲突的有1个。我已经完成了大部分工作,但只需要一些最后的帮助。
到目前为止的步骤
我正在使用 a public repo on Github, and Visual Studio 2017 Community on Windows 10 with the VS Github extension and local Git repo - but let's face it, the Visual Studio plug-in commands are quite limited to very normal workflow items. So - I've started using the Git bash as needed for command-line, and Git Extensions 作为 Git GUI,它运行良好。
我最近完成了教程的第23章,并将Chap_23
b运行ch合并到master
。然后我尝试将 master 合并到 unittesting
,但在 SuperAdventureConsole/SuperAdventureConsole.csproj 文件中发生冲突。此时的 git 状态显示:
$ git status
On branch unittesting
Your branch is ahead of 'origin/unittesting' by 1 commit.
(use "git push" to publish your local commits)
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Changes to be committed:
modified: SuperAdventure.sln
modified: SuperAdventureConsole/App.config
modified: SuperAdventureConsole/Properties/AssemblyInfo.cs
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: SuperAdventureConsole/SuperAdventureConsole.csproj
Untracked files:
(use "git add <file>..." to include in what will be committed)
SuperAdventureConsole/SuperAdventureConsole.csproj.BASE
SuperAdventureConsole/SuperAdventureConsole.csproj.LOCAL
SuperAdventureConsole/SuperAdventureConsole.csproj.REMOTE
SuperAdventureConsole/SuperAdventureConsole.csproj.orig
此时我 运行 git mergetool
基于 Q: How to resolve merge conflicts in Git?,它将 kdiff3 作为合并工具运行(无论如何在我的设置中),原始文件为 A
文件,LOCAL 和 REMOTE 为 B
和 C
(我不确定哪个是哪个)。我能够通过那个错误,并为每个冲突(总共 6 个)在 B
和 C
之间进行选择。这就是我卡住的地方。
起初输出文件(在 kdiff3 中 A
、B
和 C
下方的底部)没有被接受,但在第 3 次尝试时,我保存并退出 kdiff3,不再有合并冲突:
$ git mergetool
No files need merging
但是,根据 "git status":
,我仍然有未跟踪的文件
$ git status
On branch unittesting
Your branch is ahead of 'origin/unittesting' by 1 commit.
(use "git push" to publish your local commits)
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: SuperAdventure.sln
modified: SuperAdventureConsole/App.config
modified: SuperAdventureConsole/Properties/AssemblyInfo.cs
modified: SuperAdventureConsole/SuperAdventureConsole.csproj
Untracked files:
(use "git add <file>..." to include in what will be committed)
SuperAdventureConsole/SuperAdventureConsole.csproj.BASE
SuperAdventureConsole/SuperAdventureConsole.csproj.LOCAL
SuperAdventureConsole/SuperAdventureConsole.csproj.REMOTE
SuperAdventureConsole/SuperAdventureConsole.csproj.orig
问题
看起来修改后的文件是 kdiff3 保存的输出,因此已经添加到索引中,因此我可以提交。那是对的吗?我假设在这种情况下我只是承诺完成合并?
总的来说,我不确定这里发生了什么 - 为什么 "git status" 显示 4 个带扩展名的未跟踪文件(即 .BASE
、.LOCAL
、.REMOTE
、和 .orig
),但在 "modified" 文件列表中显示没有扩展名的 SuperAdventureConsole/SuperAdventureConsole.csproj
?
我理解.LOCAL
和.REMOTE
,但是.BASE
和.orig
有什么区别?其中一个应该是两个b运行ches的父级,但是它是哪一个,另一个是什么?
此外,我可以从 Git Bash 或使用 Git 扩展程序或另一个 Git GUI 来仔细检查合并是否准备好按照我期望的方式提交?
谢谢!!
It looks like the modified file is the saved output from kdiff3 and therefore is already added to the index, and therefore I can commit. Is that correct? I assume in this case I just commit to complete the merge?
看起来是这样的。使用 git diff --cached
(或 git diff --staged
,如果您愿意:两者做完全相同的事情)来比较现在索引中的内容,即 new[=82 中的内容=] 提交,当前提交的内容。另请参阅第二个问题的答案。
(git status
与 git diff --cached
相同,但使用 --name-status
,因此您只能看到任何添加、删除或修改的文件,而不是实际更改的内容。)
Overall, I'm not sure what happened here - why does "git status" show 4 untracked files with an extension (i.e. .BASE
, .LOCAL
, .REMOTE
, and .orig
) ...
这有点神秘:它表明你还有 git mergetool
运行.
git mergetool
所做的是在 失败 合并后清理索引中留下的混乱。请记住,索引,又名 暂存区 或 缓存 - 一个事物的三个名称 - 通常只是您建立下一次提交的地方.它具有将进入新提交的每个文件的一个副本。但是,在合并失败期间,每个失败的合并文件可以有 三个 个副本,而不是只有一个。
(好像只有一个文件的自动合并失败了,即SuperAdventureConsole/SuperAdventureConsole.csproj
。)
索引中的三份分别是:
- 文件的合并基础版本。
- 文件的当前(
HEAD
、--ours
,或者—啊哈!—本地)版本。
- 文件的另一个(
--theirs
或一个非常糟糕的名称,远程)版本。
索引中的文件是一种特殊的、仅 Git 的形式,因此 git mergetool
所做的是将其中的每一个提取到工作树中的一个普通文件中。它还将留在 SuperAdventureConsole/SuperAdventureConsole.csproj
中的失败合并结果文件复制到 .orig
。
然后,git mergetool
运行您选择的文件合并程序。您可以在此程序中操作文件。完成后,保存文件并退出。 mergetool
脚本将 .orig
文件与最终版本进行比较,以查看您是否真正修复了任何内容,and/or 查看程序的退出代码。
如果看起来您对失败的合并做了一些处理,git mergetool
脚本应该删除 至少三个,通常是全部四个文件。它没有表明 git mergetool
仍然是 运行。您可能会检查并确保它确实不是。也许有什么东西杀死了它,它再也没有机会清理了。
I understand .LOCAL
and .REMOTE
, but what is the difference between .BASE
and .orig
? One of these should be the parent of both branches, but which one is it, and what is the other one?
.LOCAL
文件只是索引中的 --ours
版本(git show :2:<path>
,在冲突期间)。 .REMOTE
文件是 --theirs
版本 (git show :3:<path>
)。 .BASE
文件是基于合并的版本(如您所说,共同的父级;git show :1:<path>
)。 .orig
是文件级合并留下的任何内容的备份。当您选择的合并程序退出时,mergetool
脚本主要使用它来与原始文件中剩余的内容进行比较。
背景
我是 Git 的新手,正在解决我的第一个合并冲突。我在 C# 中工作,在 Scott Lilly C# SuperAdventure tutorial 上使用 Visual Studio。在构建教程时,我正在使用 Github 来学习 SCM 和 Git。作为这个过程的一部分,我学会了有一个clean master,直接按照教程不走偏,为每一章创建一个b运行ch,最后合并回master,然后单独保留任何实验b运行ches - 这样我的实验在创建新功能或重构现有代码时就不会与教程冲突。
到目前为止,还不错。我的一项实验是添加一些单元测试。我开始了一个单独的 unittesting
b运行ch,并决定将更改从 master 引入到这个 b运行ch 以使其保持最新。在第一次合并时,由于安装了不同的包,我在要添加单元测试的项目的 Visual Studio 项目文件中发生了冲突。这没什么大不了的,但机械师让我失望了。添加冲突有5个,都可以直接合并,真正冲突的有1个。我已经完成了大部分工作,但只需要一些最后的帮助。
到目前为止的步骤
我正在使用 a public repo on Github, and Visual Studio 2017 Community on Windows 10 with the VS Github extension and local Git repo - but let's face it, the Visual Studio plug-in commands are quite limited to very normal workflow items. So - I've started using the Git bash as needed for command-line, and Git Extensions 作为 Git GUI,它运行良好。
我最近完成了教程的第23章,并将Chap_23
b运行ch合并到master
。然后我尝试将 master 合并到 unittesting
,但在 SuperAdventureConsole/SuperAdventureConsole.csproj 文件中发生冲突。此时的 git 状态显示:
$ git status
On branch unittesting
Your branch is ahead of 'origin/unittesting' by 1 commit.
(use "git push" to publish your local commits)
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Changes to be committed:
modified: SuperAdventure.sln
modified: SuperAdventureConsole/App.config
modified: SuperAdventureConsole/Properties/AssemblyInfo.cs
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: SuperAdventureConsole/SuperAdventureConsole.csproj
Untracked files:
(use "git add <file>..." to include in what will be committed)
SuperAdventureConsole/SuperAdventureConsole.csproj.BASE
SuperAdventureConsole/SuperAdventureConsole.csproj.LOCAL
SuperAdventureConsole/SuperAdventureConsole.csproj.REMOTE
SuperAdventureConsole/SuperAdventureConsole.csproj.orig
此时我 运行 git mergetool
基于 Q: How to resolve merge conflicts in Git?,它将 kdiff3 作为合并工具运行(无论如何在我的设置中),原始文件为 A
文件,LOCAL 和 REMOTE 为 B
和 C
(我不确定哪个是哪个)。我能够通过那个错误,并为每个冲突(总共 6 个)在 B
和 C
之间进行选择。这就是我卡住的地方。
起初输出文件(在 kdiff3 中 A
、B
和 C
下方的底部)没有被接受,但在第 3 次尝试时,我保存并退出 kdiff3,不再有合并冲突:
$ git mergetool
No files need merging
但是,根据 "git status":
,我仍然有未跟踪的文件$ git status
On branch unittesting
Your branch is ahead of 'origin/unittesting' by 1 commit.
(use "git push" to publish your local commits)
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: SuperAdventure.sln
modified: SuperAdventureConsole/App.config
modified: SuperAdventureConsole/Properties/AssemblyInfo.cs
modified: SuperAdventureConsole/SuperAdventureConsole.csproj
Untracked files:
(use "git add <file>..." to include in what will be committed)
SuperAdventureConsole/SuperAdventureConsole.csproj.BASE
SuperAdventureConsole/SuperAdventureConsole.csproj.LOCAL
SuperAdventureConsole/SuperAdventureConsole.csproj.REMOTE
SuperAdventureConsole/SuperAdventureConsole.csproj.orig
问题
看起来修改后的文件是 kdiff3 保存的输出,因此已经添加到索引中,因此我可以提交。那是对的吗?我假设在这种情况下我只是承诺完成合并?
总的来说,我不确定这里发生了什么 - 为什么 "git status" 显示 4 个带扩展名的未跟踪文件(即 .BASE
、.LOCAL
、.REMOTE
、和 .orig
),但在 "modified" 文件列表中显示没有扩展名的 SuperAdventureConsole/SuperAdventureConsole.csproj
?
我理解.LOCAL
和.REMOTE
,但是.BASE
和.orig
有什么区别?其中一个应该是两个b运行ches的父级,但是它是哪一个,另一个是什么?
此外,我可以从 Git Bash 或使用 Git 扩展程序或另一个 Git GUI 来仔细检查合并是否准备好按照我期望的方式提交?
谢谢!!
It looks like the modified file is the saved output from kdiff3 and therefore is already added to the index, and therefore I can commit. Is that correct? I assume in this case I just commit to complete the merge?
看起来是这样的。使用 git diff --cached
(或 git diff --staged
,如果您愿意:两者做完全相同的事情)来比较现在索引中的内容,即 new[=82 中的内容=] 提交,当前提交的内容。另请参阅第二个问题的答案。
(git status
与 git diff --cached
相同,但使用 --name-status
,因此您只能看到任何添加、删除或修改的文件,而不是实际更改的内容。)
Overall, I'm not sure what happened here - why does "git status" show 4 untracked files with an extension (i.e.
.BASE
,.LOCAL
,.REMOTE
, and.orig
) ...
这有点神秘:它表明你还有 git mergetool
运行.
git mergetool
所做的是在 失败 合并后清理索引中留下的混乱。请记住,索引,又名 暂存区 或 缓存 - 一个事物的三个名称 - 通常只是您建立下一次提交的地方.它具有将进入新提交的每个文件的一个副本。但是,在合并失败期间,每个失败的合并文件可以有 三个 个副本,而不是只有一个。
(好像只有一个文件的自动合并失败了,即SuperAdventureConsole/SuperAdventureConsole.csproj
。)
索引中的三份分别是:
- 文件的合并基础版本。
- 文件的当前(
HEAD
、--ours
,或者—啊哈!—本地)版本。 - 文件的另一个(
--theirs
或一个非常糟糕的名称,远程)版本。
索引中的文件是一种特殊的、仅 Git 的形式,因此 git mergetool
所做的是将其中的每一个提取到工作树中的一个普通文件中。它还将留在 SuperAdventureConsole/SuperAdventureConsole.csproj
中的失败合并结果文件复制到 .orig
。
然后,git mergetool
运行您选择的文件合并程序。您可以在此程序中操作文件。完成后,保存文件并退出。 mergetool
脚本将 .orig
文件与最终版本进行比较,以查看您是否真正修复了任何内容,and/or 查看程序的退出代码。
如果看起来您对失败的合并做了一些处理,git mergetool
脚本应该删除 至少三个,通常是全部四个文件。它没有表明 git mergetool
仍然是 运行。您可能会检查并确保它确实不是。也许有什么东西杀死了它,它再也没有机会清理了。
I understand
.LOCAL
and.REMOTE
, but what is the difference between.BASE
and.orig
? One of these should be the parent of both branches, but which one is it, and what is the other one?
.LOCAL
文件只是索引中的 --ours
版本(git show :2:<path>
,在冲突期间)。 .REMOTE
文件是 --theirs
版本 (git show :3:<path>
)。 .BASE
文件是基于合并的版本(如您所说,共同的父级;git show :1:<path>
)。 .orig
是文件级合并留下的任何内容的备份。当您选择的合并程序退出时,mergetool
脚本主要使用它来与原始文件中剩余的内容进行比较。