如何将文件从存储库移动到保存存储文件的另一个存储库历史记录

时间:2018-08-17 17:35:46

标签: git repository

我已将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:由于这些文件已提交到上游,并且之后还有提交,所以我不想重做此操作。

1 个答案:

答案 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决定在提交Holddir/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的提交。如果遇到将重命名 Holddir/doc.txt的提交,它将打印该提交-然后停止寻找newdir/doc.txt并开始寻找改为olddir/doc.txt

它使用一个完整的路径名来完成。如果您有newdir/doc.txt搜索目录,它将永远不会检测到重命名,因为它只会检测重命名的文件

(最近曾尝试修复/更改此问题,但它还是出错了。希望很快会有更好的版本。)

在任何情况下,您的存储库中的提交都具有使用旧名称和新名称的文件,或者没有。如果没有提交,则不会发现它们。如果确实有提交,将来的Git也许可以找到整个目录的重命名,但是当前版本的Git找不到。