繁体   English   中英

如何在git repo的特定目录中还原所有已删除的文件?

[英]How do I restore all deleted files in a particular directory of a git repo?

我们想在git repo的特定目录及其所有子目录中恢复已删除的文件。

该目录包含我们的数据库迁移。 名称和内容可以更改(重命名,删除,添加),并且在最近5年或5年内都可以更改。

现在我们意识到我们还没有所有迁移的完整列表,因此想从存储库中恢复它们。

我们想要实现的是在删除之前将所有文件还原为它们的最后一种形式。

据我了解,这对所有重命名的文件可能并不是特别有效,但是我们可以手动进行分类。

每个文件的名称都有2个部分,一个时间戳和一个迁移名称-名称保持不变,但是时间戳部分在重命名过程中会更改。

例如:20150101010101_inital_migration.sql可能已重命名为20150101010102_inital_migration.sql。

内容可能稍有变化,但名称的“ initial_migration”部分不会更改。 不知道这是否有任何用处,但是如果在git本身中没有办法进行重命名,那将是我们如何检测重命名。

如果文件更改如此不同,以致被记录为实际删除和新文件,则删除之前的文件将生效。 一旦文件的所有最终形式都存在,我们便可以浏览文件。

编辑1-得到了已删除文件的列表,但无法处理它们。

所以我有一些进一步的方法: git log --diff-filter=D --summary migrations/

将显示所有已删除的文件(10,190 ...哎哟!)。

运行: git log --diff-filter=D --summary migrations/ | grep 'delete mode' | grep -o migr.* git log --diff-filter=D --summary migrations/ | grep 'delete mode' | grep -o migr.* git log --diff-filter=D --summary migrations/ | grep 'delete mode' | grep -o migr.*将向我显示所有已删除的文件。

但是尝试通过xargs运行它(慢速?不在乎!这是一个问题): git log --diff-filter=D --summary migrations/ | grep 'delete mode' | grep -o migr.* | xargs -I {} git checkout $commit~1 "{}" git log --diff-filter=D --summary migrations/ | grep 'delete mode' | grep -o migr.* | xargs -I {} git checkout $commit~1 "{}" git log --diff-filter=D --summary migrations/ | grep 'delete mode' | grep -o migr.* | xargs -I {} git checkout $commit~1 "{}" ...

$ git log --diff-filter=D --summary migrations/ | grep 'delete mode' | grep -o migr.* | xargs -I {} git checkout $commit~1 "{}"
error: pathspec '~1' did not match any file(s) known to git
error: pathspec 'migrations/20190727100901_in651_fix_item_id_on_order_items_table.php' did not match any file(s) known to git
error: pathspec '~1' did not match any file(s) known to git
error: pathspec 'migrations/20190130101201_bac1005_add_paysera_payment_gateway_driver.php' did not match any file(s) known to git
error: pathspec '~1' did not match any file(s) known to git
error: pathspec 'migrations/20190210174730_truncate_phinx_log_20190210174730.php' did not match any file(s) known to git
error: pathspec '~1' did not match any file(s) known to git
error: pathspec 'migrations/20190212110201_fix_end_times_in_sessions.php' did not match any file(s) known to git
error: pathspec '~1' did not match any file(s) known to git
error: pathspec 'migrations/20190212171608_bac1611_delete_orders.php' did not match any file(s) known to git
error: pathspec '~1' did not match any file(s) known to git
error: pathspec 'migrations/20190212174401_bac1610_make_contact_pseudonymisation_not_nullable.php' did not match any file(s) known to git
...

编辑2- $commit部分应该是提交哈希,而不是文字$commit h!

编辑3-因此,确定哈希和删除的文件分别显示后,我编写了一个小的过滤器来处理git log命令的输出并生成git checkout命令。

<?php

$lastHash = null;

while (false !== ($line = fgets(STDIN))) {
    // Is the line a hash?
    if (preg_match('`(?P<hash>[a-f0-9]{10}) `', $line, $matches)){
        $lastHash = $matches['hash'];
    } else {
        preg_match('`(?P<file>migrations/.*$)`', $line, $matches);
        echo sprintf('git checkout %s~1 "%s"', $lastHash, $matches['file']), PHP_EOL;
    }
}

所以我的最终命令是git log --diff-filter=D --summary --oneline migrations/ | php ../ugd.php | bash git log --diff-filter=D --summary --oneline migrations/ | php ../ugd.php | bash

与很多事情一样,总是有其他方法来思考问题。

因此,git log命令可以向我显示从特定目录中删除文件的提交哈希。

git log --diff-filter=D --summary --oneline migrations/

处理此输出需要读取2种不同类型的线并使用两条线中的值。

第一行包含哈希,另一行包含文件名。

因此,使用基于PHP的过滤器将日志输出转换为还原文件的命令列表非常简单。

<?php

$lastHash = null;

while (false !== ($line = fgets(STDIN))) {
    // Is the line a hash?
    if (preg_match('`(?P<hash>[a-f0-9]{10}) `', $line, $matches)){
        $lastHash = $matches['hash'];
    } else {
        preg_match('`(?P<file>migrations/.*$)`', $line, $matches);
        echo sprintf('git checkout %s~1 "%s"', $lastHash, $matches['file']), PHP_EOL;
    }
}

这将生成类似

git checkout a653b7f95a~1 "migrations/20140514122900_populate_dimensions.php"
git checkout 75a2989b5b~1 "migrations/20140116173610_drop_xusers_copy.php"
git checkout b0de683071~1 "migrations/20140114163419_initial_migration.php"

然后,通过bash运行此输出将恢复所有已删除的文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM