Tuesday, 3 July 2018

Managing Git submodules

A git submodule is helpful for a project that requires dependency on another project. For example, this can be a library that was developed by you or another team. It can be hard to manage when the library is updated and you made some custom code inside your project.
Git handles this by using submodules. It allows you to manage a Git repository as a subfolder of another Git repository, which in turn lets you clone a repository isolated from the commits of the current repository.
The following points will be illustrated in below:
  • Adding a submodule.
  • Cloning a project with submodules.
  • Removing a submodule.
  • Using a subtree instead of a submodule.
  • Adding a subproject with a subtree.
  • Contributing on a subtree.

Adding a submodule

Let's imagine you want to add the "myutil" library that helps you development of your feature. The first thing to do is to clone the library's Git repository inside your subfolder:
$ git submodule add https://mygitserver/scm/myutil.git myutil
You now have the myutil project inside the myutil folder.
You can do everything you want inside it, such as add modifications, change the remote repository, push your changes in the remote repository, and so on.
While you add the Git submodule, Git adds two files, myutil and .gitmodules.
Let's see this with the git status command:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>…" to unstage)
# new file: .gitmodules
# new file: myutil
Git sees the myutil folder as a submodule, so it won't track the changes if you're not in this folder. An important fact is that Git saves this addition as a nonregular commit of this repository, so if someone clones your website, Git can recreate the same environment.

Cloning a project with submodules

If you clone a project using submodules Git will add all files other than the submodule files:
$ git clone https://mygitserver/scm/myproject.git
$ ls
myfile.txt myutil
$ cd myutil
$ ls
$
The myutil folder is created, but it is empty. You will have to execute these two commands to initialize the import submodule:
$ git submodule init
$ git submodule update
Your repository is now up to date. Using submodules can be interesting if you want to separate and isolate some parts of your code.
If you execute a git pull command on your project, you will not have the last version of the submodule. To do this, you have to execute git submodule update every time you want to update your submodule.

Removing a submodule

To remove a submodule from your project, you have to execute these steps:
  1. Delete the lines of the submodule from the .gitmodules file.
  2. Delete the submodule part from .git/config.
  3. Delete the submodule from Git by executing this command:
    $ git rm -cached submodule_path
  4. Commit and delete the untracked files.

Using a subtree instead of a submodule

The use of git module is not a best practice because you have to use git submodule update every time, and you will probably forget to do this. The second problem is that Git doesn't really handle merging into a submodule. It detects SHA conflicts, but this is all. It's left to you to find out what should be done.
Thankfully, there is the subtree, which is better in a few ways:
  • Easy to manage for light workflow.
  • While you clone a superproject, the subproject's code is available too.
  • Subtree doesn't use files such as .gitmodules. 
  • The most important point is that contents can be modified inside your project without having a copy of the dependency elsewhere.
Git subtree is available since version 1.7.11 of Git delivered in May 2012.

Adding a subproject with a subtree

Firstly, we need to tell Git that we want to include a project as a subtree. We use the git remote command to specify where the remote repository of this subtree is:
$ git remote add –f myutil_remote https://mygitserver/scm/myutil.git
Now, you can add the subtree inside your project using the remote repository:
$ git subtree add --prefix myutil myutil_remote master --squash
This will create the subproject. If you want to update it later, you will have to use the fetch and subtree pull commands:
$ git fetch myutil_remote master
$ git subtree pull myutil myutil_remote master --squash 

Contributing on a subtree

Obviously, you can commit your fixes to the subproject in the local directory, but when you push back upstream, you will have to use another remote repository:
$ git remote add info-myutil https://mygitserver/scm/myutil.git
$ git subtree push --prefix=myutil info-myutil master
Git push using: info-myutil master
Counting objects: 1, done.
Delta compression using up to 1 thread.
Compressing objects: 100% (1/1), done.
Writing objects: 100% (1/1), 170 bytes, done.
Total 1 (delta 1), reused 0 (delta 0)
To https://mygitserver/scm/myutil.git
.................................................... -} master
Git subtree can be an easy way if you have to frequently update your subproject and want to contribute to it with less effort.

No comments:

Post a Comment

Welcome

Hello everybody, Welcome in my blog called "Information technology archive". Obviously the topics will be related to Informatio...