从已有的repo子目录创建新的git repo

时间:2011-07-13 14:40:48

标签: git

我想从已经存在的repo的子文件夹创建一个单独的repo。

Detach (move) subdirectory into separate Git repository显示了这一点。但是,我无法用它获得一个干净的回购。我最终遇到了两个新的回购问题:

  1. 历史似乎重复;
  2. 我无法保留分支机构的历史。
  3. 这是我做的:

    $ 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)我看到,作为第一个提交,第一个repo的初始提交。然后,图表显示原始repo的完整历史记录,直到最后一次提交。然后,我在第一个上面有一个SECOND历史,显示了我想要的子文件夹的历史。但在历史的那一部分,我只有“主人”,没有分支/合并。

    “git log”,gitk或gitg都只显示“flatten”历史:它们不会在子文件夹的展平历史之前显示初始回购的历史记录。

    我尝试使用“filter-branch”命令,克隆生成的repo(使用--no-hardlinks),使用:

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

    而不是:

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

    但结果相同。

    我做错了什么或者git坏了吗?我真的没有想法......使用git 1.7.6。感谢。

    编辑:我认为问题可能来自于filter-branch忽略了merge提交,因此给出了没有分支或合并的平面历史记录......

4 个答案:

答案 0 :(得分:4)

这里有两个问题:

(1)正如Kevin Ballard指出的那样,你需要删除.git目录中的refs / original目录来摆脱虚假的日志条目; IIRC在你提到的问题中提到了这一点。

(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重用或重命名存储原始引用的命名空间。另请注意,如果特定分支上不存在子目录,您可能会看到“无需重写”等消息 - 您可能希望从新存储库中删除这些分支。 (或者在运行脚本之前删除它们。)

答案 1 :(得分:2)

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

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

git clone git://github.com/defunkt/github-gem.git

cd github-gem/ 将目录更改为存储库

git filter-branch --prune-empty --subdirectory-filter lib master

答案 2 :(得分:1)

我认为你需要删除你的遥控器。 e.g。

git remote rm origin

当我运行git log --allgitk --all并看到所有提交时,我想到了同样的事情。然后我意识到额外的提交来自遥控器。

答案 3 :(得分:0)

git filter-branch将所有原始引用保存到自己的命名空间中(在original/下)。听起来你的git log --all也在显示那些裁判。您应该检查所关注的所有引用,如果它们看起来不错,那么您可以丢弃original/命名空间。