Skip to content

Commit c77aab8

Browse files
committed
docs: Add journal entry for Git submodules and link to YouTube video
- Created a new journal entry for 2025-11-02 documenting Git submodules - Added a link to the YouTube video "Why everyone hates git submodules" for additional insights - Updated the git submodule page with a reference to the video for useful tips
1 parent 99cb950 commit c77aab8

File tree

3 files changed

+147
-0
lines changed

3 files changed

+147
-0
lines changed

journals/2025_11_02.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- [[git/submodule]]
2+
- [[YouTube/@philomatics/25/05/Why everyone hates git submodules]]
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
readwise-link:: [Why everyone hates git submodules | Readwise](https://read.readwise.io/new/read/01k91vdy4mm9wz23x89acfymgh)
2+
3+
- [Why everyone hates git submodules - YouTube](https://www.youtube.com/watch?v=JESI498HSMA)
4+
- ## [[My Notes]]
5+
- In old versions of git, you had to run `git submodule update --recursive` after changing a branch, running git pull, merging and rebase, etc. In recent versions of git, you can run these two commands once, which will make it so that when you switch branches or run a git pull or git push, all submodules will be updated automatically as necessary.
6+
- ~~~
7+
git config --global submodule.recurse true
8+
git config --global push.recurseSubmodules on-demand
9+
~~~
10+
- Some recommended aliases for submodules
11+
- ~~~
12+
git config --global alias.smu "submodule update --init --recursive"
13+
git config --global alias.sms "submodule status"
14+
git config --global alias.sma "submodule add"
15+
~~~
16+
- One alternative to using git submodules is using a package manager like [[npm]] or [[pip]] and keeping the two repos separate, but including the child repo in the parent repo's package.json or whatever is the equivalent. Most package managers allow you to include a custom URL to a repo. So even if your library is private, you can still use this method. This might actually be less confusing for some teams.
17+
- ~~~
18+
{
19+
"dependencies": {
20+
"library1": "git+ssh://[email protected]/User/library1.git#v1.2.3"
21+
}
22+
}
23+
~~~
24+
- ## [[Video]]
25+
- {{video https://www.youtube.com/watch?v=JESI498HSMA}}
26+
- ### {{youtube-timestamp 0}} Introduction to Git Submodules
27+
- #### What Are Submodules?
28+
- Git submodules are a way to put one Git repository inside another, allowing you to have nested Git repos
29+
- Common use case: when your team has written a library that is shared among multiple different applications
30+
- Each submodule is **pinned to a specific commit**
31+
- #### Cloning Repositories with Submodules
32+
- When you clone a repo that includes submodules, the code in the submodule will **not be downloaded automatically**
33+
- To download everything, add the `--recursive` flag when cloning:
34+
- `git clone --recursive <repo-url>`
35+
- This ensures all submodules, including entire git history, are downloaded
36+
- Alternatively, if you've already cloned the repo, run from the parent repo's directory:
37+
- `git submodule update --init --recursive`
38+
- #### How Submodules Work
39+
- When you run `git submodule update --init --recursive`, Git:
40+
- Looks at the `.gitmodules` file (created automatically when submodule was first added)
41+
- Goes through added submodules in this file
42+
- Clones each submodule from the specified URL
43+
- Checks out the specific commit the submodule is pinned to
44+
- To see which commit hash the submodule is currently pinned to:
45+
- `git ls-tree HEAD <submodule-path>`
46+
- The commit hash is stored in the hidden `.git` folder of the parent repo (not in `.gitmodules`)
47+
- #### Recursive Flag
48+
- Sometimes a submodule can have another submodule nested in it
49+
- The `--recursive` flag ensures nested submodules are all downloaded as well
50+
- #### Submodule Behavior
51+
- Once downloaded, submodule behaves like a regular git repository
52+
- It doesn't have its own hidden `.git` folder like the parent repo
53+
- Instead has a `.git` file that points at the parent repo
54+
- Git commands from the submodule directory only affect that specific repo, not the parent repo
55+
- ### {{youtube-timestamp 136}} Making Changes to Submodules
56+
- #### The Detached Head Problem
57+
- Making changes to submodules is one of the **most confusing aspects** when working with submodules
58+
- Parent repo always pins the submodule to a specific commit hash
59+
- When Git downloads a submodule, it's put into a **detached HEAD state**
60+
- Detached HEAD means you've checked out a specific commit without any branch checked out
61+
- #### Switching to a Branch
62+
- To make changes properly, switch to the main branch (or appropriate branch):
63+
- `cd <submodule-directory>`
64+
- `git checkout main`
65+
- This switch doesn't change files since the commit is already the latest on main
66+
- The purpose is so when you commit changes, they get added to a new commit on the branch
67+
- #### Updating the Parent Repo
68+
- After committing changes in submodule, the parent repo doesn't know about the new commit yet
69+
- Running `git status` in the parent repo shows the submodule has changed
70+
- Another way this happens: running `git pull` in the submodule directory to get latest changes
71+
- To update the pinned commit in the parent repo:
72+
- Run `git add <submodule-path>` in the parent directory (like any other change)
73+
- Commit this change to the parent repo
74+
- You're telling the parent repo: change submodule from old commit hash to new commit hash
75+
- After pushing parent repo, the pinned commit changes on GitHub as well
76+
- ### {{youtube-timestamp 244}} Branching and Auto-Update Configuration
77+
- #### Switching Branches with Submodules
78+
- When switching branches in the parent repo, by default Git will **not automatically update the submodule**
79+
- Example: main branch has submodule pinned to commit A, older branch has it pinned to commit B
80+
- After switching branches, submodule should have old commit checked out, but Git won't do this automatically
81+
- Running `git status` in parent repo shows Git thinks there are newer commits in submodule
82+
- #### Manual Update Required (Old Git Versions)
83+
- To fix this, run: `git submodule update`
84+
- This moves the submodule state to the pinned commit
85+
- Also necessary when:
86+
- Switching to a branch where submodule didn't exist yet
87+
- Running `git pull` in the parent repo
88+
- In older versions of Git, you had to run `git submodule update` after all these operations, which was extremely annoying
89+
- #### Auto-Update Configuration (Newer Git Versions)
90+
- In newer versions of Git, you can configure automatic updates
91+
- Run these two commands once to enable in your global git config:
92+
- `git config --global submodule.recurse true`
93+
- `git config --global push.recurseSubmodules on-demand`
94+
- This makes submodules update automatically when you:
95+
- Switch branches
96+
- Run `git pull`
97+
- Run `git push`
98+
- **Highly recommended**: Update Git to latest version before working with submodules
99+
- #### Useful Aliases
100+
- Setting up aliases for common operations makes things easier:
101+
- `git config --global alias.smu "submodule update --init --recursive"`
102+
- `git config --global alias.sms "submodule status"`
103+
- `git config --global alias.sma "submodule add"`
104+
- ### {{youtube-timestamp 336}} Adding and Removing Submodules
105+
- #### Adding a Submodule
106+
- Run: `git submodule add <repo-url> <path>`
107+
- This will:
108+
- Download the submodule repo to the specified directory
109+
- Create the `.gitmodules` file if necessary
110+
- Add the new submodule to it
111+
- By default, submodule will be on the latest commit of the default branch (usually main)
112+
- To pin it to a different commit:
113+
- Switch to that commit or branch in the submodule directory
114+
- Then commit the change to the parent repo
115+
- #### Removing a Submodule
116+
- Run: `git rm <submodule-path>` and commit your changes
117+
- In older versions of Git, this required a few more steps, but latest version handles it automatically
118+
- ### {{youtube-timestamp 383}} Alternatives and Conclusion
119+
- #### Evaluation of Submodules
120+
- Under the hood, submodules are **really elegant and powerful**
121+
- Unfortunately, the user experience is **really confusing and awful**
122+
- Recent versions of Git have made working with them easier (thanks to auto-update settings)
123+
- #### Alternative 1: Package Managers
124+
- Use a package manager like [[npm]] or [[pip]] instead
125+
- Keep the two repos completely separate
126+
- Include the child repo in the parent repo's `package.json` (or equivalent)
127+
- Most package managers allow custom URLs to repos, even private ones
128+
- Example format:
129+
- ~~~
130+
{
131+
"dependencies": {
132+
"library1": "git+ssh://[email protected]/User/library1.git#v1.2.3"
133+
}
134+
}
135+
~~~
136+
- **Recommendation**: Use this method over submodules if you're not already using them
137+
- Benefits:
138+
- Saves team from potential headaches
139+
- Uses tools team is already comfortable with
140+
- Limitation: Not always possible depending on package manager setup and programming language
141+
- #### Alternative 2: Monorepo Approach
142+
- Put all code in a single repo in separate modules
143+
- Comes with its own set of trade-offs

pages/git___submodule.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
alias:: [[git submodules]]
2+
3+
- see [[YouTube/@philomatics/25/05/Why everyone hates git submodules]] for some useful tips

0 commit comments

Comments
 (0)