从你的文字描述来看,我
认为
您要说的是,您有一个单独的存储库,其中包含两个独立的(不相交的,技术上的)提交子图。例如,这里是这样一个存储库的图表:
C--D
/ \
A--B G--H <-- branch1
\ /
E--F <-- branch2
I--J--K--L <-- master
\
M--N <-- develop
这个特殊的图有四个“入口点”,即提交
F
和
H
在根于的子图中
A
并承诺
L
和
N
在根于的子图中
I
.
虽然这样一个存储库没有本质上的错误,也没有被破坏,但是将它拆分成两个独立的存储库相对容易。简单地从两个克隆开始,它们都是这样的。(您可以使用
git clone --mirror
以生成保留所有引用的镜像克隆。一定要删除他们的
origin
这样它们就不会同时指向原始的组合存储库。)
在一个这样的克隆中,如果存在任何其他引用,则删除任何外部标记分支名称、标签名和其他引用。
一
两个子图中:
C--D
/ \
A--B G--H <-- branch1
\ /
E--F <-- branch2
I--J--K--L [abandoned]
\
M--N [abandoned]
请确保包含指向有意放弃的子图的任何标记或其他名称。正常的图形查看命令,如
git log
,将不显示未引用的子图:它将
出现
将被移除,尽管它仍然存在。最终,未引用的子图将消失,或者您可以使用
git gc
. 克隆
从
此存储库将没有未引用的子图。
在其他两个克隆中,删除对
其他
子图:
C--D
/ \
A--B G--H [abandoned]
\ /
E--F [abandoned]
I--J--K--L <-- master
\
M--N <-- develop
和以前一样,未被引用的子图最终会消失。
注意,原始的两个独立子图存储库的任何克隆
可以
习惯于
git push
到
任何一个
这些分裂的克隆体。因此,任何第三个完全独立的存储库都可以
也
用于推送到这两个克隆体中的任何一个。为独立子图中的提交添加名称的任何推送都将导致整个独立子图进入推送的接收者。
As you surmise in a comment
,我怀疑这就是这种情况最初的起因。
您可以添加一个pre-receive钩子,该钩子拒绝添加新根提交的新名称,尽管据我所知,此表单没有方便的pre-receive钩子。做起来容易,但速度慢:快跑
git rev-list --all --max-parents=0 --count
计算现有根和第二根
git rev-list --all --max-parents=0 --count <hash>
若接受来自
git推送
. 如果计数增加,新的推送将添加一个新的根。
注意,可以添加一个新的根
不
不相交子图的一部分。例如,考虑“before and proposed after”图:
before:
A--B--C <-- master
after:
A--B--C--F--G <-- master
/
D--E
这种预接收钩子会拒绝这样的推送。这可能是你想要的,但可能不是;小心你的程序。:-)