Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Git显示移动文件的上游_Git - Fatal编程技术网

Git显示移动文件的上游

Git显示移动文件的上游,git,Git,如果我有一个被重命名过多次的文件,并且有一个已知的版本,我需要查看它在给定版本中的状态——我如何将当前文件名和版本映射到旧文件名git show似乎不够聪明: git show $rev:dir1/file1.c fatal: path 'dir1/file1.c' exists on disk, but not in 'a1b86bcbe9bb27f17ddf3c895135def0d366e0a0' 最小可复制示例: tmp> echo hi > dir0/file2.c t

如果我有一个被重命名过多次的文件,并且有一个已知的版本,我需要查看它在给定版本中的状态——我如何将当前文件名和版本映射到旧文件名<代码>git show似乎不够聪明:

git show $rev:dir1/file1.c
fatal: path 'dir1/file1.c' exists on disk, but not in 'a1b86bcbe9bb27f17ddf3c895135def0d366e0a0'

最小可复制示例:

tmp> echo hi > dir0/file2.c
tmp> git add dir0/file2.c; git commit -m "First commit"
[master 8c34d4f] First commit
 1 file changed, 1 insertion(+)
 create mode 100644 dir0/file2.c
tmp> git mv dir0/file2.c dir1/file2.c
tmp> git commit -m "moving file"
[master 7181e5b] moving file
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename {dir0 => dir1}/file2.c (100%)
tmp> echo Hello >> dir1/file2.c
tmp> git add -u; git commit -m "Last Commit"
[master 799192b] Last Commit
 1 file changed, 1 insertion(+)
tmp> git show HEAD^^:dir1/file2.c
fatal: path 'dir1/file2.c' exists on disk, but not in 'HEAD^^'
TL;博士 使用
git diff
并启用
--find renames
。(或,<代码> Git日志-遵循,内部做同样的事情)。对于编程消费,考虑使用<代码> Git DIFR树< /C> >或其他所谓的管道命令,其中有明确定义的输出格式。除了<代码> -M (简短的<代码>——查找Reims< /Calp>),考虑使用<代码> -DIFF过滤器< />代码>和/或<代码> -Z 标志。您可以直接比较两次提交,也可以像git log那样逐个提交;请参阅下面的详细描述

长的 如果我有一个被重命名过多次的文件,并且有一个已知的版本,我需要查看它在给定版本中的状态——我如何将当前文件名和版本映射到旧文件名

没有简单完美的答案

您在这里看到的问题是:文件X与文件Y“相同”意味着什么?在一些系统中,有简单(但最终总是不令人满意)的答案。例如,我们可以为文件X指定一个“inode编号”。如果我们随后重命名文件X而不更改其“inode编号”,那么我们可以稍后扫描所有文件以查找具有旧inode编号的文件。不管出现什么名称,这些都是文件X的名称。然而,我们真正做的只是声称“文件X”的真实名称是它的索引节点号,并且我们使用某种形式的假名称别名,我们在某种形式的表(隐藏或不隐藏)中查找它的真实名称,通过它我们可以访问真实的文件

这不令人满意的原因是,我们可以使用此恒定inode编号获取文件的全部内容,然后将其全部移动到具有其他inode编号的其他文件中。因为内部索引节点号决定了标识,所以我们现在认为这个空文件就是正确的文件。但是我们将这个空文件重命名为“X.defunct”,并将新的inode编号文件重命名为“X”,以便所有内容都清晰可见,就在一个名为X的文件中,但我们的系统坚持认为真正的X是没有内容的。我们的船已经腐烂了,然而,就在港口里,有一艘忒修斯的船,每个人都可以看到

当Linus Torvalds编写Git时,他意识到这些问题,并决定正确的方法不依赖于两种最常用的方法中的任何一种。大多数VCSE使用文件名或某种内部标识号(“索引节点号”或等效物)来跟踪单个文件。Git没有这样做。相反,每次提交只是记录每个文件,按照提交时的格式

稍后,如果我们选择任何一对提交,Git将(至少原则上):

  • 从某处提取两个完整的提交;然后
  • 将每个文件的内容与其他每个文件的内容进行比较
这样,例如,如果某个函数
f
lib
中,而某个函数
g
也在
lib
中,但是
f
现在在
lib\u part\u 1
中,
g
现在在
lib\u part\u 2
中,我们可以确定一个文件中的
f
与另一个文件中的
f
相同,并且一个文件中的
g
与第三个文件中的
g
相同

出于可计算性(即性能)的原因,考虑到当前的技术,Git实际上并不是每次都能做到这一切。一些命令,如
git-dull
,比其他命令(如
git-diff
)更愿意跨多个文件执行。但总的来说,这是一个总体思路:我们不局限于特定的文件,而是寻找特定的内容。随着计算机速度的提高,我们开始改变内容分析的工作方式

不过,就目前而言,它在git diff中的工作方式有点像。给定两个提交L和R(用于左和右),Git首先查看两个提交中的所有文件名。如果L和R都有一个文件名为
path/to/file.ext
,Git至少在开始时会假定这是“同一个文件”。这些文件被标识为“同一文件”,尽管内容可能不同

但是,如果文件被重命名,我们通常会发现L中有一些文件在R中根本没有对应的名称,反之亦然。通过比较gone-from-L-new-in-R文件(所有文件都是成对的)的内容,Git可以确定某个文件是否被重命名

由于Git的内部存储格式,Git首先快速检查一些文件是否完全匹配。如果是这样,它们将配对:标识为“同一文件”。这些已识别的对来自L和R中的一组不匹配的文件。只有剩余的文件才能对其内容进行分析。每个提议的配对都分配了一个相似性指数,即百分比分数。任何满足某个最小阈值的配对都将被保留,然后使用这种最佳配对将L和R上的文件标识为“相同”

所有这一切意味着,如果您采取任何一对提交并比较它们,如果一些文件被重命名,但它们的内容“非常相似”,Git将声明它们被重命名。此重命名附带的相似性索引值范围从1(几乎完全不同的零表示完全不同且不会配对)到100(完全相同)。计算这些分数非常昂贵,所以只有启用重命名查找时才会发生。在比较m时,重命名队列长度也有限制⋅n个可能的对(m个文件在左边,n个在右边)。1

这对我来说是什么
git diff --find-renames <revision-L> <revision-R>