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。

 

posted @ 2017-10-15 22:13  timwind  阅读(1048)  评论(0)    收藏  举报