The following is a dump of Git commands for use on your shell of choice.

This book is generated with mdBook and hosted by GitLab Pages.

The book can be served locally by running mdbook serve.

Notes and warnings

If you want to escape, typically Shift + Q is the way to do so on Windows. This includes after running a command like git log (depending upon what it uses; Q will exit if it's using less for paging).

Also on Windows, remember that you can use notepad <filename> to open/create a file in Notepad.

Getting started

# Clone a repository into a new directory in the current directory.
git clone _.git
git clone _.git differentFolderName

# Create a new repository in the current directory.
git init
# Add a new remote for a repo. In this case 'upstream' might be helpful for the repo this was forked from.
git remote add upstream _.git

# Create a new branch.
git branch <branchName>

# Switch current repo to a different, existing, branch.
git checkout <branchName>
git checkout master

Clone troubleshooting

# If running into issues cloning a repository, clones a shallow copy. Then updates remotes and fetches everything.
git clone --depth=1 _.git
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch --unshallow

Getting started on macOS

Use Homebrew.

Install Git

brew install git

Update Git

If you haven't updated brew in a while, you can both make sure it and all applications are current.

brew update && brew upgrade

Otherwise just upgrade Git itself:

brew upgrade git

Getting started on Windows

There's a lot of different options. In no particular order:


The following sections covers general configuration and information.

User information

# Pull user information.
git config
git config

# Update all repository user name.
git config --global "Your Name"

# Update individual repository user name / email.
git config "Your Name"
git config ""

Git configuration

# See where configuration options are set.
git config --list --show-origin
git config --list --show-origin --name-only
git config --list --show-origin --show-scope --name-only

# Edit system/global/local.
git config --system --edit


# Set the default branch name when using git init. Here set to 'main'.
git config --global init.defaultBranch main

Repository information


# List config details, including remotes, for the current repo.
git config --local -l

# List all configuration settings for the current repository, including global and system.
git config -l


# Change remote origin URL (repo name change or move).
git remote set-url origin _.git

# See what remotes are setup on a repo.
git remote -v

# See more information about remotes (origin in this case).
git remote show origin

# Add a new remote with name _ and location _.git.
git remote add _ _.git

# Rename a remote.
git remote rename old-name new-name

# Delete a named remote.
git remote rm _

# Delete the origins push URL.
# May be necessary for projects that explicitly set a fetch and push URL.
git remote set-url --delete --push origin push.git


# List all local branches.
git branch --list

# List all branches, including remotes.
git branch -a

# List all branches merged into master (for cleanup).
git branch --merged


# List database information, include size (size-pack = kb).
git count-objects -v

# Runs database clean-up.
git gc

# Check validity of objects in the database.
# File System Check
git fsck

Beyond Compare

If you use Beyond Compare, the following sets up Git to use it for diff and merge.

git config --global diff.tool bc
git config --global difftool.bc.path "c:/Program Files/Beyond Compare 4/bcomp.exe"
git config --global merge.tool bc
git config --global mergetool.bc.path "c:/Program Files/Beyond Compare 4/bcomp.exe"
# This is up to the user on whether they want to keep .orig files.
git config --global mergetool.keepBackup false

Included Tools

# Simple GUI for Git.
git gui
# Simple GUI showing current branch commits.
# Simple GUI showing all branches and commits.
gitk --all


# Use a basic GUI. Actually works quite well for staging hunks that can't be split.
git gui

# See what has changed/etcetera
git status

# See only changes to tracked files
git status -uno
git status --untracked-files=no

# See which files have changed.
git diff --stat

# See how many files have changed (insertions/deletions).
git diff --stat | tail -n1

# See what or how many files are staged.
git diff --cached --stat
git diff --cached --stat | tail -n1

# See differences, with words colored inline.
git diff --color-words

# Difference. Use Shift + Q to quit. (Q may also work.)
git diff <file>

# Difference, ignoring space changes (EOL and multiple into one).
git diff -b <file>

# See what changed in a file that's already been staged.
git diff --cached <file>

# Add/stage a new/updated file.
git add <file>

# Add/stage multiple files, space delimited
git add <file> <file>

# Add a file with prompts on what to do with hunks
git add <file> -p
git add <file> --patch

# Add/stage all changes with prompts on what to do with hunks.
git add -p

# Add/stage all changes (including deletions)
git add -u

# Add/stage file deletion.
git rm <file>

# Add/stage file move/rename (such as case sensitive change)
git mv -f <file> <File>

# Add/stage directory rename.
git mv <oldDirectoryName> <newDirectoryName>

# Unstage change.
git reset HEAD <file>

# Unstage all changes.
git reset

# Selectively unstage changes to files.
git reset -p

# Work in Interactive mode.
git add -i

# Discard changes to a file
git checkout -- <file>

# Selectively discard changes to a file
git checkout -p

# Discard all local changes to tracked files. Leaves new files/folders as-is. Helpful if you did a mass find/replace and want to undo it.
git checkout -f
git checkout --force

# Discard all untracked files, interactively.
git clean -i

# Get a file from a particular commit.
git checkout a1b2c3 -- <file>

# Get a file from the commit previous to the commit. Helpful if you want to revert a change just made to a file.
git checkout a1b2c3~1 -- <file>

# Commit with Message.
git commit -m "Message"

# Commit with a summary and detail. Additional -m parameters can be passed as needed.
git commit -m "Summary" -m "Details."
git commit -m "Summary" -m "Details." -m "Another line/paragraph of details."

# Add all changed files and commit. New files are not committed.
git commit -am "Message"

# Show changes made in a particular commit.
git show <commit_id>

# Show changes made in last commit.
git show HEAD

# Show the message and files from a particular commit.
git show --stat <commit_id>

# See a list of changes made in branchName2 not in branchName1.
git diff <branchName1>...<branchName2>

# See a list of files that have changed in the current branch, compared to master. Includes number of files and inserts/deletes.
git diff --stat master...
git diff --stat master...<branchName>

# See the number of changed files, and how many inserts/deletes there were in a branch, since master.
git diff --shortstat master...<branchName>

# See a list of just the file names that were changed in a branch, since master.
git diff --name-status master...<branchName>

Fixing commits

# Update the last commit's message.
git commit --amend -m "Message"

# Update the last commit's date (reflected on GitHub).
git commit --amend --no-edit --date="Fri Nov 6 20:00:00 2016 -0600"

# Add another file to the last commit. Uses the last message.
git add <file>
git commit --amend -C HEAD

# Revert the last commit.
git revert HEAD

# Revert only the second to last commit. Etcetera
git revert HEAD~1

# Revert the last three commits, but stage the reversion locally.
git revert --no-commit HEAD~3..

# Reset working files to match master (or another branch), removing local changes and commits.
git fetch --all
git reset --hard origin/<branchName>

Stashing changes

# Stash changes in tracked files.
git stash

# Also stash untracked changes.
git stash -u

# List all stashes.
git stash list

# View all stashes in a pretty list.
git stash list --pretty=format:'%Cblue%gd%Cred: %C(yellow)%s'

# View changes in all stashes.
git stash list -p

# Show file changes in a particular stash (0 = last one).
git stash show 'stash@{0}'

# Show individual changes in a particular stash.
git stash show -p 'stash@{0}'

# Show stashed changes in individual file.
git diff ..stash -- <file>

# Create a patch file from the above.
git diff ..stash -- <file> > name.patch

# Apply stashed changes in an individual file.
git diff ..stash -- <file> | git apply

# Apply changes from the last stash. Keep the stash.
git stash apply
git stash apply 'stash@{0}'

# Apply changes from the last stash. Drop the stash after.
# git stash pop = git stash apply && git stash drop
git stash pop

# Drop the most recent stash.
git stash drop
git stash drop 'stash@{0}'
git stash drop 0

# Drop a particular stash.
git stash drop 'stash@{2}'

Using a temporary stash to pull/merge

# If you can't pull/merge due to a file conflict, create a temporary stash.
git stash
git pull
git stash pop


# Pull from default remote.
git pull

# Push to default remote.
git push

# Push to 'origin' remote from 'master' branch.
git push origin master

# Sync with the repo this was forked from / the remote associated with 'upstream.'
git pull upstream master

# Fetch from all remotes, by default, unless remotes are setup in the config.
git remote update


# Create a new branch.
git branch <branchName>

# Create a new branch at a specific commit, and switch to it.
git checkout -b <branchName> 3f4308df1e0b7f663d851108128e8e53deb1b5fb

# Switch to an existing branch.
git checkout <branchName>
git checkout master

# Switch to the previous branch.
git switch -
git switch @{-1}
# For use in PowerShell.
git switch '@{-1}'
git checkout -
git checkout @{-1}

# Checkout and switch to a new branch.
git checkout -b my_new_branch

# Push the new branch to a remote.
git push -u origin my_new_branch

# Alternative way to push a branch to a remote, without permanently setting the upstream.
git push origin my_new_branch

# Checkout a remote branch.
git checkout --track origin/<branchName>

# Merge changes from master into a branch.
git checkout <branchName>
git merge master

# Abort a merge (such as if there's conflicts that need to be resolved differently).
git merge --abort

# Delete a branch.
git branch -d my_new_branch

# Delete a branch on the remote.
git push origin :my_new_branch

# Do a dry run of pruning local branches that no longer exist on a remote.
git remote prune origin --dry-run

# Show all current branches, including remotes.
git show-branch -a --list

# Show all local branches that have been merged into master.
git branch --merged

# Show all local branches that have not been merged into master.
git branch --no-merged

# Show all local branches, sorted by and showing last commit
git for-each-ref --sort=committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'

# Merge two local branches, without fast-forwarding, with default editor opening to modify the message.
git merge <branchName> --no-ff --edit

# Merge two local branches, without fast-forwarding, and including messages for the last X (20 here) commits.
# According to Linus Torvalds, the better way to do merges.
git merge <branchName> --log=20 --no-ff

# While on a different branch, update the master branch from remote.
# See
git fetch origin master:master

# Put recent local commits in master into a new branch.
# X is the number of commits to rollback.
git branch <branchName>
git reset --hard HEAD~X
git checkout <branchName>

# Add a specific commit on top of the current branch.
git cherry-pick a6e1e5ad

# Rename the current branch
git branch -m <newBranchName>

# Get the name of the previous branch.
git rev-parse --symbolic-full-name @{-1}
# For PowerShell.
git rev-parse --symbolic-full-name '@{-1}'


# List all worktrees for the current repo.
git worktree list

# Create a new worktree for a specific branch. Path can't be a current working directory.
git worktree add ../path/for/branchName

# Delete a worktree.
git worktree remove path/to/worktree


git rebase in the Atlassian Git Tutorial has a nice overview of this command.

# Rebase the current branch by appying them to the passed branch.
git rebase <branchName>


# List all tags.
git tag

# Create a new tag, locally.
git tag -a TagName -m "Message"

# Delete a tag.
git tag -d TagName

# Push a tag to a remote (local by default).
git push origin TagName


# View the commit log, in various ways.
git log
git log --oneline
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'
git log --graph --date=short --pretty=format:'%C(yellow)%h%C(reset) %C(green)%ad%C(reset) %C(red)|%C(reset) %s %C(bold blue)[%an]%C(reset)%C(yellow)%d%C(reset)'
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen%cn%Creset %Cblue(%cr)%Creset' --abbrev-commit --date=relative
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
git log --graph --pretty=format:'%C(auto)%h%Creset - %d%s %Cgreen(%cr) %C(bold magenta)<%an>%Creset'
git log --decorate --graph --abbrev-commit --date=relative
git log --graph --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(white)- %an, %ar%Creset'

# View the last commit's message and changed files.
git log -1 HEAD --stat

# View commits that touched a file.
git log --full-history -- <file>

# View commits that touched a directory.
git log --full-history -- *\<directory-name>\*

# View commits that touched a directory.
git log <directory-path>
git log --pretty=oneline <directory-path>
git log --stat <directory-path>

# View last X commits, with message and files, that touched a directory.
git log --stat -X <directory-path>
git log --name-status -X .

# View commits that touched a file.
git log -p <file>

# View commits that touched a file, including renames.
git log --follow -p <file>

# View commits that have deleted files.
git log --diff-filter=D --summary

# View all deleted files.
git log --all --pretty=format: --name-only --diff-filter=D | sort -u

# Search commits messages for specific text (case sensitive).
git log --grep="searchTerm"

# Search commit diffs for changes in count of text (added or removed).
git log -SsearchTerm
git log -SsearchTerm -i

# Search commit diffs for specific text (case sensitive) showing changed lines.
git log -SsearchTerm -p

# Search commit diffs for changes involving search term.
# You can type /searchTerm to use the pager to find the first instance, and then n to find the next one(s).
git log -GsearchTerm -p

# Search commit contents for specific text.
git grep "searchTerm"
git grep -i "searchTerm"

# View all commits that are in branch-2 that are not in branch-1.
git log branch-1..branch-2

# View all commits ending with a particular branch
git log <branchName> --graph
git log <branchName> --graph --oneline

# View all commits merging a branch into master
git log --merges --first-parent --format=oneline

# View where all branches are in the commit history.
git log --color --graph --oneline --decorate --simplify-by-decoration --all

# View all users who committed to the repository, ordered by number of commits
git shortlog -s -n

# View mostly commonly modified files, based upon commits.
git log --pretty=format: --name-only | sort | uniq -c | sort -rg | head -10

# View all files in Git with the date the file was last touched in Git.

# macOs.
git ls-files | while read file; do git log -n 1 --pretty="Filename: $file, commit: %h, date: %ad" -- $file; done | less

# PowerShell.
git ls-tree -r --name-only HEAD | ForEach-Object { "$(git log -1 --format="%ai" -- "$_")`t$_" }



# List files in Git.
git ls-files
git ls-files -c
# List modified files.
git ls-files -m
# List other (untracked, ignored, ...) files.
git ls-files -o
# List untracked ignored files, based upon .gitignore.
git ls-files -io --exclude-from=.gitignore


# Pretty-print the contents of HEAD.
git cat-file -p HEAD
# Pretty-print the contents of a tree ID (file list), for example the tree ID from -p HEAD.
git cat-file -p <id_from_tree>
# Pretty-print the contents of an ID, for example the parent ID from -p HEAD.
git cat-file -p <id_from_parent>

Example: Updating a fork

# On the fork:
git checkout master

git pull upstream master

git push origin master

# If the branch should be created.
git checkout -b new_branch
git push -u origin new_branch

# If the branch already exists.
git checkout branch_name
git merge master

# If there are conflicts:
# Uses the default merge tool against all conflicts, one at a time.
git mergetool
# Uses the default merge commit message.
git commit --no-edit

Example: Create a new repo from a subdirectory

Useful if you want to pull a directory, and its commit history, out into a new repo.

# Clone the repository into a new directory.
git clone _.git

# Get only the files and commits impacting a particular directory.
# This should be the name of the directory only; if using PowerShell or the like make sure it does not include path information.
# <branchName> is the name of the default branch, generally master.
git filter-branch --prune-empty --subdirectory-filter <pathToDirectory> <branchName>

# View and then update your remotes with the new repo location.
git remote -v
git remote set-url origin _.git

git push -u origin <branchName>


The following are some aliases that I have setup.

Find them by running the following

git config --get-regexp 'alias.*'
# Define an alias to change user information for a repo.
git config --global alias.workprofile 'config ""'
# With the above alias defined, run in a repo directory to switch user information for the specific repo.
git workprofile


git config --global alias.last 'log -1 HEAD --stat'
git config --global alias.lg "!git lg1"
git config --global alias.lg1 "!git lg1-specific --all"
git config --global alias.lg2 "!git lg2-specific --all"
git config --global alias.lg3 "!git lg3-specific --all"
git config --global alias.lg1-specific "log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)'"
git config --global alias.lg2-specific "log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n''          %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'"
git config --global alias.lg3-specific "log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset) %C(bold cyan)(committed: %cD)%C(reset) %C(bold yellow)%d%C(reset)%n''          %C(white)%s%C(reset)%n''          %C(dim white)- %an <%ae> %C(reset) %C(dim white)(committer: %cn <%ce>)%C(reset)'"

Related Links