Introduction

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

# 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

# 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:

Configuration

The following sections covers general configuration and information.

User information

# Pull user information.
git config user.name
git config user.email

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

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

Git configuration

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

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

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

# 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

Commits

# 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 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

# Difference. Use Shift + Q to quit.
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"

# 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

# 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 the message and files from a particular commit.
git show --stat <commit_id>

# 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

# 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

# If you can't pull/merge due to a file conflict, stashes changes, does a pull, and then puts the changes back, dropping the stash.
# git stash pop = git stash apply && git stash drop
git stash
git pull
git stash pop

# Stash changes and then apply them, keeping the stash.
git stash
git pull
git stash apply

# Drop the most recent stash.
git stash drop

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

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

# Show individual changes in a particular stash.
git stash show -p '[email protected]{0}'

Collaboration

# 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

Branching

# 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

# 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
# https://stackoverflow.com/a/5188364/11912
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 https://stackoverflow.com/a/42902058/11912
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

Tags

# 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

Logging

# View the last few commits.
git log
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 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$_" }

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>

Related Links