如何在保留历史记录的同时将文件从一个 git 存储库移动到另一个
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10524578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to move a file from one git repository to another while preserving history
提问by Randall Cook
I am trying to move a single file (call it foo.txt) from one repository to another (unrelated) repository, preserving its history. ebneter's questionshows how to do this for a subdirectory. taw's questionhas some hints and suggestions, but not a step-by-step procedure to follow. jkeating's questionlooked promising, but didn't work for me. Google searches came up empty for this particular use case. What I am looking for is a clear sequence of commands to accomplish this.
我试图将单个文件(称为 foo.txt)从一个存储库移动到另一个(不相关的)存储库,以保留其历史记录。ebneter 的问题显示了如何为子目录执行此操作。taw 的问题有一些提示和建议,但不是要遵循的分步程序。jkeating 的问题看起来很有希望,但对我不起作用。对于此特定用例,Google 搜索结果为空。我正在寻找的是完成此操作的清晰命令序列。
The sequence of commands I started to follow was this:
我开始遵循的命令序列是这样的:
$ 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
The logic of my filter command is to git rm
all files that are not foo.txt. I added the || true
to the command to force it to have a zero return value to satisfy filter-branch.
我的过滤器命令的逻辑是git rm
所有不是 foo.txt 的文件。我|| true
在命令中添加了以强制它具有零返回值以满足过滤器分支。
My intention was to set source-repo-copy as a remote for my target repository (target-repo), and assuming git filter-branch
filtered out everything but foo.txt, fetch and merge source-repo-copy into target-repo. Unfortunately, the git filter-branch
command seemed to have no effect. It ran with no errors and appeared to grind through the 600+ commits in source-repo, but when it finished, the git log
and files in source-repo-copy looked the same. Shouldn't all files but foo.txt be missing and all commits that didn't touch it be gone from the log?
我的意图是将 source-repo-copy 设置为我的目标存储库 (target-repo) 的远程副本,并假设git filter-branch
过滤掉除 foo.txt 之外的所有内容,然后将 source-repo-copy 提取并合并到 target-repo 中。不幸的是,该git filter-branch
命令似乎没有效果。它运行时没有错误,并且似乎在源代码库中的 600 多个提交中进行了打磨,但是当它完成时,git log
源代码库副本中的和 文件看起来相同。难道除了 foo.txt 之外的所有文件都应该丢失,并且所有未触及它的提交都应该从日志中消失吗?
At this point I don't know how to proceed. Any suggestions?
在这一点上我不知道如何继续。有什么建议?
采纳答案by blang
This worked for me, but with a whole directory.
这对我有用,但有一个完整的目录。
As shown 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
EDIT: For a single file:
编辑:对于单个文件:
Filter the directory first:
先过滤目录:
git filter-branch --prune-empty --subdirectory-filter myDirectory -- --all
Filter the single file:
过滤单个文件:
git filter-branch -f --prune-empty --index-filter "git rm --cached --ignore-unmatch $(git ls-files | grep -v 'keepthisfile.txt')"
Do some cleanup:
做一些清理:
git reset --hard
git gc --aggressive
git prune
This should do it.
这应该做。