我有一个Git存储库,其中包含许多子目录.现在我发现其中一个子目录与另一个子目录无关,应该分离到一个单独的存储库.
如何在将文件的历史记录保存在子目录中的同时执行此操作?
我想我可以制作一个克隆并删除每个克隆的不需要的部分,但我想这会给我一个完整的树,当检查旧版本等.这可能是可以接受的,但我宁愿能够假装两个存储库没有共享历史记录.
为了说清楚,我有以下结构:
XYZ/
.git/
XY1/
ABC/
XY2/
Run Code Online (Sandbox Code Playgroud)
但我想这样做:
XYZ/
.git/
XY1/
XY2/
ABC/
.git/
ABC/
Run Code Online (Sandbox Code Playgroud) 这个问题基于Detach子目录到单独的Git存储库中
我想分离一对,而不是分离一个子目录.例如,我当前的目录树如下所示:
/apps
/AAA
/BBB
/CCC
/libs
/XXX
/YYY
/ZZZ
Run Code Online (Sandbox Code Playgroud)
而我想这样做:
/apps
/AAA
/libs
/XXX
Run Code Online (Sandbox Code Playgroud)
该--subdirectory-filter参数git filter-branch将无法工作,因为它在第一次运行时除去了给定目录之外的所有内容.我认为使用--index-filter所有不需要的文件的参数会起作用(尽管很乏味),但如果我尝试不止一次运行它,我会得到以下消息:
Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?TIA
我试图将一个文件(称为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之外的所有文件,并且所有未触及它的提交都会从日志中删除吗?
此时我不知道该怎么办.有什么建议?
我的情况是,我有一个git repo从SVN转换为HG到GIT,我只想提取一个源文件.我也有像aÌ(编码不匹配损坏的Unicodeä)和文件名中的空格这样奇怪的字符.
看起来并不是特别容易,这就是为什么我会回答我自己的问题,尽管有很多关于git [index-filter | subdirectory-filter | filter-tree]的类似问题,因为我需要使用前面所有的来实现这一点!
所以问题是:"如何从存储库中提取一个文件并将其放在新存储库的根目录下?"
我想要的是这个问题.但是,我希望拆分为单独仓库的目录仍然是该仓库中的子目录:
我有这个:
foo/
.git/
bar/
baz/
qux/
Run Code Online (Sandbox Code Playgroud)
我想将它拆分为两个完全独立的存储库:
foo/
.git/
bar/
baz/
quux/
.git/
qux/ # Note: still a subdirectory
Run Code Online (Sandbox Code Playgroud)
如何在git中执行此操作?
如果有一些方法可以将所有新repo的内容移动到历史记录中的子目录中,我可以使用此答案中的方法.
我有一个SNMP代理项目,其中相关的MIB文件(*.smiv2文件)与它一起开发,但现在我想要它们在一个单独的git存储库中.
为了不丢失任何MIB文件历史,因为它们不是在现在的同一目录中启动,我不能只使用--subdirectory-filterfilter-branch,所以我尝试了--filter-index基于这个问题的方法.这个想法是删除所有没有结束的文件.smiv2(显然是在原始项目的新克隆上,在过程结束时将其推送到我的新MIBs回购).
为了简单起见,我选择使用ls-filesover ls-tree,而不是:
git filter-branch --prune-empty --index-filter 'git ls-tree -r --name-only \
--full-tree $GIT_COMMIT | grep -v ".smiv2$" | xargs git rm --cached \
--ignore-unmatch -r'
Run Code Online (Sandbox Code Playgroud)
我用过这个:
git filter-branch --prune-empty --index-filter 'git ls-files | \
grep -v ".smiv2$" | xargs git rm --cached --ignore-unmatch'
Run Code Online (Sandbox Code Playgroud)
但是在第一次提交中任何一个都失败了,因为它看起来git rm根本没有提供任何参数(--ignore-unmatch如果找不到提供的参数,我认为会正常工作,但是在没有提供参数的情况下不会这样做):
$ git filter-branch --prune-empty --index-filter 'git ls-files | \
> grep -v ".smiv2$" | xargs git rm --cached …Run Code Online (Sandbox Code Playgroud)