Ada*_*sey 2 git git-filter-branch
我正在尝试在两个git存储库repo1和之间移动某些文件repo2。我有一小段要移动的文件(保留历史记录)。
来自repo1以下三个文件:
libraryname/file1
libraryname/file2
tests/libraryname/file3
Run Code Online (Sandbox Code Playgroud)
还有在其他文件libraryname/和tests/libraryname/。还有在其他文件夹/和tests/
我的计划是checkout repo1,然后修改历史记录树,直到它仅包含我感兴趣的文件的历史记录。然后checkout repo2,并合并到上一个操作的输出中。似乎git filter-branch是第一步的正确工具。
到目前为止,我已经尝试过git filter-branch --index-filter 'git rm -r --cached <FILES>'
在哪里<FILES>列出所有不需要的整个文件夹或文件。
但这留下了许多文件夹,这些文件夹不再存在于HEAD,而是在此存储库生存期的某个时刻存在。弄清楚该回购历史中已存在的一切似乎很乏味-必须有更好的方法
我如何最终得到仅包含这三个文件的git commit树?有没有比我建议的更好的方法?或者,是否可以删除所有当前不存在的文件的痕迹HEAD?
您说它留在文件夹后面;我以为您的意思是它在这些文件夹中留下了文件(因为git不会保留空文件夹)...
似乎您可能想采用清除索引,然后重新添加所需条目的方法。
git filter-branch ...
--index-filter 'git rm -r --cached * && git reset $GIT_COMMIT -- libraryname/file1 libraryname/file2 tests/libraryname/file3
...
Run Code Online (Sandbox Code Playgroud)
由于您将内容精简了很多,所以请不要忘记您想包含一个--prune-empty选项
使用 Git 2.24(2019 年第四季度),git filter-branch已弃用。
等效的将是, using newren/git-filter-repo,及其示例部分:
如果你有很长的文件、目录、globs 或正则表达式列表来过滤,你可以把它们放在一个文件中并使用
--paths-from-file; 例如,有一个名为文件stuff-i-want.txt与内容
README.md
guides/
tools/releases
glob:*.py
regex:^.*/.*/[0-9]{4}-[0-9]{2}-[0-9]{2}.txt$
tools/==>scripts/
regex:(.*)/([^/]*)/([^/]*)\.text$==>\2/\1/\3.txt
Run Code Online (Sandbox Code Playgroud)
然后你可以跑
git filter-repo --paths-from-file stuff-i-want.txt
Run Code Online (Sandbox Code Playgroud)
在你的情况下,stuff-i-want.txt将是:
libraryname/file1
libraryname/file2
tests/libraryname/file3
Run Code Online (Sandbox Code Playgroud)
在 Ubuntu 20.04 上运行良好,
pip3 install git-filter-repo因为它仅支持 stdlib 并且不安装任何依赖项。在 Ubuntu 18 上,它与发行版的 git 版本不兼容,但它很容易在
docker run -ti ubuntu:20.04