46

我正在尝试将单个文件(称为 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

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

我的意图是将 source-repo-copy 设置为我的目标存储库 (target-repo) 的远程,并假设git filter-branch过滤掉除 foo.txt 之外的所有内容,获取 source-repo-copy 并将其合并到 target-repo 中。不幸的是,该git filter-branch命令似乎没有效果。它运行没有错误,并且似乎通过了 source-repo 中的 600 多个提交,但是当它完成时,git logsource-repo-copy 中的和文件看起来是一样的。除了 foo.txt 之外的所有文件都不应该丢失,并且所有没有触及它的提交都应该从日志中消失吗?

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

4

1 回答 1

37

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

如此处所示

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

这应该这样做。

于 2012-05-09T21:57:07.583 回答