git subtree使用
【直接使用subtree最简单】
已存在工程:
https://github.com/timwind/testPlatform.git
https://github.com/timwind/testProjectC.git
在本地clone testProjectC后进入testProjectC目录:
git subtree add --prefix=platform https://github.com/timwind/testPlatform.git master
该目录下新增一个platform目录,并且已clone testPlatform工程。如果platform已存在,会报错:prefix 'platform' already exists.
当platform有新的更改,git pull 不会自动拉取(只会拉取testProjectC的改动),若拉取,需单独执行命令:
git subtree pull --prefix=platform https://github.com/timwind/testPlatform.git master
当拉取后,本地会merge一个新的提交,该提交可以push到testProjectC的工程中,这样其他人员clone工程或者使用git pull时,会自动下载的platform已是merge版本。
以下命令支持在testProjectC直接修改platform,因避免冲突,暂时不建议使用该功能。更要注意的是:禁止直接修改platform push到testProjectC。
git subtree push --prefix=platform https://github.com/timwind/testPlatform.git master
【另一种方式,不推荐】
1. 进入testProjectA工程,git branch -a的结果:
$ git branch -a
develop
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/platform/master
2. 建立远程仓库(实际并没有push到远程)
$ git remote add -f platform_test https://github.com/timwind/testPlatform.git
Updating platform_test
From https://github.com/timwind/testPlatform
* [new branch] master -> platform_test/master
With -f option, git fetch <name> is run immediately after the remote information is set up.
platform: 名称可任取
创建后:
$ git branch -a
develop
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/platform/master
remotes/platform_test/master
3. 合并platform工程到该工程,该步是为下步做准备
$ git merge -s ours --no-commit --allow-unrelated-histories platform_test/master
Already up-to-date.
-s <strategy>:
Use the given merge strategy; can be supplied more than once to specify them in the order they should be tried. If there is no -s option, a built-in list of strategies is used instead (git merge-recursive when merging a single head, git merge-octopus otherwise).
With --no-commit perform the merge but pretend the merge failed and do not autocommit, to give the user a chance to inspect and further tweak the merge result before committing.
--allow-unrelated-histories
By default, git merge command refuses to merge histories that do not share a common ancestor. This option can be used to override this safety when merging histories of two projects that started their lives independently. As that is a very rare occasion, no configuration variable to enable this by default exists and will not be added.
4. 创建一个目录,拷贝平台工程到该目录
$ git read-tree --prefix=platform/ -u platform_test/master
--prefix=<prefix>/
Keep the current index contents, and read the contents of the named tree-ish under the directory at <prefix>. The command will refuse to overwrite entries that already existed in the original index file. Note that the <prefix>/ value must end with a slash
-u
After a successful merge, update the files in the work tree with the result of the merge.
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: platform/PublicSource/test.cpp
new file: platform/PublicSource/test.h
new file: platform/README.md
$ cd platform
$ ls
PublicSource/ README.md
5. 提交到本地缓存
$ git commit -m "Subtree merged in platform"
[master 3beef25] Subtree merged in platform
3 files changed, 19 insertions(+)
create mode 100644 platform/PublicSource/test.cpp
create mode 100644 platform/PublicSource/test.h
create mode 100644 platform/README.md
6. 当testPlatform工程有修改时,使用git pull获取最新platform代码
$ git pull -s subtree platform_test master
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 1), reused 4 (delta 1), pack-reused 0
Unpacking objects: 100% (4/4), done.
From https://github.com/timwind/testPlatform
* branch master -> FETCH_HEAD
63b5d1a..5a1c343 master -> platform_test/master
Merge made by the 'subtree' strategy.
platform/PublicSource/test.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
注:若远程testProjectA有修改,依旧可以使用git fetch/git merge获取,并且这两个命令不会更新platform子树的代码。
7. 可以使用git push推送到远程origin/master分支
注1:当再次使用git clone重新克隆一个新工程时,必须重新调用git 设置远程分支
参考指令:
$ mkdir temp
$ cd temp
$ git clone https://github.com/timwind/testProjectA.git
Cloning into 'testProjectA'...
remote: Counting objects: 106, done.
remote: Compressing objects: 100% (67/67), done.
remote: Total 106 (delta 28), reused 98 (delta 23), pack-reused 0
Receiving objects: 100% (106/106), 9.92 KiB | 0 bytes/s, done.
Resolving deltas: 100% (28/28), done.
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
$ git remote add -f subtree-platform https://github.com/timwind/testPlatform.git
Updating subtree-platform
From https://github.com/timwind/testPlatform
* [new branch] master -> subtree-platform/master
这里故意取了一个不一样的名字:subtree-platform
$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/subtree-platform/master
$ git pull -s subtree subtree-platform master
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 1), reused 4 (delta 1), pack-reused 0
Unpacking objects: 100% (4/4), done.
From https://github.com/timwind/testPlatform
* branch master -> FETCH_HEAD
5a1c343..e2b6f20 master -> subtree-platform/master
Merge made by the 'subtree' strategy.
platform/PublicSource/test.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
这里存在疑问,由于测试了2次,所以testPlatform的工程目录实际上有2个,
MINGW64 /f/study/01_work/temp/testProjectA (master)
$ ls
platform/ platform_for_projectA/ projectA.txt README.md
重新clone的工程仅仅设置了远端仓库为subtree-platform,并没有设置platform目录还是platform_for_projectA目录,但pull后只会更新platform的代码,可能跟subtree的合并策略有关。
注2:
人为限制不能在testProjectA工程中修改platform的代码,不建议这样做,没有尝试过
注3:
在testProjectA工程中创建本地分支后,无法更新platform,这种情况属于正常,因为归属本地分支?
$ git branch develop_test
$ git checkout develop_test
Switched to branch 'develop_test'
$ git branch -a
* develop_test
master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/platform2/master
remotes/subtree-platform/master
$ git fetch
$ git merge
fatal: No remote for the current branch.
$ git pull -s subtree subtree-platform
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 1), reused 4 (delta 1), pack-reused 0
Unpacking objects: 100% (4/4), done.
From https://github.com/timwind/testPlatform
e2b6f20..cc5c0de master -> subtree-platform/master
You asked to pull from the remote 'subtree-platform', but did not specify
a branch. Because this is not the default configured remote
for your current branch, you must specify a branch on the command line.
参考资料:
https://stackoverflow.com/questions/571232/svnexternals-equivalent-in-git
https://help.github.com/articles/about-git-subtree-merges/
http://www.linuxidc.com/Linux/2014-12/110771.htm 使用submodule引用
【git remote】
git remote 命令允许你创建、查看和删除和其它仓库之间的连接。远程连接更像是书签,而不是直接跳转到其他仓库的链接。它用方便记住的别名引用不那么方便记住的 URL,而不是提供其他仓库的实时连接。
git remote
列出你和其他仓库之间的远程连接。
git remote -v
和上个命令相同,但同时显示每个连接的 URL。
git remote add <name> <url>
创建一个新的远程仓库连接。在添加之后,你可以将 <name> 作为 <url> 便捷的别名在其他 Git 命令中使用。
git remote rm <name>
移除名为的远程仓库的连接。
git remote rename <old-name> <new-name>
将远程连接从 <old-name> 重命名为 <new-name>。
当你用 git clone 克隆仓库时,它自动创建了一个名为 origin 的远程连接,指向被克隆的仓库。当开发者创建中央仓库的本地副本时非常有用,因为它提供了拉取上游更改和发布本地提交的快捷方式。这也是为什么大多数基于 Git 的项目将它们的中央仓库取名为 origin。
浙公网安备 33010602011771号