我已将git存储库中的某些文件移动到新文件夹(foo)
中。当我在文件夹上执行git log (--follow)
时,只看到一个提交,即移动提交。(我为每个文件使用了git mv
)
test $ git log foo/
commit 97210f4e547279ab1bdb (HEAD -> develop)
Date: Fri Aug 17 10:41:29 2018 -0400
moving files to foo folder
test $ git log --follow foo/
commit 210f4e547279ab1bdb (HEAD -> develop)
Date: Fri Aug 17 10:41:29 2018 -0400
moving files to foo folder
对于文件夹中的文件,如果我尝试git log --follow
,我会看到它们的所有历史记录。
git log
命令对所有命令都是相同的,这表明我已经移动了文件。
test $ git log --follow foo/bar.txt
commit 97210f4e547279ab1bdb (HEAD -> develop)
Date: Fri Aug 17 10:41:29 2018 -0400
moving files to foo folder
test $ git log --follow foo/bar.txt
commit 97210f4e547279ab1bdb (HEAD -> develop)
Date: Fri Aug 17 10:41:29 2018 -0400
moving files to foo folder
commit 12a1dad45f70ec8d62f7
Date: Tue Oct 24 15:12:54 2017 -0400
Canned PowerShell
commit cbe9cce205640e606e13
Date: Thu Aug 3 20:32:00 2017 -0400
Policy for no maid
现在,我要移动此文件夹并保留历史记录。我尝试使用此命令
git filter-branch --subdirectory-filter foo -- --all
结果只有一次提交,因此在我将文件移到foo
文件夹之前,不会保留文件的历史记录。即使文件上的git log --follow
也仅显示一次提交。我尝试使用谷歌搜索功能,但是在移动文件之前找不到任何可以保留历史记录的内容。任何帮助,将不胜感激。
p.s:由于这些文件已提交到上游,并且之后还有提交,所以我不想重做此操作。
答案 0 :(得分:1)
至少从当前可用的Git版本开始,您无法从现在的位置到达想要的位置。
Git没有文件历史记录。 Git有承诺;提交历史记录。对于每个提交(由其唯一的哈希ID标识),存储库具有该提交或缺少该提交。每个提交都保留所有文件的快照,提供有关谁进行提交的元数据(以及何时以及为什么),并标识(通过哈希ID)其 parent 提交,或者对于合并,父提交(复数) )。
git log
命令根据需要通过遍历和显示提交来生成历史记录。也就是说,git log
显示一个提交,然后显示该提交的父级,依此类推。在合并提交(在历史记录分支的位置),git log
会同时显示和(和父母)(按一定顺序)。使用git log --graph
会强制Git按照对历史记录来说有意义的顺序显示提交,同时绘制该图的粗略文本表示形式。
给出可选参数,git log
可以遍历历史记录-图形-但省略某些提交,并且仅显示特别有趣的提交。 git log filename
就是这样工作的。假设您正在查看从master
的最后一次提交开始的历史记录。如果此提交的文件 filename
副本与父提交的副本相同,则git log
仅不显示提交< / em>。然后,它照常移回父级。如果父母的父母具有文件 filename
的其他版本,则git log
显示父母。然后git log
移至父母的父母,依此类推。
结果是您看到一个缩写历史记录,仅命名文件中的 filename
相对于该特定提交的父级已更改的那些提交。如果您想将其称为文件的历史记录,就可以了:但这不是Git中的实际内容,它是 commit graph 或 commit history ,只需选择来自的提交历史。看起来 文件历史记录,直到您仍然要重命名文件为止。
使用git log dir/
的工作方式几乎相同:它照常遍历提交历史记录,但是除非在{{1} }已更改,其中“已更改”表示将父提交与子提交进行比较显示某些文件已更改。
dir/
在目录上不起作用您不能在目录上使用git log --follow
。您只能在一个文件名上使用它。这样做的原因是该实现很糟糕。 (将来可能会有所改善。)git log --follow
在文件上的工作方式是使用Git的重命名检测。
请记住,每个提交仅代表一个快照。假设我们有一个父提交,哈希为--follow
,子提交为哈希G
。 Git决定在提交H
和olddir/doc.txt
之间重命名的某个文件(例如G
)的方式是:
H
存在于olddir/doc.txt
中,但不存在于G
H
存在于newdir/doc.txt
中,但不存在于H
G
(在olddir/doc.txt
中的G
(在newdir/doc.txt
中)的内容完全相同,完全相同(此测试非常快)或在某种相似性约束内(默认相似度为50%)。 H
工作时,它将寻找一个在父git log --follow newdir/doc.txt<
和子olddir/doc.txt
之间触及文件G
的提交。如果遇到将重命名 H
到olddir/doc.txt
的提交,它将打印该提交-然后停止寻找newdir/doc.txt
并开始寻找改为olddir/doc.txt
。
它使用一个完整的路径名来完成。如果您有newdir/doc.txt
搜索目录,它将永远不会检测到重命名,因为它只会检测重命名的文件。
(最近曾尝试修复/更改此问题,但它还是出错了。希望很快会有更好的版本。)
在任何情况下,您的存储库中的提交都具有使用旧名称和新名称的文件,或者没有。如果没有提交,则不会发现它们。如果确实有提交,将来的Git也许可以找到整个目录的重命名,但是当前版本的Git找不到。