Using Git Submodules
NOTE:
Following content is directly reprinted from http://patrickward.com/2013/01/09/using-git-submodules/, please go to the original website for more details.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Using Git Submodules
Author: Patrick Ward
09 Jan 2013
I've had mixed feelings about Git submodules for a long time now. But, I haven't found an alternative that I liked very much.
So, I decided to give submodules another chance the other day and write down some notes on how I've been working with them. I'm using a non-existentexample project here to illustrate the basic process.
Most of these notes are taken from the Git Submodule Tutorial, and just reordered and reiterated for my own brain here.
Initializing a Submodule
Add the submodule from the root of the host repository.
cd hostproject
git submodule add git://github.com/bitanical/example.git ./example
( comment: git submodule tracking branch
git submodule add -b branchNamegit://github.com/bitanical/example.git example/
)
- clones the submodule repository into the current directory
- by default checks out the master branch of the submodule repository
- adds the submodule's clone path to the ".gitmodules" file
- adds the ".gitmodules" file to the index, ready to be committed
- adds the submodules' current commit ID to the index, ready to be committed
At this point, the submodule has been added as a regular checkout within the host repository. As soon as you commit the changes to the host repository and push those changes to the origin repository, the submodule becomes available to other clones of that project.
git commit -m"Add submodule example"
git push
git submodule init
It's also important to realize that a submodule reference within the host repository is not a reference to a specific branch of that submodule's project, it points directly to a specific commit (or SHA1 reference), it is not a symbolic reference such as a branch or tag. In technical terms, it's a detached HEADpointing directly to the latest commit as of the submodule add. This will be important to understand when updating a submodule and pushing any changes made to it back up the chain.
Cloning a Project With a Submodule
Now that the project has the submodule reference, other users can clone that project into their distributed copies of the host repository.
git clone git://gihub.com/bitanical/hostproject.git
cd hostproject
ls -la
.
..
.git
.gitsubmodules
example
readme.md
When you check out the host project, the submodule directory is created as well, but you will immediately notice that the submodule directory is empty. Even though the submodule reference is known, cloned projects must still initialize and clone the submodule repository.
First initialize the submodule, to add the submodule URLs to .git/config.
git submodule init
Next, update the submodule, essentially cloning it's contents into the submodule directory.
git submodule update
One major difference between "submodule update" and "submodule add" is that "update" checks out a specific commit, rather than the tip of a branch. It's like checking out a tag: the head is detached, so you're not working on a branch.
A shortcut to the preceding steps is to clone the project with the --recursive option, essentially initializing and updating any submodules after the host repository has been cloned.
git clone git://gihub.com/bitanical/hostproject.git --recursive
At this point, the project has full use of it's own files along with the cloned submodule files.
Making Changes Within a Submodule and Checking Them In
Making a change within a submodule can be a bit tricky, but if you're careful with the order of the steps you take, it can be relatively painless.
The first, and most important, step when making a change within a submodule is to check out a branch within the submodule first. For example, git checkouot master. Remember, normal submodule references are in a detached HEAD state and not associated with an branches, so checking out a branch first gives you a true reference point to work with.
git branch
*(no branch)
master
So, checkout a branch (e.g. master):
git checkout master
Make your changes within this checked out state. Then, commit those changes to the submodule and push them to the submodule's origin repository before doing anything further with your host repository.
git commit -a -m"Updated submodule from within hostproject"
git push
Now, you can update the host repository, commit the changes and push those updates to the host repositories origin. Remember, in this case, we're using example as the name of the submodule directory.
cd ..
git add example# Make sure you don't add a forward slash
# after the name of the submodule folder
git commit -m"Updated submodule example"
git show# to show the changes
git push
Updating Cloned Projects
If you've made a change to the submodule and have updated the host project's submodule reference, other cloned versions of the host repository will need to update their own submodule references. Simply pull the changes from the origin and run the submodule update command to retrieve the latest versions.
cd hostproject
git pull
git submodule update
Working With Git Submodules Recursively
There are times when you need to apply a particular command to each submodule individually. For that, git-submodule provides the foreachcommand, which can be useful for updating and initializing multiple submodules at once.
git submodule foreach submodule update --init
Pulling Submodule Changes
Sometimes you need to pull in the changes to a submodule and make sure the host repository points to the updated code.
cd hostproject
cdexample# cd into the submodule directory
git checkout master# make sure you in a valid branch
git pull
cd../# get back into the host repository
git add example# add the changes (essentially changes the SHA1 that the host repo points to)
git commit -m"Updating submodule example"
git push
Change the Remote URL for a Submodule
I've found that I need to sometimes change a submodule from within a host repository so that I can push updates back to the submodule project. For example, public submodules on GitHub use thegit://github.com/bitanical/example.git url format, but GitHub doesn't support pushing changes back to the origin via the git:// url regardless of your commit privileges. In these cases, I find I have to delete the origin and add it back with a URL I can push to:
cd example
git remote rm origin
git remote add origin git@github.com:bitanical/example.git
git remote -v
Next, add the branch information back to the config:
git config branch.master.remote origin
git config branch.master.merge refs/heads/master
Initialize a Submodule With a Different URL
You can bypass the steps in the preceding tip, by intializing the submodule with a different URL. This lets you start with a submodule that you can, for example, push changes back to.
So, rather than doing the usual git submodule init && git submodule update flow, you substitute the init step by explicitly stating the remote url in a config command.
The following steps illustrate the steps used in cloning a host repository with a submodule, and then initializing the remote url with one that differs from the one set in host repository's .gitmodules file.
git clone https://github.com/bitanical/hostproject.git
cd hostproject
git config submodule.example.url git@github.com:patrickward/example.git
git submodule update
cd example
git remote show origin
Removing a Submodule
As of this writing, there is no built-in method for removing a submodule within Git. So, it takes a few steps to complete, but they are relatively painless. The following steps illustrate the process (in the context of our example repo).
Delete the relevant section from the .gitmodules file
# Remove the submodule section pertaining to example.git
[submodule "example"]
path = example
url = git://github.com/bitanical/example.git
Delete the relevant section from the .git/config file
# Remove the submodule seciton pertaining to example.git
[submodule "example"]
url = git://github.com/bitanical/example.git
Remove any cached directory information (do not add a trailing slash in the directory name)
git rm --cached example
Commit the host repository:
git commit -m "Removing submodule example"
Now, delete any untracked submodule files
rm -Rf example/
References
Here are some useful references regarding git submodules that I used to understand how they work:
- Git Submodule Tutorial
- Git Submodule Man Page
- Git Pro - Submodules Chapter
- Working with git submodules recursively
- Git Submodules Explained
Using Git Submodules的更多相关文章
- 初探 Git Submodules
之前一直想将一个 Git 仓库放到另一个 Git 仓库,有 Maven 多模块项目(Maven Multimodule Project)和 Gradle 多项目构建(Gradle Multiproje ...
- Git Submodules are not SVN Externals
一直在寻找Git跟TFS里面类似SVN Externals的替代方案, 今天终于找到了GIT里面的替代方案,在此做个备注 http://alexking.org/blog/2012/03/05/git ...
- git submodule 使用
这个是备忘录,原网页: https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407 http://cncc.bingj.c ...
- git subtree 使用
这个是备忘录.原网页(https://medium.com/@porteneuve/mastering-git-subtrees-943d29a798ec , http://cncc.bingj.co ...
- Git - Tutorial官方【转】
转自:http://www.vogella.com/tutorials/Git/article.html#git_rename_branch Lars Vogel Version 5.8 Copyri ...
- Git submodule实战
http://blog.jqian.net/post/git-submodule.html 使用git管理的项目开发中,如果碰到公共库和基础工具,可以用submodule来管理. 常用操作 例如, 公 ...
- git subproject commit xxxxxxxxxxxxxxxxxxxxx -dirty
-Subproject commit 8c75e65b647238febd0257658b150f717a136359 +Subproject commit 8c75e65b647238febd025 ...
- git submodule 使用过程中遇到的问题
git submodule 使用过程中遇到的问题 资源文件 原.gitmodules文件的内容如下: [submodule "Submodules/FFmpegWrapper"] ...
- Merge git repo into branch of another repo
git 两个repo merge You can't merge a repository into a branch. You can merge a branch from another rep ...
随机推荐
- ztree使用系列四(ztree实现同级拖拽排序并将排序结果保存数据库)
ztree这个系列的最后一篇,也是ztree功能强大的体现之中的一个--排序功能. ztree能够实现全部节点之间任意的拖拽排序功能.我这里依据须要实现了仅仅同意同级之间任意拖拽排序,事实上原理都一样 ...
- Android消息机制——时钟显示和异步处理工具类(AsyncTask)
1. 时钟显示 定义布局文件——activity_my_analog_clock_thread_demo.xml <?xml version="1.0" encoding=& ...
- C++对象内存模型1(堆栈模型)
对象内存模型 一. 栈(Stack) VS. 堆(heap) 栈 由系统自动管理,以执行函数为单位 空间大小编译时确定(参数+局部变量) 函数执行时,系统自动分配一个stack 函数执行结束时,系统立 ...
- Java最重要的21个技术点和知识点之JAVA基础
(一)Java最重要的21个技术点和知识点之JAVA基础 写这篇文章的目的是想总结一下自己这么多年JAVA培训的一些心得体会,主要是和一些java基础知识点相关的,所以也希望能分享给刚刚入门的Ja ...
- weak 弱引用的实现方式
来源:冬瓜争做全栈瓜 链接:https://desgard.com/weak/ 对于 runtime 的分析还有很长的路,最近在写 block 系列的同时,也回顾一下之前疏漏的细节知识.这篇文章是关于 ...
- 1.4.9 DocValues
DocValues 在solr4.2以后,引入了一个令人兴奋的功能,这个功能在lucene存在已经一段时间了,但是还没有在solr中使用. 在某些方面,DocValue 是一种非常有效的索引方式. 为 ...
- ListView的addAll方法
add是将传入的参数作为当前List中的一个Item存储,即使你传入一个List也只会另当前的List增加1个元素addAll是传入一个List,将此List中的所有元素加入到当前List中,也就是当 ...
- 单表多次join的sql
select o1.emp_name as 员工姓名1 , o2.emp_name as 员工姓名2 from tableTest join employee o1 on tabletest.[Emp ...
- MySQL(20):事务简介 和 事务的四个特性
1. 事务概念引入: 现实生活中,我们往往经常会进行转账操作,转账操作可以分为两部分来完成,转入和转出.只有这两部分都完成了才可以认为是转账成功.在数据库中,这个过程是使用两条语句来完成的,如果其中任 ...
- eclipse添加hadoop开发插件
在开发hadoop的时候去查找了一下eclipse marketplace是没有找到hadoop的插件,上网又找了一下发现原来hadoop中其实是带有这样的插件的, 其实很简单只要将这个插件复制到ec ...