我已经阅读过有关此问题的其他问题,但是我的本地git中丢失文件的情况很简单。
我克隆了一个存储库:
git clone https://github.com/uruddarraju/kubernetes
cd kubernetes/
我使用以下命令对项目kubernetes进行了上游提取:
git remote add upstrm https://github.com/kubernetes/kubernetes
git fetch upstrm
这带来了一堆标签如下:
uruddarraju$ git tag
v1.3.2-beta.0
v1.3.3
v1.3.3-beta.0
v1.3.4
我正在尝试将v1.3.4合并到分支tess或远程源
中git merge v1.3.4
我必须解决很多合并冲突,但有趣的是我也看到添加到upstrm / v1.3.4的新文件现在在本地文件系统中丢失了,我看不到该文件处于git状态。
这怎么可能?我期待这些文件作为合并的一部分添加,但显然它们不是。
uruddarraju$ ls pkg/genericapiserver/
resource_encoding_config.go
我正在寻找文件resource_config.go 我放弃了合并并检查了v1.3.4以验证该分支中是否存在该文件:
uruddarraju$ git checkout -b merege1.3 v1.3.4
uruddarraju$ ls pkg/genericapiserver
resource_config.go
resource_config_test.go
resource_encoding_config.go
我在两个分支上做了一个git diff,我清楚地看到这些文件已经在upstrm / v1.3.4中添加了 我在v1.3.4上运行了以下内容
uruddarraju$ git diff master --name-status
A pkg/genericapiserver/resource_config.go
A pkg/genericapiserver/resource_config_test.go
A pkg/genericapiserver/resource_encoding_config.go
当我做相反的事情时,我正在掌握并使用v1.3.4做差异,我看到了:
uruddarraju$ git diff v1.3.4 --name-status
D pkg/genericapiserver/resource_config.go
D pkg/genericapiserver/resource_config_test.go
D pkg/genericapiserver/resource_encoding_config.go
编辑1:
合并基础如下所示:
uruddarraju$ git merge-base --all HEAD v1.3.4
812b9a47d6625b0fd02af18f9b147720f3c6bfce
编辑2:
我也看到以下警告:
warning: inexact rename detection was skipped due to too many files.
warning: you may want to set your merge.renamelimit variable to at least 4292 and retry the command.
我显然遗漏了一些东西。任何帮助将不胜感激。
答案 0 :(得分:2)
git merge
做什么在Git中,merge
操作用于将第二行开发结合到第一行开发中。
假设Alice和Bob都在编写一些代码。它们以代码的通用版本开头。 Alice添加了一个新功能,Bob添加了一个不同的新功能。
在此过程中,Alice可能会创建或删除文件,或修改现有文件。同样,Bob可能会创建或删除文件。让我们说,只是为了论证,Alice能够在不添加或删除任何文件的情况下进行所有更改,但Bob添加文件n
(对于新文件)并删除文件o
(旧)。
Alice和Bob都提交了他们的更改 - 可能是一次提交,也许提交了多次 - 并且Alice将她的工作推回到origin
,以便Bob可以看到它。
现在假设Bob决定合并Alice的工作,即获取她所做的更改。他可能会跑:
$ git fetch origin
这可以让Bob以名称origin/alice
获得Alice的提交到Bob的存储库中。 (实际名称取决于Alice在做git push
时使用的内容。)
接下来,鲍勃会跑:
$ git merge origin/alice
此合并必须首先找到合并基础:Alice和Bob分歧并进行不同提交的点。让我们假设Bob在分支bob
上,并绘制提交图,以便我们可以看到这个"合并基础"是:
...--o--*--o--o--B <-- bob
\
o--o--o--A <-- origin/alice
在这种情况下,Alice通过进行四次提交来构建她的功能,这些提交添加和删除了没有新文件,但可能修改了一些现有文件。 Bob通过三次提交构建了他的功能,其中一些提交了新文件(new
)和/或删除了现有文件(old
)。合并基础是我标记为*
的提交,Alice和Bob的分支提示分别是A
和B
。
Git的工作是结合 Alice的更改,来自未添加或删除任何文件但修改了某些文件的四个提交, plus Bob的更改,来自添加和删除文件的三个提交。如果一切顺利 - 如果没有要解决的冲突 - 最终结果仍然会有一个新文件new
和一个已删除的文件old
,并且Bob将获得一个新的合并提交< / em> M
:
...--o--*--o--o--B---M <-- bob
\ /
o--o--o--A <-- origin/alice
在此合并之前和之后,如果Bob要求Git提交提交B
和A
,他会看到一些已删除的文件和一些已添加的文件。 这些不是Alice添加或删除的文件;相反,这些是Bob自己添加和删除的文件。
由于我们现在知道(来自git merge-base
命令输出)只有一个合并库,我们可以使用三点语法与git diff
进行比较一个合并基础到两个分支提示。实际上,这将让我们弄清楚Bob做了什么&#34;并且&#34;弄清楚Alice做了什么&#34;。
您的提交图可能比上面示例中的提交图复杂得多,但至少 ,您的任务是相同的:您有两个特定的提交A
和B
你正在合并,其中commit B
是你当前分支的HEAD
提交,提交A
是你用名称v1.3.4
识别的那个}。所以你有:
...--o--*--o--o--B <-- HEAD
\
o--o--o--A <-- v1.3.4
(旁白:即使v1.3.4
是一个标记,它也可以在这里工作。分支名称HEAD
和你当前的分支名称一样,所以我用它代替分支名称。)
提交*
是合并基础 - 哈希为812b9a47d6625b0fd02af18f9b147720f3c6bfce
的基础。我们可以运行这两个git diff
命令:
git diff 812b9a47d6625b0fd02af18f9b147720f3c6bfce HEAD
git diff 812b9a47d6625b0fd02af18f9b147720f3c6bfce v1.3.4
这需要输入哈希(或复制粘贴)。相反,我们可以使用这种更短的形式:
git diff v1.3.4...HEAD
git diff HEAD...v1.3.4
因为只有一个合并库(812b9a47d6625b0fd02af18f9b147720f3c6bfce
),所以这两组命令做同样的事情。第一个显示我们&#34;我们做了什么&#34;第二个显示了我们&#34;他们做了什么&#34;。 Git将尝试将这两组变化结合起来。
(请注意,我们可以将--name-status
和/或--stat
添加到这些diff命令中,以获得更改的更短摘要,而不是完整的差异。这可能对您的情况有用。)
当你遇到冲突时(正如你所做的那样),这只是意味着Git无法协调他们的&#34;改变(来自第二个差异)&#34;我们的&#34;变化(来自第一个差异)。如果他们的更改包括添加文件,Git就没有问题:它会添加这些文件。它们不会从合并结果中遗漏。但据推测,这里发生的事情是&#34;我们&#34; (在&#34;我们的&#34;分支)删除了文件。
据推测,我们不需要这些文件,但是在我们通过合并添加到代码中的更改中,执行需要这些文件。 Git不知道这个--Git不知道任何代码意味着什么。我们只需要将这些文件恢复为某种合适的形式,并在必要时修复我们的代码,以允许这些文件存在;或者我们将不得不修改他们的代码,以便在没有这些文件的情况下工作;或两者的某种组合。
拥有两个或更多合并基础,甚至没有合并基础是很少见的,但并非不可能。在这种情况下,git merge
知道该怎么做,但git diff
没有。如果遇到这种情况,简单的git diff A...B; git diff B...A
方法将无法(完全)向您显示合并过程的输入。没有简单的方法来处理这种情况。在使用git merge-base --all
样式差异来确定git diff A...B
是什么之前,最好检查(使用git merge
)以确保不会干扰这一点。看到。