我有TEST
分支,然后我有master
分支。
我有一个名为DATA
的文件夹,其中包含子文件夹和文件。
现在我的主人有
现在我只想用来自master分支的新文件更新TEST分支,以便TEST分支中没有其他所有内容,但新文件应该在那里。
我可以使用rsync
轻松完成,但只是想一想是否可以在git
中完成
答案 0 :(得分:2)
你应该对此有点小心,因为对类似但不完全相同的问题有不同的答案。例如,假设提交历史记录如下所示:
A - B - C <-- master
\
D - E <-- TEST
此处master
和TEST
以常见提交A
开头,然后分歧。假设公共提交A
包含这些文件(如果您愿意,可以在目录DATA/
中,但我只是命名文件):
file_A1
file_A2
进一步假设提交B
添加file_B1
但删除file_A2
。然后,提交C
添加file_C1
并稍微修改file_A1
。
这意味着如果您git checkout master
,您将获得包含修改后的file_A1
内容的三个文件(A1,B1和C1)。
现在假设提交D
修改file_A1
并添加file_B1
和file_D1
。然后提交E
删除file_B1
并添加其他内容。
这意味着,如果您git checkout TEST
,您将获得三个文件(A1,A2和D1),其中包含已修改的file_A1
内容(可能会与提交C
中的版本进行不同的修改,或者可以与commit C
)中的内容相同。
当您询问“TEST
中不属于master
”的文件时,file_A2
是否会计算?如果你git checkout TEST
,那就在那里;如果你git checkout master
,它就不在那里;但 在共同的起点,提交A
。
当您想知道“两者都修改过的文件”时:两者都明确file_A1
。但是,如果两者中的更改相同,那么file_A1
具有相同的内容,无论检出哪个分支。那是“两者兼修”,还是没有?
要回答这些问题,git需要做的是选择是否比较两个特定修订,或者考虑更像是三向合并(如果你尝试的话会得到什么)合并TEST
和master
使用其合并基础修订版A
作为起点。)
git diff <options> master TEST
这将比较提交C
(什么master
指向,即主分支的“提示”)与提交E
(分支的尖端TEST
})。因此,您将比较两个file_A1
,并看到提交E
有file_A2
和file_D1
且缺少file_B1
。
此处的<options>
部分可能为空,或者可能如下所述。
mergebase=$(git merge-base master TEST)
git diff <options> $mergebase master
git diff <options> $mergebase TEST
这是针对A
的合并基础(提交master
)和针对TEST
的合并基础的两个单独的差异。
第一个差异将显示在分支master
上,从A
到C
的更改是修改file_A1
,删除file_A2
,添加{ {1}},然后添加file_B1
。
这是git用来弄清楚如何进行分支合并的操作。事实上,对于两个分支的合并基础运行file_C1
有一种特殊的语法,与这两个分支之一的尖端相反:
git diff
这与第一个差异(git diff <options> TEST...master # three dots
)相同。要将merge-base与分支git diff <options> $mergebase master
的提示进行比较:
TEST
对于git diff <options> master...TEST # again, three dots
,如果您对文件的不同内容不感兴趣,那么显而易见的选项是<diff options>
,它会打印名称和状态-es文件和--name-status
,以关闭重命名检测(除非您想要重命名检测,在这种情况下,请添加--no-renames
)。
根据您获得的两棵树之间的变化,文件将分别显示为添加,删除或修改(-M
,A
和D
状态)你查看了diff选择的提交。这里有更多的可能性:如果常规文件被符号链接替换,则会发生M
,反之亦然(以及更多特殊情况下的子模块);如果您添加T
和/或C
选项,则会出现--find-copies-harder
(加上数字相似度值);并且重命名检测会出现-C
(加上R
之类的数值)。 C
和C
个案不仅会打印状态和文件名,还会打印“原始文件名”。
您可以添加R
以仅选择特定事件:例如,--diff-filter
将仅选择状态为--diff-filter=A
(已添加)的文件。