git submodules - ghdrako/doc_snipets GitHub Wiki

Problems with submodules

  • if added via ssh protocol, users without ssh configured for their git account can’t clone them - so always use https-protocol to add a submodule • submodules easily get in a “detached head” state • at least git on windows has authentication problems with submodules (use of pageant helps)

  • https://git-scm.com/book/en/v2/Git-Tools-Submodules

A Git submodule is essentially a reference to another Git repository. It allows you to include a specific commit or branch of an external repository as a subdirectory within your own Git repository. This subdirectory is managed as a separate Git repository in its own right. Submodules are very static and only track specific commits. Submodules do not track git refs or branches and are not automatically updated when the host repository is updated.

There's a core command to set index entries directly.

git update-index --cacheinfo 160000,<new_SHA_here>,path


* 160000 is the mode for a submodule entry in the Git index.
* <new_SHA_here> should be replaced with the desired commit SHA-1 hash.
* path/to/submodule is the path to the submodule within your main repository.
sets the entry for path to that commit, exactly as if you'd git added a submodule's checkout of that commit.
Note to others that you need to use the **full SHA**, rather than the short SHA that git commands often accept.

Make sure to commit the changes in your main repository after running the git update-index command to record the updated submodule reference.

git update-index --cacheinfo 160000,<Git hash of the submodule's tree>,

So for example if your project directory structure looks like this:

. ├── .git └── submodule

Then to update the submodule to point to commit 2764a900748fbed7453f5839cb983503cee346d2 you would run:

git update-index --cacheinfo 160000,2764a900748fbed7453f5839cb983503cee346d1,submodule

And finally follow it up with git commit as usual.


Inna opcja jest:
1. Edit the .gitmodules File:

Open the .gitmodules file in your main repository, and specify the commit or reference of the submodule directly. For example:

[submodule "path/to/submodule"] path = path/to/submodule url = https://github.com/example/repo.git commit = <desired_commit_or_reference>

Replace <desired_commit_or_reference> with the actual commit hash or reference of the submodule that you want to use.
2. Update the Submodule Reference:
After editing the .gitmodules file, you can update the submodule reference in your main repository using the git submodule sync command:

git submodule sync

This command updates the submodule configuration in your main repository based on the changes made in the .gitmodules file. It will modify the reference without actually fetching the submodule's content to your local machine.

3. Commit the Change in the Main Repository:

Commit the change in your main repository to record the updated submodule reference:
git add .gitmodules path/to/submodule  # Stages the changes to the submodule reference
git commit -m "Update submodule reference to the desired commit"
git push
This way, you update the reference of the submodule in your main repository without pulling or fetching the submodule's content to your local machine. Users who clone or update your main repository will receive the submodule reference associated with the specified commit, but they won't fetch the actual submodule content until they run git submodule update.

Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate.

1. Add a Git submodule to your main project. *git submodule add*:  

git submodule add <remote_url> <destination_folder> # desctination folder is optional


$ git submodule add https://github.com/chaconinc/DbConnector $ git status

By default, submodules will add the subproject into a directory named the same as the repository, in this case “DbConnector”. You can add a different path at the end of the command if you want it to go elsewhere.

When adding a new Git submodule into your project, multiple actions will be performed for you :
* A folder is created in your Git repository named after the submodule that you chose to add
* [A hidden file](https://devconnected.com/how-to-show-hidden-files-on-linux/) named “.gitmodules” is created in your Git repository : this file contains the references to the remote repositories that you cloned as submodules;
* Your Git configuration (located at .git/config) was also modified in order to include the submodule you just added;
* The submodule you just added are marked as changes to be committed in your repository.


$ cat .gitmodules

[submodule "DbConnector"] path = DbConnector url = https://github.com/chaconinc/DbConnector


$git config submodule.DbConnector.url PRIVATE_URL


Example1

git submodule add https://github.com/example/repo.git path/to/submodule



2. When adding a Git submodule, your submodule will be staged. As a consequence, you will need to commit your submodule by using the “git commit” command.

$ git diff --cached DbConnector $ git diff --cached DbConnector --submodule $ git commit -am 'Add DbConnector module'


3.

git push origin master


***
### Cloning a Project with Submodules
Whenever [you are cloning a Git repository](https://devconnected.com/how-to-clone-a-git-repository/) having submodules, you need to execute an extra command in order for the submodules to be pulled.

$ git clone https://github.com/chaconinc/MainProject # powstanie DbConnector ale pusty #$ git submodule init # initialize submodule configuration $ git submodule update --init --recursive

W jednym kroku - clone a repository including its submodules

$ git clone --recursive https://github.com/chaconinc/MainProject $ git clone --recurse-submodules https://github.com/chaconinc/MainProject


pulling a Git submodule in our colleague Git repository detached the HEAD at a given commit.

The submodule is always set to have its HEAD detached at a given commit by default : as the main repository is not tracking the changes of the submodule, it is only seen as a specific commit from the submodule repository.

In submodule dir:

git fetch


Automatyczne pobieranie zmian dla wszyskich podmodułów

git submodule update --remote DbConnector # domysnie aktualizujemy na podstawie gałęzi master

git config -f .gitsubmodules submodule.DbConnector.branch stable git submodule update --remote


### Update a Git Submodule

$ git submodule update --remote --merge


Using the “–remote” command, you will be able to update your existing Git submodules without having to run “git pull” commands in each submodule of your project.

When using this command, your detached HEAD will be updated to the newest commit in the submodule repository.


### Fetch new submodule commits

$ cd repository/submodule

$ git fetch

git log --oneline origin/master -3 git checkout -q 93360a2


Your HEAD is now aligned with the newest commits from the submodule repository.

You can now go back to your main repository and commit your changes for other developers to fetch those new commits.

$ cd repository $ git add . $ git commit -m "Added new commits from the submodule repository" $ git push


### Remove Git submodules

$ git submodule deinit

$ git rm

When executing the “git submodule deinit” command, you will delete the local submodule configuration stored in your repository.

As a consequence, the line referencing the submodule will be deleted from your .git/config file.

The “git rm” command is used in order to delete submodules files from the working directory and remaining .git folders.

To remove a submodule called mymodule you need to:
git submodule deinit -f — mymodule
rm -rf .git/modules/mymodule
git rm -f mymodule

git push recursive-submodules=check

or

cd submodule git push

automatycznie

git push recursive-submodules=on-demand




###  Executing a command on every submodule

git submodule foreach 'git reset --hard'

including nested submodules

git submodule foreach --recursive 'git reset --hard'

git submodule foreach --recursive 'git stash'

git submodule foreach --recursive 'git checkout -B funkcjaA' # automatyczne utworzenie galezi w podmodulach i przejscie do nich

git submodule foreach 'git diff'

⚠️ **GitHub.com Fallback** ⚠️