从已有的仓库子目录创建新的git仓库

12

我想从已经存在的仓库的子文件夹中创建一个独立的仓库。

将(移动)子目录分离为单独的Git存储库 就是这样做的。但是,我无法得到干净的仓库。新仓库有两个问题:

  1. 历史记录似乎重复了;
  2. 我无法保留分支历史记录。

这是我所做的:

$ git clone ssh://.../repo.git
$ cd repo
$ git filter-branch --subdirectory-filter subdirectory HEAD -- --all
$ git reset --hard
$ git gc --aggressive
$ git prune

在此之后,似乎我拥有了仓库的原始历史和新的历史。我输入 "git log --all --graph" (或 gitk --all) ,我看到,作为第一次提交,是第一个仓库的最初提交。然后,图形显示了原始仓库的完整历史,直到最后一次提交。接下来,我有了第二个历史,位于第一个历史之上,只显示我想要的子文件夹的历史。但在那部分历史中,我只有 "master" 而没有分支/合并。
"git log"、gitk 或 gitg 都仅显示 "flatten" 历史,不显示子文件夹的平坦历史之前的原始仓库历史。
我尝试只使用 "filter-branch" 命令,在克隆结果仓库时(用--no-hardlinks),使用:
$ git filter-branch --subdirectory-filter subdirectory -- --all

而不是:

$ git filter-branch --subdirectory-filter subdirectory HEAD -- --all

但结果相同。

我是做错了什么还是git出了问题?我真的没有头绪...使用git 1.7.6。谢谢。

编辑:我认为问题可能来自于合并提交被filter-branch忽略,从而得到一个平坦的历史记录,没有分支或合并...


使用 git branch -a 命令可以查看分支历史吗? - Andy
$ git branch -a
  • 主分支 远程/origin/HEAD -> origin/master 远程/origin/master
- big_gie
4个回答

4

你有两个问题:

(1) 正如Kevin Ballard所指出的那样,你需要删除.git目录中的refs/original目录以摆脱虚假的日志条目;如果我没记错,这在你所提到的问题中已经提到了。

(2) 你必须逐个转换分支。据我所知,这没有在任何地方提到,但通过实证很容易发现。一个执行此操作的脚本应该类似于以下内容:

for branch in $(git for-each-ref --format='%(refname:short)' refs/remotes/origin | grep -v HEAD); do
  git checkout -b $(basename $branch) $branch
  git filter-branch -f --subdirectory-filter subdirectory HEAD -- --all
done

请注意,您需要使用-f参数或类似--original $(basename $branch)-original的选项来强制git重用或重命名存储原始引用的名称空间。还要注意,如果子目录在特定分支上不存在,则可能会看到类似“未找到要重写的内容”的消息 - 您可能需要从新存储库中删除这些分支。(或在运行脚本之前将其删除)。

有没有办法通过扩展脚本来自动删除筛选分支返回“未发现要写入的内容”的操作? - shaioz

3
Github有一个直截了当的方法:

https://help.github.com/articles/splitting-a-subpath-out-into-a-new-repository

  1. 克隆完整的仓库:git clone https://github.com/USERNAME/REPOSITORY-NAME
  2. 进入仓库根目录:cd REPOSITORY-NAME
  3. 过滤掉子文件夹 A/B/Cgit filter-repo --path A/B/C/
    • 安装 git-filter-repopip install git-filter-repo(或使用其他方法)
    • 提供相对于根目录的路径结构
    • 即使在 Windows 上也要使用正斜杠(该路径是指 git 对象,而不是文件系统上的位置)

1

我认为你需要删除你的远程。例如:

git remote rm origin

当我运行git log --allgitk --all并看到所有提交时,我也曾有过与你相同的想法。然后我意识到额外的提交来自远程。


0

git filter-branch 会将所有原始引用保存在它们自己的命名空间下(在 original/ 下)。这似乎是你的 git log --all 也显示了这些引用。相反,你应该检查所有你关心的引用,如果它们看起来不错,那么你可以丢弃 original/ 命名空间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接