Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git Submodule Workflow Advice

So I started using Git a few days ago. ( Very late to the party - don't scold :) ). Really starting to get comfortable with the basic commands, ideas and workflows. However, submodules are really taking my brain for a ride. I am attempting to contribute code to FuelPHP's GitHub and I could use some guidance and tips.

I am running the following commands in the terminal:

//1: clone the repository from Fuel's github.
git clone git://github.com/fuel/fuel.git

//2: move into the main fuel directory
cd fuel

//3: initilize the submodules (populate .git/config with submodule data)
git submodule init

//4: download the submodules...
git submodule update

//5: move into the core directory (which is a submodule).
cd fuel/core

//6: change branch from (*no branch) to 1.1/develop
git checkout 1.1/develop

//7: open random file in text editor + make some small change (i.e. typo) + save file.
sudo gedit classes/autoloader.php

//8: add this file to the staging area.
git add classes/autoloader.php

//9: commit this file under 1.1develop branch.
git commit -m "im committing a submodule"

//10: push the new commit to MY (not fuel's) github repo (yes i've renamed the repo).
git push [email protected]:jordanarseno/fuel-core.git

//11: changes are reflected on github, looks good.

//12: back way out to fuel again. time to push the submodule commit separately.
cd ../../

//13: add the fuel/core submodule to the staging area.
git add fuel/core

//14: commit the submodule change.
git commit -m "submodule pushed. pushing super now."

//15: push the commit to MY (not fuel's) github repo.
git push [email protected]:jordanarseno/fuel.git

Specifically, my questions are:

  1. Is this the proper workflow for working with submodules? Is it what you would do?
  2. Why does git pull down the 1.1/develop branch in a submodule but set me on *no branch by default? Can I modify this behaviour?
  3. What part of the Fuel submodule tells git to pull 1.1/develop to begin with? There are other branches (1.1/master, 1.0/develop etc..).
  4. Why can't we call it a day at step 11? The submodule push worked fine. I push the super afterwards because the manual tells me it's a good idea. And indeed, heading over to GitHub and looking at MY super, a commit is made. This commit 845de87 however, appears to be just a reference to Fuel's super and not MY super. Shouldn't it link to MY repo and not theirs?
  5. Running cat .git/config in super shows:

Along with all the submodules...

[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = git://github.com/fuel/fuel.git`

Running cat .git config in the core submodule shows:

[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = git://github.com/fuel/core.git

Would it be wise to change these url's to MY own repo on GitHub? Fuel denies pushes anyway. If I perform a submodule update, will they be overwritten?

I've also asked this over on Fuel's Forums, but it's more of a general question and there are more Gitters here... THANKS!

like image 637
Jordan Arseno Avatar asked Feb 23 '12 10:02

Jordan Arseno


People also ask

Is using git submodules a good idea?

Git submodules may look powerful or cool upfront, but for all the reasons above it is a bad idea to share code using submodules, especially when the code changes frequently. It will be much worse when you have more and more developers working on the same repos.

When should I use git submodules?

In most cases, Git submodules are used when your project becomes more complex, and while your project depends on the main Git repository, you might want to keep their change history separate. Using the above as an example, the Room repository depends on the House repository, but they operate separately.

How do I manage git submodules?

Use the git submodule update command to set the submodules to the commit specified by the main repository. This means that if you pull in new changes into the submodules, you need to create a new commit in your main repository in order to track the updates of the nested submodules.

Can submodules have submodules?

Cloning a Project with Submodules If you pass --recurse-submodules to the git clone command, it will automatically initialize and update each submodule in the repository, including nested submodules if any of the submodules in the repository have submodules themselves.


1 Answers

  1. Yes, as explained in "true nature of submodules"

  2. a git submodule is a reference to a specific commit (SHA1), not a branch, so you are always in a detach mode a first (which is compatible with a read-only usage).
    In other words, git submodule update checks out a specific commit, rather than the tip of a branch.
    The .gitmodule file will contain the reference of your submodule repo. And the specific SHA1 will be recorded in the parent repo as a special commit (mode 160000). When you 'git submodule add' a new submodule, it records the SHA1 at which that other repo is currently checked out (whatever its branch).
    If you want to make changes, then you must checkout a branch within that submodule repo (an existing branch or a new one: in both cases, you will push any new change back to the remote repo of that submodule).
    An alternative would be git slave.

  3. See 2. The other branch(es) listed in the git branch are the local one existing in your submodule repo, including one local branch for each tracking branch if you did a git pull at one point.

  4. Because the parent still reference the initial SHA1 of the submodule.
    But since you have made modifications in it, that SHA1 needs to be updated.
    Keep in mind that the submodule is a git repo in itself... with absolutely no idea it is used as a submodule. Hence the necessity to record the new state of that repo in the parent repo (the only one keeping track of the state of its submodules).
    Your first git push is entirely an internal operation of the submodule repo (which isn't seen at all by the parent repo).
    For a parent repo, the submodule repo is a "black box", with only a remote address and a SHA1. Whatever is done within the submodule has no consequence on the parent, which will detect only the change of the SHA1 of the submodule tree.

  5. Using forks might help
    See "Changing remote repository for a git submodule" to update your submodule remote URL.

like image 170
VonC Avatar answered Oct 04 '22 22:10

VonC