我试图将一个文件(称为foo.txt)从一个存储库移动到另一个(不相关的)存储库,以保留其历史记录。 ebneter's question显示了如何对子目录执行此操作。 taw's question有一些提示和建议,但没有遵循的分步过程。 jkeating's question看起来很有前途,但对我没有用。对于此特定用例,Google搜索为空。我正在寻找一个明确的命令序列来完成此任务。

我开始遵循的命令顺序如下:

$ 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

我的filter命令的逻辑是对不是foo.txt的所有文件git rm。我在命令中添加了|| true,以使其具有零返回值以满足过滤器分支。

我的意图是将source-repo-copy设置为目标存储库(target-repo)的远程服务器,并假定git filter-branch过滤掉了foo.txt之外的所有内容,然后将source-repo-copy提取并合并到target-repo中。不幸的是,git filter-branch命令似乎无效。它没有错误地运行,并且似乎可以遍历source-repo中的600多个提交,但是完成后,git log和source-repo-copy中的文件看起来是相同的。除了foo.txt以外的所有文件都应该丢失,并且所有没有触及的提交都应该从日志中消失吗?

在这一点上,我不知道如何进行。有什么建议?

最佳答案

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

如图所示here

~$ 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

编辑:对于单个文件:

首先过滤目录:
 git filter-branch --prune-empty --subdirectory-filter myDirectory -- --all

过滤单个文件:
 git filter-branch -f --prune-empty --index-filter "git rm --cached --ignore-unmatch $(git ls-files | grep -v 'keepthisfile.txt')"

做一些清理:
 git reset --hard
 git gc --aggressive
 git prune

这应该做。

08-26 21:48
查看更多