Git Top Codes

List of Top & Popular Git Codes for your project

Git Submodule Remove

A Git submodule is a Git repository inside another Git repository. Sometimes you need to remove one, for example when it is not needed anymore, or when the update is not working and you want to clean it and add it again.

Removing a submodule needs a few steps, because its data is in three places: the working folder, the .gitmodules file and the hidden folder .git/modules. First we make a project with a submodule to practice:

Terminal output

$ git submodule status
c61d9dcb43b1c0515422e270481321b0a8028ca4 libs/lib (heads/main)
$ cat .gitmodules
[submodule "libs/lib"]
path = libs/lib
url = ../lib

Steps to remove the submodule

Terminal output

$ git submodule deinit -f libs/lib
Cleared directory 'libs/lib'
Submodule 'libs/lib' (../lib) unregistered for path 'libs/lib'
$ git rm -f libs/lib
rm 'libs/lib'
$ rm -rf .git/modules/libs/lib
$ git commit -m "Remove libs/lib submodule"
[main a2ea29e] Remove libs/lib submodule
2 files changed, 4 deletions(-)
delete mode 160000 libs/lib
$ git status -s

How it works

  • git submodule deinit -f removes the submodule from the Git config of the project and clears its files.
  • git rm -f removes the folder and the entry from .gitmodules, and stages both changes.
  • rm -rf .git/modules/... deletes the hidden copy of the submodule repository. Without it, adding the same submodule again can fail.
  • The commit saves the removal. If you need to push, run git push after this.
Note: Be careful with rm -rf. Check the path two times before you press Enter. Read more in Git Submodule.

.gitignore Template for Web Projects

Copy this .gitignore to the root of your web project (PHP, JavaScript or any other) and remove the lines you do not need.

# Dependencies
node_modules/
vendor/

# Environment and secrets
.env
.env.*
!.env.example
*.pem

# Logs and temporary files
*.log
*.tmp
*.cache

# Build output
dist/
build/

# System files
.DS_Store
Thumbs.db

# Editor files
.idea/
.vscode/
*.swp

Test the template

Terminal output

$ mkdir shop
$ cd shop
$ git init -q
$ cp ../.gitignore .
$ echo "x" > debug.log
$ echo "SECRET=1" > .env
$ echo "SECRET=" > .env.example
$ mkdir node_modules
$ echo "x" > node_modules/pkg.js
$ echo "<h1>Hi</h1>" > index.html
$ git status -s
?? .env.example
?? .gitignore
?? index.html

How it works

  • node_modules/ ignores the full folder.
  • .env.* ignores all env variants, and the line !.env.example keeps the example file, which has no real secrets.
  • Patterns like *.log match files in any folder.
Note: A .gitignore does not remove files that are already tracked. See Git Ignore for how to untrack them.

Useful Git Aliases

Aliases are short names for long commands. They save a lot of typing. You can add them to your global Git config with git config --global alias.name "command".

Terminal output

$ git config –global alias.st "status -sb"
$ git config –global alias.co checkout
$ git config –global alias.br branch
$ git config –global alias.lg "log –oneline –graph –decorate"
$ git config –global alias.last "log -1 HEAD –stat"
$ git config –global alias.undo "reset –soft HEAD~1"
$ git st
## main
$ git lg
* ab2fc5b (HEAD -> main) Second commit
* 910ce77 First commit
$ git undo
$ git st
## main
A b.txt

Alias list

AliasReal commandUse
git stgit status -sbShort status with branch
git cogit checkoutSwitch or restore
git brgit branchList branches
git lggit log --oneline --graph --decorateCompact graph history
git lastgit log -1 HEAD --statShow the last commit
git undogit reset --soft HEAD~1Undo the last commit, keep the changes

How it works

  • Aliases are saved in the file ~/.gitconfig under the [alias] section.
  • You can also edit that file by hand with git config --global --edit.
  • Remove an alias with git config --global --unset alias.name.
Note: Create only the aliases you will really use. Also see Git Configuration.

Git Pre-commit Hook to Block Debug Code

This pre-commit hook checks the staged changes, and blocks the commit if it finds var_dump( or console.log(. It stops debug code going to the repository by mistake.

#!/bin/sh
# Block commit if staged lines contain debug code

PATTERN='var_dump\(|console\.log\('

if git diff --cached -U0 | grep -E "^\+.*($PATTERN)" > /dev/null; then
  echo "Commit blocked: remove debug code (var_dump / console.log)."
  git diff --cached -U0 | grep -E "^\+.*($PATTERN)"
  exit 1
fi

exit 0
Terminal output

$ chmod +x .git/hooks/pre-commit
$ echo 'console.log("test");' > app.js
$ git add app.js
$ git commit -m "Add app"
Commit blocked: remove debug code (var_dump / console.log).
+console.log("test");
$ echo 'alert("hello");' > app.js
$ git add app.js
$ git commit -m "Add app"
[main (root-commit) 7c5a852] Add app
1 file changed, 1 insertion(+)
create mode 100644 app.js

How it works

  • git diff --cached -U0 shows only the staged changed lines.
  • grep -E "^\+.*(pattern)" looks for added lines (they start with a plus) which have the debug function.
  • A non zero exit (exit 1) stops the commit. In the second try, the file is clean and the commit works.
Note: You can skip a hook once with git commit --no-verify, but do it only in a real emergency. See Git Hooks.

Script to Delete Merged Git Branches

After some weeks, a repository has many old branches that are already merged. This small script finds them and deletes them with the safe option -d, so unmerged work is never deleted.

#!/bin/sh
# Delete local branches already merged into main (keeps main)

git branch --merged main | grep -v -E '^\*|^ +main$' | while read -r branch; do
  git branch -d "$branch"
done

Branches before the cleanup: feature-cart and old-fix are merged, but feature-search has a commit that is not in main.

Terminal output

$ git branch
feature-cart
feature-search
* main
old-fix
$ sh ../cleanup-branches.sh
Deleted branch feature-cart (was 40827b1).
Deleted branch old-fix (was 40827b1).
$ git branch
feature-search
* main

How it works

  • git branch --merged main lists branches whose commits are all in main.
  • grep -v removes the current branch (the star line) and main from the list.
  • The loop runs git branch -d for each name. The capital -D is not used, so unmerged branches are safe.
Note: Remote branches are not touched. To clean the remote names, use git fetch --prune. See Git Branch.

Git commit-msg Hook to Check Message Format

The commit-msg hook runs after you write the commit message. This one allows only messages like feat: add login or fix: cart total, which keeps the history easy to read.

#!/bin/sh
# Allow only messages that start with feat:, fix:, docs: or chore:

MSG_FILE="$1"
FIRST_LINE=$(head -n 1 "$MSG_FILE")

if ! echo "$FIRST_LINE" | grep -E '^(feat|fix|docs|chore): .+' > /dev/null; then
  echo "Bad commit message: $FIRST_LINE"
  echo "Use: feat: ..., fix: ..., docs: ... or chore: ..."
  exit 1
fi
Terminal output

$ chmod +x .git/hooks/commit-msg
$ git commit -m "added file"
Bad commit message: added file
Use: feat: …, fix: …, docs: … or chore: …
$ git commit -m "feat: add first file"
[main (root-commit) 7a05184] feat: add first file
1 file changed, 1 insertion(+)
create mode 100644 a.txt
$ git log –oneline
7a05184 (HEAD -> main) feat: add first file

How it works

  • Git gives the hook the path of a temporary file with the message as the first argument ($1).
  • The script reads the first line and checks it with a regular expression.
  • When the script exits with 1, Git cancels the commit and the message is not saved.
Note: Hooks stay only in your own .git/hooks folder. For a team, keep the scripts in the project and use git config core.hooksPath .githooks. See Git Hooks.