Top Tags

Git, GitHub Handbook

Quick reference handbook for essential Git and GitHub CLI commands

Setup & Configuration

Set User Identity

bash
1git config --global user.name "Your Name"
2git config --global user.email "[email protected]"

View Configuration

bash
1git config --list # show all settings
2git config --list --show-origin # show settings with file locations
3git config user.name # show single value

Set Default Branch Name

bash
1git config --global init.defaultBranch main

Set Default Editor

bash
1git config --global core.editor "code --wait" # VS Code
2git config --global core.editor "vim" # Vim
3git config --global core.editor "nano" # Nano

Credential & Auth Helpers

bash
1git config --global credential.helper cache # cache for 15 min
2git config --global credential.helper 'cache --timeout=3600' # cache 1 hour
3git config --global credential.helper store # save to disk (plain text)

Line Ending Configuration

bash
1git config --global core.autocrlf input # macOS/Linux (LF)
2git config --global core.autocrlf true # Windows (CRLF → LF on commit)

Creating & Cloning Repositories

Initialize a New Repo

bash
1git init # init in current directory
2git init my-project # create new directory & init
3git init --bare my-repo.git # bare repo (for servers)

Clone an Existing Repo

bash
1git clone https://github.com/user/repo.git
2git clone https://github.com/user/repo.git my-folder # custom directory
3git clone [email protected]:user/repo.git # SSH

Clone a Specific Branch

bash
1git clone -b branch-name https://github.com/user/repo.git
2git clone -b v2.0 --single-branch https://github.com/user/repo.git # single branch only

Shallow Clone

bash
1git clone --depth 1 https://github.com/user/repo.git # latest commit only
2git clone --depth 10 https://github.com/user/repo.git # last 10 commits
3git clone --shallow-since="2024-01-01" https://github.com/user/repo.git

Staging & Snapshotting

Check Status

bash
1git status
2git status -s # short format
3git status -sb # short + branch info

Stage Files

bash
1git add file.txt # stage a single file
2git add src/ # stage entire directory
3git add . # stage all changes in current dir
4git add -A # stage all changes in entire repo
5git add *.js # stage by pattern
6git add -p # interactive staging (hunk by hunk)

Unstage Files

bash
1git restore --staged file.txt # modern syntax
2git restore --staged . # unstage everything
3git reset HEAD file.txt # older syntax

Commit Changes

bash
1git commit -m "commit message"
2git commit -am "message" # stage tracked files + commit
3git commit --amend # edit last commit message
4git commit --amend --no-edit # add staged changes to last commit silently
5git commit --allow-empty -m "msg" # empty commit (useful for CI triggers)
6git commit -m "title" -m "body" # multi-line: title + description

Discard Local Changes

bash
1git restore file.txt # discard working directory changes
2git restore . # discard all changes
3git restore --source=HEAD --staged --worktree file.txt # restore both index & working tree
4git checkout -- file.txt # older syntax

Move & Remove Files

bash
1git mv old-name.txt new-name.txt # rename/move tracked file
2git rm file.txt # remove from working tree & index
3git rm --cached file.txt # untrack but keep on disk
4git rm -r --cached folder/ # untrack entire folder

Branching

List Branches

bash
1git branch # local branches
2git branch -r # remote branches
3git branch -a # all branches
4git branch -v # branches with last commit
5git branch -vv # branches with upstream tracking info
6git branch --merged # branches merged into current
7git branch --no-merged # branches not yet merged

Create a Branch

bash
1git branch new-branch # create only
2git checkout -b new-branch # create and switch
3git switch -c new-branch # create and switch (modern)
4git checkout -b feature origin/feature # track remote branch
5git switch -c feature --track origin/feature

Switch Branches

bash
1git checkout branch-name
2git switch branch-name # modern syntax
3git switch - # switch to previous branch

Rename a Branch

bash
1git branch -m old-name new-name # rename specific branch
2git branch -m new-name # rename current branch
3# After renaming, update remote:
4git push origin --delete old-name
5git push -u origin new-name

Delete a Branch

bash
1git branch -d branch-name # safe delete (merged only)
2git branch -D branch-name # force delete
3git push origin --delete branch-name # delete remote branch

Merging & Rebasing

Merge a Branch into Current

bash
1git merge branch-name
2git merge --no-ff branch-name # always create merge commit
3git merge --squash branch-name # squash all commits into one (then git commit)

Abort a Merge

bash
1git merge --abort

Resolve Conflicts

bash
1# After fixing conflicts manually:
2git add resolved-file.txt
3git commit # finalize merge
4# Or pick a side:
5git checkout --ours file.txt # keep current branch version
6git checkout --theirs file.txt # keep incoming branch version

Rebase

bash
1git rebase main # rebase onto main
2git rebase -i HEAD~3 # interactive rebase last 3 commits
3git rebase -i --autosquash HEAD~5 # auto-reorder fixup/squash commits
4git rebase --onto main feature bugfix # rebase bugfix onto main (skip feature)
5git rebase --abort # cancel rebase
6git rebase --continue # after resolving conflicts
7git rebase --skip # skip current conflicting commit

Interactive Rebase Actions

bash
1# Inside the interactive rebase editor:
2# pick = use commit as-is
3# reword = edit commit message
4# edit = pause to amend the commit
5# squash = merge into previous commit (keep message)
6# fixup = merge into previous commit (discard message)
7# drop = remove commit entirely

Remote Repositories

View Remotes

bash
1git remote -v # list remotes with URLs
2git remote show origin # detailed info about a remote

Add a Remote

bash
1git remote add origin https://github.com/user/repo.git
2git remote add upstream https://github.com/original/repo.git

Change Remote URL

bash
1git remote set-url origin https://github.com/user/new-repo.git
2git remote set-url origin [email protected]:user/repo.git # switch to SSH

Rename & Remove Remotes

bash
1git remote rename origin upstream
2git remote remove origin

Fetch, Pull & Push

Fetch (Download Without Merging)

bash
1git fetch # fetch from default remote
2git fetch origin # fetch from specific remote
3git fetch --all # fetch from all remotes
4git fetch --prune # remove stale remote-tracking branches
5git fetch origin --tags # fetch all tags from remote
6git fetch origin branch-name # fetch a specific branch

Pull (Fetch + Merge)

bash
1git pull # pull current branch
2git pull origin main # pull specific branch
3git pull --rebase # fetch + rebase instead of merge
4git pull --rebase=interactive # interactive rebase on pull
5git pull --autostash # auto-stash before pull, apply after
6git pull --ff-only # only fast-forward (fail if diverged)

Push

bash
1git push # push current branch
2git push origin main # push specific branch
3git push -u origin main # set upstream tracking and push
4git push --all # push all branches
5git push --tags # push all tags
6git push origin v1.0.0 # push a specific tag
7git push --force # force push ⚠️ destructive — rewrites remote
8git push --force-with-lease # safer force push (fails if remote has new commits)
9git push origin --delete branch # delete remote branch

Stashing

Save Changes to Stash

bash
1git stash # stash tracked changes
2git stash -u # include untracked files
3git stash -a # include untracked + ignored files
4git stash push -m "description" # with a message (modern)
5git stash push src/file.txt # stash specific files

List & Apply Stashes

bash
1git stash list # list all stashes
2git stash show # show latest stash summary
3git stash show -p # show latest stash diff
4git stash apply # apply latest stash (keep in stash)
5git stash pop # apply latest stash and remove it
6git stash apply stash@{2} # apply specific stash

Drop & Branch from Stash

bash
1git stash drop # remove latest stash
2git stash drop stash@{2} # remove specific stash
3git stash clear # remove all stashes
4git stash branch new-branch # create branch from stash and apply

Viewing History & Diffs

View Commit Log

bash
1git log # full log
2git log --oneline # compact format
3git log --oneline --graph --all # graph with all branches
4git log --oneline --decorate --graph # with branch/tag names
5git log --author="Name" # filter by author
6git log --grep="fix" # search commit messages
7git log -n 5 # last 5 commits
8git log --since="2024-01-01" # commits since date
9git log --until="2024-06-01" # commits until date
10git log --after="1 week ago" # relative dates
11git log -- file.txt # history of specific file
12git log --follow file.txt # follow renames
13git log --stat # include file change stats
14git log --pretty=format:"%h %an %s" # custom format

Pretty Log Formats

bash
1# Useful custom formats:
2git log --pretty=format:"%C(red)%h%Creset %s %C(blue)(%an)%Creset"
3git log --pretty=format:"%h %ad %s" --date=short

View Differences

bash
1git diff # unstaged changes
2git diff --staged # staged changes (same as --cached)
3git diff HEAD # all changes since last commit
4git diff main..feature # diff between branches
5git diff main...feature # changes in feature since branching from main
6git diff HEAD~2 # diff from 2 commits ago
7git diff --stat # summary of changes
8git diff --name-only # only file names
9git diff --name-status # file names with status (M/A/D)
10git diff --word-diff # inline word-level diff

Show a Specific Commit

bash
1git show abc1234 # full commit details
2git show HEAD # latest commit
3git show HEAD~2 # 2 commits ago
4git show HEAD:src/file.txt # file content at commit
5git show --stat abc1234 # commit stats only

Blame (Line-by-Line Authorship)

bash
1git blame file.txt
2git blame -L 10,20 file.txt # specific line range
3git blame -w file.txt # ignore whitespace changes
4git blame -C file.txt # detect moved/copied lines

Shortlog (Summary by Author)

bash
1git shortlog -sn # count commits per author
2git shortlog -sn --no-merges # exclude merge commits

Undoing & Resetting

Reset Commits

bash
1git reset --soft HEAD~1 # undo commit, keep changes staged
2git reset --mixed HEAD~1 # undo commit, unstage changes (default)
3git reset --hard HEAD~1 # undo commit, discard all changes ⚠️
4git reset --hard origin/main # reset to match remote exactly ⚠️

Revert a Commit (Safe Undo)

bash
1git revert abc1234 # create new commit that undoes changes
2git revert HEAD # revert last commit
3git revert HEAD~3..HEAD # revert last 3 commits
4git revert --no-commit abc1234 # stage revert without committing

Cherry-Pick (Apply Specific Commits)

bash
1git cherry-pick abc1234 # apply a single commit
2git cherry-pick abc1234 def5678 # apply multiple commits
3git cherry-pick abc1234..def5678 # apply range of commits
4git cherry-pick --no-commit abc1234 # stage without committing
5git cherry-pick --abort # cancel in-progress cherry-pick

Recover Lost Commits

bash
1git reflog # view history of HEAD movements
2git reflog show feature-branch # reflog for specific branch
3git checkout abc1234 # go to a specific commit (detached HEAD)
4git branch recovery abc1234 # create branch from lost commit

Tags

List Tags

bash
1git tag # list all tags
2git tag -l "v1.*" # filter tags by pattern
3git tag -l --sort=-version:refname "v*" # sort by version descending

Create Tags

bash
1git tag v1.0.0 # lightweight tag
2git tag -a v1.0.0 -m "Release 1.0.0" # annotated tag (recommended)
3git tag -a v1.0.0 abc1234 # tag a past commit

Push Tags

bash
1git push origin v1.0.0 # push single tag
2git push origin --tags # push all tags
3git push --follow-tags # push commits + annotated tags

Delete Tags

bash
1git tag -d v1.0.0 # delete local tag
2git push origin --delete v1.0.0 # delete remote tag
3git push origin :refs/tags/v1.0.0 # alternative delete syntax

Show Tag Info

bash
1git show v1.0.0 # show tag details and commit
2git describe # describe HEAD relative to nearest tag
3git describe --tags --abbrev=0 # nearest tag name only

Advanced: Bisect, Worktree & Submodules

Bisect (Binary Search for Bugs)

bash
1git bisect start # begin bisect session
2git bisect bad # mark current commit as bad
3git bisect good abc1234 # mark a known good commit
4# Git checks out a midpoint — test it, then:
5git bisect good # if this commit works
6git bisect bad # if this commit is broken
7# Repeat until Git finds the first bad commit
8git bisect reset # end bisect, return to original branch
9git bisect log # view bisect history
10git bisect replay log.txt # replay a saved bisect session

Automated Bisect

bash
1git bisect start HEAD abc1234
2git bisect run ./test-script.sh # auto-test each step (exit 0 = good)

Worktrees (Multiple Working Directories)

bash
1git worktree list # list all worktrees
2git worktree add ../hotfix-tree hotfix-branch # create linked worktree
3git worktree add -b new-branch ../new-tree # create worktree + new branch
4git worktree remove ../hotfix-tree # remove a worktree
5git worktree move ../old-path ../new-path # move a worktree

Submodules

bash
1git submodule add https://github.com/user/lib.git libs/lib # add submodule
2git submodule init # initialize submodule config
3git submodule update # fetch & checkout submodule commits
4git submodule update --init # init + update in one step
5git submodule update --init --recursive # include nested submodules
6git submodule update --remote # update to latest remote commit
7git submodule foreach git pull origin main # pull in all submodules
8git submodule status # show submodule commit SHAs
9git submodule deinit libs/lib # unregister a submodule
10git rm libs/lib # remove submodule from project

Sparse Checkout (Partial Repo)

bash
1git sparse-checkout init --cone # enable cone mode
2git sparse-checkout set src/ docs/ # only checkout these dirs
3git sparse-checkout add tests/ # add more dirs
4git sparse-checkout list # show checked-out dirs
5git sparse-checkout disable # disable, restore full repo

GitHub CLI (gh)

Authentication

bash
1gh auth login # interactive login
2gh auth login --web # browser-based login
3gh auth login --with-token < token.txt # token from file
4gh auth login --hostname enterprise.internal # GitHub Enterprise
5gh auth status # check auth status
6gh auth logout # log out
7gh auth refresh --scopes write:packages # add extra scopes

Repository Management

bash
1gh repo create my-repo --public # create public repo
2gh repo create my-org/project --private # create in org
3gh repo create --source=. --remote=origin --push # from local dir
4gh repo clone user/repo # clone a repo
5gh repo fork user/repo # fork a repo
6gh repo fork user/repo --clone # fork and clone locally
7gh repo fork --org my-org # fork into organization
8gh repo view # view repo info
9gh repo view --web # open in browser
10gh repo set-default owner/repo # set default repo for CLI
11gh repo list user --limit 50 # browse repos

Pull Requests

bash
1gh pr create --title "Title" --body "Body" # create PR
2gh pr create --fill # auto-fill from commits
3gh pr create --draft # create as draft
4gh pr create --web # open creation page in browser
5gh pr create --base main --head feature # specify branches
6gh pr list # list open PRs
7gh pr list --state all # list all PRs
8gh pr view 42 # view PR details
9gh pr view 42 --web # open PR in browser
10gh pr checkout 42 # checkout PR locally
11gh pr diff 42 # view PR diff
12gh pr merge 42 # merge PR
13gh pr merge 42 --squash # squash merge
14gh pr merge 42 --rebase # rebase merge
15gh pr merge 42 --auto # auto-merge when checks pass
16gh pr close 42 # close without merging
17gh pr reopen 42 # reopen a closed PR
18gh pr review 42 --approve # approve PR
19gh pr review 42 -r -b "needs changes" # request changes
20gh pr revert 42 # revert a merged PR

Search PRs

bash
1gh search prs "fix bug" --repo=user/repo
2gh search prs --review-requested=@me --state=open
3gh search prs --author=@me --merged
4gh search prs --assignee=@me --draft

Issues

bash
1gh issue create --title "Bug" --body "Details"
2gh issue create --label "bug,urgent" # with labels
3gh issue create --assignee @me # assign to self
4gh issue list # list open issues
5gh issue list --state all --limit 100
6gh issue list --label "bug" # filter by label
7gh issue view 42 # view issue details
8gh issue close 42 # close issue
9gh issue reopen 42 # reopen issue
10gh issue edit 42 --add-label "priority" # edit labels
11gh issue comment 42 --body "Working on this"

Releases

bash
1gh release create v1.0.0 # create release
2gh release create v1.0.0 --generate-notes # auto-generate notes
3gh release create v1.0.0 --draft # create draft release
4gh release create v1.0.0 ./build.zip # upload asset
5gh release list # list releases
6gh release view v1.0.0 # view release
7gh release download v1.0.0 # download assets
8gh release delete v1.0.0 # delete release

Gists

bash
1gh gist create file.txt # create gist from file
2gh gist create file.txt --public # public gist
3gh gist create -d "description" file.txt # with description
4gh gist list # list your gists
5gh gist view <id> # view gist
6gh gist clone <id> # clone gist locally
7gh gist edit <id> # edit a gist
8gh gist delete <id> # delete a gist

Workflow Runs (GitHub Actions)

bash
1gh workflow list # list workflows
2gh workflow view deploy.yml # view workflow details
3gh workflow run deploy.yml # trigger workflow manually
4gh workflow run deploy.yml -f env=production # with input parameters
5gh run list # list recent runs
6gh run view 12345 # view run summary
7gh run view 12345 --log # full run log
8gh run view 12345 --log-failed # only failed step logs
9gh run watch 12345 # live-watch a run
10gh run rerun 12345 # rerun a workflow
11gh run cancel 12345 # cancel a run
12gh run download 12345 # download run artifacts

Secrets & Variables

bash
1gh secret set MY_SECRET # set repo secret (prompt)
2gh secret set MY_SECRET < secret.txt # set from file
3gh secret set MY_SECRET --env production # environment secret
4gh secret set MYSECRET --user # user-level (Codespaces)
5gh secret list # list repo secrets
6gh secret delete MY_SECRET # delete a secret
7gh variable set MY_VAR --body "value" # set a variable
8gh variable list # list variables

SSH & GPG Keys

bash
1gh ssh-key list # list SSH keys
2gh ssh-key add ~/.ssh/id_ed25519.pub # add SSH key
3gh gpg-key list # list GPG keys
4gh gpg-key add key.pub # add GPG key

GitHub API (Direct Access)

bash
1gh api repos/user/repo # GET request
2gh api repos/user/repo/issues -f title="Bug" # POST with fields
3gh api --method DELETE repos/user/repo/issues/1
4gh api graphql -f query='{ viewer { login } }' # GraphQL query
5gh api repos/{owner}/{repo}/releases --jq '.[0].tag_name' # with jq filter

Cleanup & Maintenance

Remove Untracked Files

bash
1git clean -n # dry run — show what would be removed
2git clean -f # remove untracked files
3git clean -fd # remove untracked files and directories
4git clean -fX # remove only ignored files
5git clean -fdx # remove untracked + ignored files & dirs ⚠️

Garbage Collection

bash
1git gc # standard cleanup
2git gc --aggressive # deeper optimization
3git gc --prune=now # prune all unreachable objects immediately

Prune & Verify

bash
1git remote prune origin # remove stale remote-tracking branches
2git fetch --prune # prune during fetch
3git prune # remove unreachable objects
4git fsck # verify repository integrity

Count Objects & Repo Size

bash
1git count-objects -vH # human-readable object count & size
2git rev-list --count HEAD # total commit count

Useful Aliases

bash
1git config --global alias.st "status -sb"
2git config --global alias.co checkout
3git config --global alias.br branch
4git config --global alias.ci commit
5git config --global alias.unstage "restore --staged"
6git config --global alias.last "log -1 HEAD --stat"
7git config --global alias.lg "log --oneline --graph --all --decorate"
8git config --global alias.amend "commit --amend --no-edit"
9git config --global alias.undo "reset --soft HEAD~1"
10git config --global alias.contributors "shortlog -sn --no-merges"
11git config --global alias.aliases "config --get-regexp alias"

.gitignore Patterns

bash
1# Common patterns
2*.log # ignore all .log files
3node_modules/ # ignore directory
4dist/ # ignore build output
5.env # ignore env files
6.env.* # ignore all env variants
7!.env.example # exception — track this one
8**/*.tmp # ignore .tmp in any nested directory
9build/ # ignore build folder
10*.DS_Store # macOS system files
11Thumbs.db # Windows system files

Global .gitignore

bash
1git config --global core.excludesfile ~/.gitignore_global