git submodules - ghdrako/doc_snipets GitHub Wiki
action | command | comment |
---|---|---|
add submodule to repo | git submodule add https://github.com/<remote_path> ./<local_path> |
git will store the commit ID and URL of submodule |
download submodule | git submodule update --init |
cloning repository doesn't download its submodules |
update submodule | git submodule update |
git pull and git checkout don't update submodules. Use command every single time you switch branch or pull and it puts the submodule in detached HEAD state
|
automatic update submodule after pull/checkout | submodule.recurse true |
config option |
shwow which commits were added/removed in git diff/git status |
status.submoduleSummary true diff .submodule log
|
config option |
- 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)
Update the reference of the submodule in your main repository without pulling or fetching the submodule's content to your local machine
- https://stackoverflow.com/questions/68862399/is-it-possible-to-update-a-submodule-sha-without-pulling
- https://stackoverflow.com/questions/33514642/how-can-i-set-a-submodule-to-point-to-a-specific-commit-without-fetching-it
local repo that has a reference to a submodule - update the submodule's reference to a more recent SHA without pulling the submodule's contents from the remote
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>,<path to the submodule>
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.
- 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.
- 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.
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.
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.
- 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 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
- 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'
git push origin master
Whenever you are cloning 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
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
git submodule update --remote DbConnector # domysnie aktualizujemy na podstawie gałęzi master
git config -f .gitsubmodules submodule.DbConnector.branch stable
git submodule update --remote
$ 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.
$ 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
$ git submodule deinit <submodule>
$ git rm <submodule>
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
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'