清除已删除文件的git历史记录,保留已重命名文件的历史记录
我想将一些文件提取到一个新的repo,保留它们的历史,包括文件重命名 我能找到的最好和最接近的答案是,使用清除已删除文件的git历史记录,保留已重命名文件的历史记录,git,version-control,git-filter-branch,Git,Version Control,Git Filter Branch,我想将一些文件提取到一个新的repo,保留它们的历史,包括文件重命名 我能找到的最好和最接近的答案是,使用git filter branch--index filter。它成功地保留了现有文件的历史记录,但不保留重命名文件的历史记录 (我能找到的另一个答案是使用git filter branch--subdirectory filter。但它有两个问题:似乎不适用于整个repo(文件夹“.”),并且不保留重命名文件的历史记录。) (另一个答案是使用git子树。但它根本不保留历史。) 因此,我可能
git filter branch--index filter
。它成功地保留了现有文件的历史记录,但不保留重命名文件的历史记录
(我能找到的另一个答案是使用git filter branch--subdirectory filter
。但它有两个问题:似乎不适用于整个repo(文件夹“.”),并且不保留重命名文件的历史记录。)
(另一个答案是使用git子树
。但它根本不保留历史。)
因此,我可能正在寻找一种方法来改进
git ls files>将这些.txt
命令从最接近的答案保留到列出所有以前的文件名。可能是脚本?Git不存储文件名更改
每个提交存储一个完整的树,例如,可能提交1234567…
有文件README
和foo.txt
和提交fedcba9。。。有文件readme.txt
和foo
。如果让git将commit1234567
与commitfedcba9
进行比较,并且README
与README.txt
非常相似,git会说将一个提交转换为另一个提交的方法是重命名文件。(如果一个提交是另一个提交的父级,则子提交的git show
将显示重命名,因为git show
在git show
时间计算此更改。)
另一方面,如果第二个自述文件
差异太大,但自述文件
与foo
非常相似,git会说更改1234567
以实现fedcba9
的方法是将自述文件
重命名为foo
关键是git会在您请求比较时进行计算,而不是更早。在提交之间没有写“重命名某些文件”的内容。Git只是比较提交,然后决定文件是否足够相似
出于您的目的,这最终意味着对于要复制或部分复制的提交序列中的每个提交,您必须决定保留哪些路径名,以及放弃哪些路径名。如何做到这一点主要取决于你。git log
命令确实有一个--follow
标志,当它从子提交到其父提交向后工作时,会激活有限数量的重命名检测,并且git bull
会自动尝试这样做;您可以使用这些(一次一个路径名)来生成表单的映射:
in: commits A..B C..D E..F
use path: dir/file.ext dir/frill.txt lib/frill.next
比如说。但这并没有内在的东西,也不会特别容易。我首先将git log--follow
与--raw
或--name status
输出相结合,并查看是否检测到任何有趣的重命名。如果存在,则这些是提交边界,在执行提交时,您需要更改保留和放弃的路径(无论是使用过滤器分支
还是其他方法)
如果这不起作用,或者您需要更多的控制,请考虑在不同的提交对之间运行<代码> Git DIF-name状态< /代码>(提交代码信息来自<代码> GIT Rev List)。
1只要您要求进行重命名检测,“完全相同”就足够相似,任何低至“50%相似”的情况都一样。您可以使用提供给
git diff
的-M
标志的可选值调整所需的相似性
编辑:这似乎可以正常工作。我在git自己的
builtin/var.c
上使用了它,根据这一点,它以前有两个名称:
$ git log --follow --raw --diff-filter=R --pretty=format:%H builtin/var.c
81b50f3ce40bfdd66e5d967bf82be001039a9a98
:100644 100644 2280518... 2280518... R100 builtin-var.c builtin/var.c
55b6745d633b9501576eb02183da0b0fb1cee964
:100644 100644 d9892f8... 2280518... R096 var.c builtin-var.c
--diff过滤器
会抑制除重命名输出之外的所有内容,以便查看哪个提交似乎会重命名文件。将其转化为更有用的功能需要做更多的工作,但这可能会让您走得更远:
git log --follow --raw --diff-filter=R --pretty=format:%H builtin/var.c |
while true; do
if ! read hash; then break; fi
IFS=$'\t' read mode_etc oldname newname
read blankline
echo in $hash, rename $oldname to $newname
done
产生了:
in 81b50f3ce40bfdd66e5d967bf82be001039a9a98, rename builtin-var.c to builtin/var.c
in 55b6745d633b9501576eb02183da0b0fb1cee964, rename var.c to builtin-var.c
你能提供一个脚本来列出以前的文件名吗?我不知道怎么做,而且我有数百个文件要处理,所以不能一次手动分析一个文件的日志。默认50%相似对我来说很好。多亏了你,我在read-r行中获得了带有
git ls files |的旧文件名列表;do(git log--follow--raw--diff filter=R--pretty=format:%H“$line”|为true;do if!读取哈希;然后break;fi;IFS=$'\t'读取模式\u等oldname newname;读取空行;echo$oldname;done);完成