Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git submodules without detached head?

Maybe I'm using git-submodules not on purpose, but if there's any other git feature which satisfies my case, would be nice to find it.

After cloning repository, I want submodule to be in master branch, I'll never store any additional files inside of chef-starter submodule.

git clone [email protected]:holms/vagrant-starter.git
git submodule update --init
cd chef-starter
git branch
   * (detached from 0b6a803)
   master

I do understand that it's a nice feature to track that submodule dir tree separately, but it's not my case. After main repository clone, I just want that submodule would be cloned to the latest master stage without any additional fuss.

How can I achieve this?

like image 435
holms Avatar asked Dec 07 '22 03:12

holms


2 Answers

The submodule has a detached head because a submodule means "check out a specific commit from the submodule's repository". The master branch may have moved forward (it may point to a commit that descends from commit 0b6a803), so Git checks out the specific revision instead of checking out a branch.

git-submodule has the option to record a branch name. When you do this, you can use git submodule update --remote to update the submodule with that branch:

# Add the submodule with the "master" branch referenced
git submodule add -b master https://github.com/holms/chef-starter.git chef-starter

# When you want to update the submodule:
git submodule update --remote

# You'll still need to commit the submodule if you want future checkouts to use the new revision
git add chef-starter
git commit -m "Update chef-starter submodule"

You'll still get a detached head in the submodule when you start checking out different versions of the super project (vagarant-starter), but at least now it's easier to update the submodule to the latest version from the remote.

You may find it easier to use git-subtree instead of submodules:

# First, get rid of the submodule
git submodule deinit chef-starter # If you have Git 1.8.3 or later, otherwise edit .gitmodules
git rm chef-starter               # Remove the directory
git commit -m "Removed chef-starter submodule in preparation to add as a subtree"

# Now add the subtree
git subtree add -P chef-starter https://github.com/holms/chef-starter master --squash

This grafts the chef-starter repo into the chef-starter/ directory in your vagrant-starter repo. From that point forward, you don't have to do anything special if you choose to edit files in the subtree. For instance, you don't have to run git submodule update after cloning.

like image 94
Stephen Jennings Avatar answered Dec 11 '22 09:12

Stephen Jennings


To ensure my submodules stay synced and undetached, I have the following in a batch file. It relies on adopting the policy of syncing to the submodule's master branch - for me this isn't a problem, I just fork the submodule and ensure it has a master. I find it's much easier to keep track of things with this approach.

git pull
git submodule sync    # Ensure the submodule points to the right place
git submodule update  # Update the submodule  
git submodule foreach git checkout master  # Ensure subs are on master branch
git submodule foreach git pull origin master # Pull the latest master
like image 26
cmaughan Avatar answered Dec 11 '22 08:12

cmaughan