Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

📖 Git Command Handbook

A practical, no-fluff reference of Git commands for open-source contributors — from your first git clone to rescuing a broken history with reflog.

PRs Welcome License: MIT


📑 Table of Contents


🗺️ Quick Reference

Goal Command
Initialize a repo git init
View remotes git remote -v
List branches git branch
Switch branches git switch <branch>
Fetch changes git fetch
Clone a repo git clone <url>
Check status git status
Stage all files git add -A
Commit git commit -m "message"
Push to remote git push
Pull from remote git pull
Create & switch branch git checkout -b <branch>
Merge a branch git merge <branch>
View history (compact) git log --oneline
View visual branch graph git log --oneline --graph --decorate --all
Undo last commit (keep changes) git reset --soft HEAD~1
Temporarily save work git stash
See what changed git diff
Search commit messages git log --grep=<keyword>
Who last changed a line git blame <file>

🌍 Open Source Contributor Workflow

The typical flow for contributing to someone else's open-source project on GitHub.
# 1. Fork the repository on GitHub, then clone your fork
git clone <your-fork-url>
cd <repo>

# 2. Add the original repository as "upstream"
git remote add upstream <original-repo-url>

# 3. Start a feature branch from the latest main
git switch main
git pull upstream main
git switch -c feature/my-fix

# 4. Make your changes, then stage and commit
git status
git add <files>
git commit -m "Add validation for empty usernames"

# 5. Update your branch with the latest upstream changes
git fetch upstream
git rebase upstream/main

# 6. Push your branch to your fork
git push -u origin feature/my-fix

# 7. Open a Pull Request from your fork to the original repository

# 8. If maintainers request changes, make the changes,
#    then commit and push again
git add <files>
git commit -m "Address review feedback"
git push

💡 If your fork has fallen behind, sync main before creating a new branch:

git switch main
git pull upstream main
git push origin main

⚙️ Setup & Init

Set up Git and create or connect repositories.

Configure your Git identity

git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global core.editor "code --wait"    # set VS Code as default editor
git config --global init.defaultBranch main       # set default branch name to "main"

Set up SSH

On a new machine, set up SSH to authenticate with GitHub without using HTTPS credentials.

# 1. Generate an SSH key
ssh-keygen -t ed25519 -C "you@example.com"

# 2. Start the SSH agent
eval "$(ssh-agent -s)"

# 3. Add your SSH key to the agent
ssh-add ~/.ssh/id_ed25519

# 4. Copy your public key
cat ~/.ssh/id_ed25519.pub

# 5. Test the connection
ssh -T git@github.com

Add the public key to GitHub → Settings → SSH and GPG keys → New SSH key.

💡 Never share your private key (~/.ssh/id_ed25519). Only add the public key (~/.ssh/id_ed25519.pub) to GitHub.

View Git configuration

git config --list
git config --global --list    # global only
git config user.name          # check a specific key

Clone a remote repository

git clone <url> [folder-name]
git clone --depth 1 <url>           # shallow clone (latest snapshot only, faster)
git clone --branch <branch> <url>   # clone a specific branch

Git supports both SSH and HTTPS for remote URLs.

Initialize a local repository

git init [folder]

Omit folder to init in the current directory.

Connect to a remote repository

git remote add origin <url>
git push -u origin main

-u sets the upstream branch, so later you can use git push directly.

Create Git aliases

git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.lg "log --oneline --graph --decorate --all"
git config --global alias.undo "reset --soft HEAD~1"

📋 Staging & Committing

Stage changes and save them as commits.

Git basics

  • Working directory — files you're editing right now
  • Stage (index) — files earmarked for the next commit
  • Commit — a saved snapshot with a message and ID
  • HEAD — pointer to the latest commit on the current branch

Check repository changes

git status
git status -s                    # short/compact status view
git diff                         # unstaged changes vs HEAD
git diff --cached                # staged changes vs HEAD
git diff HEAD                    # all changes vs HEAD
git diff <file>                  # diff for a specific file only
git diff <branch-A> <branch-B>   # diff between branches

Stage changes

git add <file>       # stage a specific file
git add -A           # stage everything (new, modified, deleted)
git add .            # stage all changes in current directory
git add *.js         # stage all JS files
git add -p <file>    # interactively pick which chunks to stage

Interactive staging prompts: y yes · n no · s split · e edit · d skip rest of file

Commit

git commit -m "Short summary (imperative tense: Fix bug, not Fixed bug)"
git commit -a                                  # stage all tracked files and commit in one step
git commit --allow-empty -m "Empty commit"     # trigger CI/CD without code changes

Amend the last commit (before pushing)

git commit --amend -m "Corrected message"
git commit --amend -a            # also include any new staged changes
git commit --amend --no-edit     # amend without changing the message

⚠️ Don't amend commits already pushed to a shared branch.

Write a good commit message

[TYPE] Short summary (≤ 72 chars, imperative tense)

Optional longer explanation. What changed and why?
Wrap lines at 74 chars.

Types: [FEATURE] [BUGFIX] [TASK] [SECURITY]
Flags:  [!!] breaking change  [DB] schema change  [CONF] config change

Ref #42

🌿 Branches

Create and manage branches for different changes.

View branches

git branch                    # list local branches
git branch -r                 # list remote branches
git branch -a                 # list all branches
git branch -v                 # show branches and latest commits
git branch -a --merged        # show merged branches
git branch -a --no-merged     # show unmerged branches

Create, switch, and rename

git branch <name>             # create a branch
git checkout <name>           # switch to a branch
git checkout -b <name>        # create and switch to a branch
git switch <name>             # switch to a branch
git switch -c <name>          # create and switch to a branch
git branch -m <old> <new>     # rename a branch

Delete branches

git branch -d <name>                  # delete merged branch (safe)
git branch -D <name>                  # force-delete (even if unmerged) ⚠️
git push origin --delete <branch>     # delete a remote branch

Track remote branches

git checkout -t origin/<branch>                # checkout + track remote branch
git branch --track <local> origin/<remote>     # create tracked branch
git branch -u origin/<remote>                  # set upstream for current branch

Inspect branch information

git branch --contains <commit-id>    # which branches include a commit
git branch --merged main             # what's already in main

🌐 Syncing with Remote

Push, pull, and fetch.

Manage remote repositories

git remote -v                        # list configured remotes
git remote add <name> <url>          # add a remote repository
git remote rename origin upstream    # rename a remote
git remote remove <name>             # remove a remote
git remote show origin               # show remote details
git remote prune origin              # remove stale remote-tracking branches

Fetch vs Pull

git fetch [remote]         # fetch changes without merging
git fetch --all            # fetch from all remotes
git pull                   # fetch and merge changes
git pull --rebase          # fetch and rebase changes
git pull origin <branch>   # pull a specific branch

Push

git push                             # push the current branch
git push -u origin <branch>          # push and set the upstream branch
git push --all origin                # push all local branches
git push --tags origin               # push all tags
git push --force-with-lease          # safely force-push if remote is unchanged
git push --force                     # force-push and overwrite remote history ⚠️

💡 Prefer --force-with-lease because it helps prevent overwriting newer remote changes.


🔗 Keeping Your Fork in Sync

Keep your fork up to date with the original repository.

Update your local main branch

git switch main
git fetch upstream
git pull upstream main

Update your fork's main branch

git switch main
git fetch upstream
git pull upstream main
git push origin main

Update your feature branch

git switch <branch>
git fetch upstream
git rebase upstream/main

Check whether your branch is behind

git fetch upstream
git status
git log HEAD..upstream/main --oneline

💡 Keep your fork's main branch synchronized with the original repository before creating new branches.


🧩 Merging & Rebasing

Combine branches.

Merge branches

git merge <branch>              # merge a branch into the current branch
git merge --no-ff <branch>      # create a merge commit
git merge --squash <branch>     # combine changes into one commit
git merge --abort               # cancel the current merge

Resolve merge conflicts

# 1. Edit the conflicted files
# 2. Stage the resolved files
git add <resolved-file>
# 3. Complete the merge
git commit -m "Resolve merge conflicts"

# Or open a merge tool
git mergetool

Rebase a branch

git rebase <branch>             # replay commits on top of another branch
git rebase --abort              # cancel the current rebase
git rebase --continue           # continue after resolving a conflict
git rebase --skip               # skip the current commit
git rebase -i HEAD~3             # edit the last 3 commits
git rebase -i <commit-id>       # start an interactive rebase

Interactive rebase keywords: pick keep · reword edit message · squash combine · fixup squash silently · edit pause · drop delete

⚠️ Avoid rebasing commits already pushed to a shared branch.

Resolve rebase conflicts

If a rebase causes a conflict, Git pauses the rebase and marks the conflicted files.

# 1. Check which files have conflicts
git status

# 2. Resolve the conflicts in the files

# 3. Stage the resolved files
git add <resolved-file>

# 4. Continue the rebase
git rebase --continue

💡 Repeat the process if Git reports another conflict.

⚠️ To cancel the rebase and return to the state before it started: git rebase --abort

Pull and rebase

git pull --rebase

🕘 Viewing History

View commits, changes, and repository history.

View commit history

git log                                       # show commit history
git log --oneline                             # show commits in one line
git log --oneline --graph --decorate --all    # show the branch history graph
git log -n 10                                 # show the last 10 commits
git log -p <file>                             # show changes made to a file
git log --grep=<keyword>                      # search commit messages
git log --author="Name"                       # show commits by an author
git log --since="2 weeks ago"                 # show recent commits
git log --after="2024-01-01"                  # show commits after a date
git log <branch>.. --oneline                  # show commits in HEAD but not in <branch>
git log <branch-A>..<branch-B>                # show commits in branch B but not A
git shortlog -sn                              # count commits by author

Inspect changes

git diff <branch-A> <branch-B>          # compare two branches
git diff <branch> --name-status         # list changed files
git diff <commit-A> <commit-B>          # compare two commits
git show <commit-id>                    # show a commit and its changes
git show <commit-id>:<file>             # show a file from a commit
git blame <file>                        # show who changed each line
git blame -L 10,25 <file>               # show changes for specific lines
git branch --contains <commit-id>       # show branches containing a commit

Reflog and recovery

git reflog                    # show HEAD movement history
git reflog show <branch>      # show movement history for a branch

If you lose a commit, git reflog can often help you recover it.

Search repository content

git grep "search term"          # search files for a string
git log -S "search term"        # find commits that added or removed a string
git log -G "regex pattern"      # find commits matching a pattern

📌 Stashing

Temporarily save changes without committing them.
git stash                                # save tracked changes
git stash -u                             # also save untracked files
git stash push -m "optional message"      # save changes with a message
git stash list                           # list saved stashes
git stash show stash@{0}                 # show stash contents
git stash show -p stash@{0}              # show the full stash diff
git stash apply [stash@{0}]              # restore a stash and keep it
git stash pop [stash@{0}]                # restore a stash and remove it
git stash drop [stash@{0}]               # delete a stash
git stash clear                          # delete all stashes
git stash branch <branch> stash@{0}      # create a branch from a stash

stash@{0} is the newest stash. Higher numbers refer to older stashes.


🎯 Tags

Create and manage tags for specific commits and releases.
git tag -n                              # list tags with annotations
git tag -l "v1.*"                       # list tags matching a pattern
git tag <tag-name>                      # create a lightweight tag
git tag <tag-name> -m "<annotation>"    # create an annotated tag
git tag <tag-name> <commit-id>          # tag a specific commit
git tag -d <tag-name>                   # delete a local tag
git push origin <tag-name>              # push a tag to the remote
git push --tags origin                  # push all tags to the remote
git push origin --delete <tag-name>     # delete a remote tag
git show <tag-name>                     # show tag details

💡 Use semantic versioning for releases, such as v1.0.0, v1.2.3.


🚀 Advanced Git Commands

For more complex workflows.

Apply specific commits

git cherry-pick <commit-id>              # apply one commit to the current branch
git cherry-pick <commit-A>..<commit-B>   # apply a range of commits
git cherry-pick --no-commit <commit-id>  # apply changes without committing
git cherry-pick --abort                  # cancel the cherry-pick

Find the commit that introduced a bug

git bisect start
git bisect bad                     # mark the current commit as bad
git bisect good <commit-id>        # mark a known working commit
# Test the commit Git selects, then mark it:
git bisect good                    # if the commit works
git bisect bad                     # if the commit is broken
git bisect reset                   # finish the bisect

Manage submodules

git submodule add <url> [folder]           # add another repository as a submodule
git submodule update --init --recursive    # initialize submodules after cloning
git submodule update --remote              # update submodules

Manage multiple worktrees

git worktree add <path> <branch>    # create a worktree for a branch
git worktree list                   # list existing worktrees
git worktree remove <path>          # remove a worktree

Remove untracked files

git clean -n       # preview files that would be removed
git clean -f       # remove untracked files ⚠️
git clean -fd      # remove untracked files and directories ⚠️
git clean -fdx     # also remove ignored files ⚠️

Use sparse checkout

git sparse-checkout init --cone
git sparse-checkout set <folder>

🚑 Undoing Mistakes

Recover from errors safely.

Unstage or discard changes

git reset HEAD -- [file]          # unstage files and keep the changes
git restore --staged <file>       # unstage a file
git restore <file>                # discard working directory changes ⚠️
git checkout -- [file]            # older syntax for restoring a file

Undo commits

git reset --soft HEAD~1           # undo the last commit and keep changes staged
git reset HEAD~1                  # undo the last commit and keep changes unstaged
git reset --hard HEAD~1           # undo the last commit and discard changes ⚠️
git reset --hard HEAD             # discard all uncommitted changes ⚠️
git revert <commit-id>            # create a new commit that reverses another commit
git revert HEAD                   # reverse the latest commit

Undo a merge

git reset --hard <commit-id-before-merge>    # remove an unpushed merge
git revert -m 1 <merge-commit-id>            # reverse a pushed merge

Stop tracking a file

git rm --cached <file>
git rm --cached -r <folder>    # recursively (e.g. accidentally committed node_modules)

Then add the file to .gitignore.

Fix an incorrect .gitignore

git rm --cached <file>
echo "<file>" >> .gitignore
git add .gitignore
git commit -m "Remove <file> and add to gitignore"

Recover lost work

git reflog                                     # find previous HEAD positions
git checkout <commit-id>                       # inspect a previous commit
git checkout -b recovery-branch <commit-id>    # create a branch from a commit
git reset --hard <commit-id>                   # move the branch back to a commit

🔧 Configuration & .gitignore

Fine-tune Git's behavior.

Configure Git scopes

git config --local     # apply settings to this repository
git config --global    # apply settings to your user account
git config --system    # apply settings to all users

Common Git settings

git config --global core.autocrlf input        # handle line endings on Mac/Linux
git config --global core.autocrlf true         # handle line endings on Windows
git config --global pull.rebase true           # use rebase for pulls by default
git config --global push.default current       # push the current branch by default
git config --global merge.conflictstyle diff3  # show the common ancestor in conflicts

.gitignore tips

*.log            # ignore all .log files
/build           # ignore the top-level build folder
node_modules/    # ignore node_modules folders
!important.log   # keep this file from being ignored

💡 Use Git ignore templates for common languages and frameworks.

Stop tracking an ignored file

git rm --cached <file>

🤝 Contributing to This Repo

Found a command that's missing, outdated, or explained badly? Contributions are welcome! See CONTRIBUTING.md for guidelines on adding new commands or fixing existing entries.


📚 Sources


📄 License

This project is licensed under the MIT License.

About

A practical Git command reference — from your first clone to branching, merging, rebasing, and rescuing broken history

Resources

Contributing

Stars

26 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors