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

Ran*_*ook 44 git git-filter-branch

我试图将一个文件(称为foo.txt)从一个存储库移动到另一个(不相关的)存储库,保留其历史记录.ebneter的问题显示了如何为子目录执行此操作.taw的问题有一些提示和建议,但不是一步一步的程序.jkeating的问题看起来很有希望,但对我没有用.针对此特定用例,谷歌搜索空洞.我正在寻找的是一系列明确的命令来实现这一目标.

我开始遵循的命令序列是:

$ git clone source-repo/ source-repo-copy
$ cd source-repo-copy
$ git filter-branch --tree-filter 'test ! "$@" = "foo.txt" && \
  git rm --cached --ignore-unmatch $@ || true' --prune-empty
Run Code Online (Sandbox Code Playgroud)

我的filter命令的逻辑是git rm所有不是foo.txt的文件.我添加了|| true命令以强制它具有零返回值以满足filter-branch.

我的目的是将source-repo-copy设置为我的目标存储库(target-repo)的远程,并假设git filter-branch过滤掉除foo.txt以外的所有内容,将source-repo-copy合并到target-repo中.不幸的是,这个git filter-branch命令似乎没有效果.它运行时没有任何错误,似乎在源代码库中通过600多次提交进行了研究,但是当它完成时,git log源代码复制中的和文件看起来是一样的.不应该丢失除foo.txt之外的所有文件,并且所有未触及它的提交都会从日志中删除吗?

此时我不知道该怎么办.有什么建议?

bla*_*ang 36

这对我有用,但有一个完整的目录.

如图所示这里

~$ cd neu
~/neu$ git filter-branch --subdirectory-filter FooBar HEAD
~/neu$ git reset --hard
~/neu$ git remote rm origin
~/neu$ rm -r .git/refs/original/
~/neu$ git reflog expire --expire=now --all
~/neu$ git gc --aggressive
~/neu$ git prune
~/neu$ git remote add origin git://github.com/FooBar/neu.git
Run Code Online (Sandbox Code Playgroud)

编辑:对于单个文件:

首先过滤目录:

 git filter-branch --prune-empty --subdirectory-filter myDirectory -- --all
Run Code Online (Sandbox Code Playgroud)

过滤单个文件:

 git filter-branch -f --prune-empty --index-filter "git rm --cached --ignore-unmatch $(git ls-files | grep -v 'keepthisfile.txt')"
Run Code Online (Sandbox Code Playgroud)

做一些清理:

 git reset --hard
 git gc --aggressive
 git prune
Run Code Online (Sandbox Code Playgroud)

这应该做到这一点.

  • 请在github上上传一个带有结构的testrepo.(或者告诉我层次结构).如果git由testDir/myFile {1..3} .txt组成,它可以正常工作.如果你的目录是空的,单个文件的过滤器不能工作,尝试irgnore目录过滤器和步骤过滤单.你的shell有可能无法很好地识别命令.git filter-branch -f --prune-empty --index-filter'git rm --cached --ignore-unmatch $(git ls-files | grep -v"keepFile.txt")' (2认同)
  • 起初我不清楚对单个文件而不是目录采取的步骤。对于任何类似困惑的人来说,这是我的理解:编辑中的两个“filter-branch”命令应该替换原始代码中的一个“filter-branch”命令。然后,“Do some cleanup”命令实际上包含在原始代码部分的其余部分中,并且应该按原样运行。最后,您需要`git push origin new-branch`。 (2认同)