Git Best Practices
Global configuration
git config --global --list
git config --local --list
GIT two popular authentication methods: SSH Key and Credentials
Git SSH key
How to Authenticate Your Git to GitHub with SSH Keys
Git credential
Store username/password instead of ssh for multiple remotes
To enable git credentials
# local
git config credential.helper store
# global
git config --global credential.helper store
Each credential is stored in ~/.git-credentials
file on its own line as a URL like:
https://<USERNAME>:<PASSWORD>@github.com
Configure credentials,
# Global
git config --global credential.https://github.com.username <your_username>
# Or
git config --local user.name <your_username>
git config --local user.email <your_useremail>
# Then git pull or git push to let it cache your username/password after it prompt you to input password in the first time
Alternatively, we can directly edit our global Git config file ~/.gitconfig
,
[credential "https://github.com"]
username = <username>
Git - Config Username & Password - Store Credentials - ShellHacks
Git submodule
- Pull the repo and its all submodules in the first time.
git clone http://10.6.64.66:30000/mtr/mtr.git
cd mtr
git submodule update --init --recursive --progress
Or just one command to clone with all the submodules.
git clone --recursive http://10.6.64.66:30000/mtr/mtr.git
- Pull the repo and its all submodules later
git submodule update --recursive --progress
- Enter each sub repository to pull its own latest of
main
per repository, when the parent repo does point to the latest branch of its submodules!
Sometimes, it is very annoying to keep the parent repository up to date on the latest reference of its every sub repository! This approach give you the flexibility while being like a shortcut.
git submodule foreach git checkout main
git submodule foreach git pull
git submodule foreach git pull origin main
git submodule update --recursive --remote
Discard local commits
Assume your local repo has 10 commits ahead of the origin/main
, and you want to move back to the origin/main
.
git reset --hard origin/main
Create a subdirectory inside Git and use it as Git submodule
First, create a subdirectory ./include/private
and initialize it as a new Git repository inside Git repo, then push it to remote.
Once done, we'll have subdirectory ./include/private
which has been gitted.
Check current parent Git submodule, and our ./include/private
sit outside.
$ git submodule
-96788d8ac53a815778a8cfd19addb3590a8be5ea code-snippets/assembly
-990e3db80c61c64ba9097adb7e729a6568c272ec code-snippets/c
-dd2097c0884363948877dea2b3f68efb90e6d204 code-snippets/cpp
-a4c753b89c423cd02718bece5a8a6302bd2385c7 code-snippets/docker-compose
-e23cfb82c6fefae4fdc6a144228bebb580bf7c13 code-snippets/python
- Option 1, Using
git submodule add
command in parent directory(note: works even./include/private
folder exists):
git submodule add https://github.com/liviaerxin/private.git include/private
Finally, commit,
git commit -m "add submodule private"
- Option 2, Editing
.gitmodules
file in parent directory by adding:
[submodule "include/private"]
path = include/private
url = https://github.com/liviaerxin/private.git
Indexing the submodule,
git add include/private
Verifying that the submodule has been included,
$ git submodule
-96788d8ac53a815778a8cfd19addb3590a8be5ea code-snippets/assembly
-990e3db80c61c64ba9097adb7e729a6568c272ec code-snippets/c
-dd2097c0884363948877dea2b3f68efb90e6d204 code-snippets/cpp
-a4c753b89c423cd02718bece5a8a6302bd2385c7 code-snippets/docker-compose
-e23cfb82c6fefae4fdc6a144228bebb580bf7c13 code-snippets/python
-e9e1b5f114e5da1896dae6c08ca01bc83b844b4d include/private
For managing the submodule,
- Sync local private file:
.git/config
by runninggit submodule init
, which will let the submodule update when runninggit submodule update
later.
Finally, commit,
git commit -m "add submodule private"
In conclusion, git submodule add
equals:
- Run
git clone {submodule} include/{submodule}
. - Add submodule configuration such as
path = include/{submodule}
andurl=https://github.com/xxx/{submodule}.git
into.gitmodules
file. - Add the sub folder
include/{submodule}
:git add include/{submodule}
. - Sync
.git/config
file:git submodule init
.
Sometimes the warning to the changes of submodules will be annoying, especially if you update submodules frequently.
To ignore all changes to the submodules:
[submodule "include/private"]
path = include/private
url = https://github.com/liviaerxin/private.git
ignore = all
Once you have ignored changes in a submodule, you will no longer see them in the output of the git status command. You will also not be able to commit or push the changes to the submodule.
To view the changes in the submodule, you can use the git submodule summary command. This command will show you a summary of the changes in the submodule, even if they are ignored.
Once you have unignored changes in a submodule, you will be able to see them in the output of the git status command and you will be able to commit and push the changes to the submodule.
Here are some additional things to keep in mind when ignoring changes in a submodule:
- Ignoring changes in a submodule does not prevent you from updating the submodule. You can still use the git submodule update command to update the submodule to the latest version.
- Ignoring changes in a submodule does not prevent you from cloning the submodule. You can still use the git submodule clone command to clone the submodule into another repository.
- Ignoring changes in a submodule does not prevent you from deleting the submodule. You can still use the git submodule deinit command to delete the submodule from your repository.
Overall, ignoring changes in a submodule can be a useful way to keep your repository clean and organized. However, it is important to understand the implications of ignoring changes before you do so.
Carve out a subdirectory from Git and use it as Git submodule
Git subtree
When you should consider using a Git subtree instead of Git submodule?
If you need to manage multiple projects within a single repository as:
- I have a main project for writing blogs
- However, I also manage several projects to maintain my daily coding snippets such as
C
,Python
, ...etc.
- I want to store these sub-projects in the specified sub-folders of my main repository.
- I will update these sub-projects frequently.
- I will pull and push changes of these sub-projects in local sub working directories.
- I don't want to the main repository to warn me the new commits from sub-projects every time I update the sub-projects.
Drawbacks:
- To update and commit changes on these sub-projects you need to remember some "information", because the metadata of these sub-projects will be not stored in a file like
.gitmodules
in main repo.
Git Subtree: Alternative to Git Submodule | Atlassian Git Tutorial