赞
踩
例如,某个git项目有三个平行的目录p1/,p2/,p3/。随着开发进程的推移,发现这三个目录的代码或文件的关联度很低,实际上是各自独立的,例如最好用分支p1proj,p2proj,p3proj来进行管理。原来的master分支,可以废弃不用。用git subtree来实现这种拆分。
创建一个示例项目。
#!/bin/bash
mkdir proj && cd proj && git init . && mkdir p1 p2 p3
i=1;while (($i < 4));do
j=1
while (($j < 3));do
echo "$i.$j" > p$i/p$i.$j && git add p$i && git commit -m "p$i add p$i.$j"
((j++))
done
((i++))
done
# ls -R
.:
p1 p2 p3
./p1:
p1.1 p1.2
./p2:
p2.1 p2.2
./p3:
p3.1 p3.2
# gitk master
实现拆分
# git subtree split --prefix=p1 -b p1proj
# git subtree split --prefix=p2 -b p2proj
# git subtree split --prefix=p3 -b p3proj
# git branch
* master
p1proj
p2proj
p3proj
# gitk p1proj p2proj p3proj
# git checkout p1proj
Switched to branch 'p1proj'
# ls
p1.1 p1.2
p1proj分支只包含master分支p1目录下的内容。这个例子中,subtree之后master分支不再使用。例如,之后针对p1的开发,在p1proj分支上进行,不必再与master分支保持同步。
利用subtree引入第三方库,作为项目中的一个目录。这种方法与submodule不同。前者是将自己的代码与三方库融合在一起管理,不需要git submodule那样对子目录进行特殊配置。当第三方库有更新时,subtree pull命令可以拉取上游更新,与自己的代码merge在一起。
# 创建一个testlib用于测试
# mkdir testlib && cd testlib && git init . && \
echo "libfile1" > libfile1 && git add . && git commit -m "libfile1"
# 切换到proj项目master分支
# cd ../proj
# git branch
* master
# ls
p1 p2 p3
# 添加这个testlib库
# git subtree add --prefix=lib1 ../testlib master
git fetch ../testlib master
warning: no common commits
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
来自 ../testlib
* branch master -> FETCH_HEAD
Added dir 'lib1'
# ls
lib1 p1 p2 p3
# ls lib1/
libfile1
# git log
commit 52fb9c2e2e850715d91285c6c828b664341b8025
Merge: 8f03cd4 a4a0852
Author:
Date:
Add 'lib1/' from commit 'a4a08523d9f0a69a6481c9977606c9726cecd36b'
git-subtree-dir: lib1
git-subtree-mainline: 8f03cd40bdc5bcd371a30d53e73f7274aa64122a
git-subtree-split: a4a08523d9f0a69a6481c9977606c9726cecd36b
commit a4a08523d9f0a69a6481c9977606c9726cecd36b
Author:
Date:
libfile1

# 在testlib上发生了版本更新
# echo "libfile2" > libfile2 && git add libfile2 && git commit -m "libfile2"
# 在proj拉取testlib的更新
# git subtree pull --prefix=lib1 ../testlib master
# git log
commit dbf7b90f1dc9185eba0ee3c30ce79bad457365a8
Merge: 52fb9c2 6b9d5a8
Author:
Date:
Merge commit '6b9d5a80386cbd90c0314e9fb058cbecc5bdbe76'
commit 6b9d5a80386cbd90c0314e9fb058cbecc5bdbe76
Author:
Date:
libfile2

在split的时候,如果指定了rejoin参数,将会把新产生的提交合并到主项目。例如前面的例子,如果执行
git subtree split --prefix=p1 -b p1proj --rejoin
主分支将产生如下的提交序列
git log将显示重复的提交,一个是original,一个是synthetic。以上命令可以反复多次运行。例如,在master分支增加一个文件p1/p1.3,提交信息为“p1 add p1.3”。然后再次运行上面带有rejoin参数的subtree split命令。主分支的提交序列变为下图。
p1proj分支此时有三次提交。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。