| Contents |

38 Quick Reference

Quickly look up commands based on what you want to do! Caveat: this list is grotesquely incomplete! See your man pages for more info!

In this reference section we use the following substitutions:

Also, don’t type the $—it’s the shell prompt. And everything after a # is a comment. A backslash \ at the end of a line indicates that it continues on the next line.

38.1 Glossary

38.2 File States

38.3 Configuration

For all git config commands, specify --global for a universal setting or leave it off to set the value just for this repo.

$ git config set VARIABLE VALUE
$ git config get VARIABLE
$ git config list
$ git config unset VARIABLE
$ git config --edit

38.3.1 Set identity

Username and email:

$ git config set --global user.name "Your Name"
$ git config set --global user.email "your-email@example.com"

SSH identity:

$ git config set core.sshCommand \
    "ssh -i ~/.ssh/id_alterego_ed25519 -F none"

38.3.2 Set default branch

This is the first branch created when you make a new repo.

$ git config set --global init.defaultBranch BRANCH

Common names are main, master, trunk, and development. This guide uses main.

38.3.3 Set default pull behavior to merge or rebase

$ git config set --global pull.rebase false   # Merge
$ git config set --global pull.rebase true    # Rebase

38.3.4 Set default editor, difftool, and mergetool

Set the default editor to Vim, and the default mergetool and difftool to Vimdiff, turn off prompting for the tools, and turn off mergetool backups:

$ git config set core.editor vim
$ git config set diff.tool vimdiff
$ git config set difftool.prompt false
$ git config set difftool.vimdiff.cmd 'vimdiff "$LOCAL" "$REMOTE"'
$ git config set merge.tool=vimdiff
$ git config set mergetool.vimdiff.cmd \
                             'vimdiff "$LOCAL" "$REMOTE" "$MERGED"'
$ git config --global set mergetool.keepBackup false

38.3.5 Colorful Git output

$ git config set color.ui true   # Or false

38.3.6 Autocorrect

Autocorrect will automatically run the command it thinks you meant. For example, if you git poush, it will assume you meant git push.

$ git config set help.autocorrect 0   # Ask "Did you mean...?"
$ git config set help.autocorrect 7   # Wait 0.7 seconds before run

$ git config set help.autocorrect immediate  # Just guess and go
$ git config set help.autocorrect prompt     # Prompt then go
$ git config set help.autocorrect never      # Turn autocorrect off

38.3.7 Newline translation

Handle automatic newline translation. Recommend set to true for Windows (not WSL) and false everywhere else.

$ git config set core.autocrlf true  # Windows (non-WSL)
$ git config set core.autocrlf false # WSL, Linux, Mac, C64, etc.

Obsolete commands for older versions:

git config user.email                     # Get
git config user.email "user@example.com"  # Set
git config --unset user.email             # Delete
git config --list                         # List
git config --edit                         # Edit

38.3.8 Aliases

Setting aliases, some examples:

$ git config set --global alias.logn 'log --name-only'
$ git config set alias.aa "add --all"
$ git config set alias.logc "log --oneline --graph --decorate"
$ git config set alias.diffs "diff --staged"
$ git config set alias.lol "log --graph"\
" --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s"\
" %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

Getting aliases:

$ git config get alias.logx
$ git config get --all --show-names --regexp '^alias\.'
$ git config set alias.aliases \
    "config get --all --show-names --regexp '^alias\.'"

Tracing an alias run:

$ GIT_TRACE=1 git logx

38.4 Creating and Cloning Repos

$ git clone URL       # Clone a URL
$ git clone URL DIR   # Clone a URL to directory
$ git init DIR        # Init repo at directory
$ git init .          # Init repo in the current directory

38.5 Adding, Renaming, Deleting, Committing

$ git add PATH             # Add PATH to the repo
$ git mv FILE1 FILE2       # Rename ("Move") FILE1 to FILE2
$ git mv FILE2 FILE1       # Undo the above rename
$ git rm FILE              # Delete ("Remove") FILE
$ git add -p FILE          # Add file in patch mode

$ git commit               # Commit files on stage
$ git commit -m "message"  # Commit with a message

Amending commits—don’t amend commits you have pushed unless you know what you’re getting into!

$ git commit --amend               # Amend last commit
$ git commit --amend -m "message"  # Amend with commit message
$ git commit --amend --no-edit     # Don't change commit message

To undelete a staged file, run these two commands in sequence:

$ git restore --staged FILE
$ git restore FILE

To undelete a deleted file, you could manually recover it from an old commit, or revert the commit that deleted it.

38.6 Getting Status

$ git status             # Show current file states
$ git log                # Show the commit logs
$ git log --name-only    # Also list changed files
$ git log CMMT           # Show log from a specific branch
$ git log CMMT1 CMMT2    # Show logs from multiple branches

$ git log CMMT1..CMMT2   # Show logs from CMMT2 since it
                         # diverged from CMMT1
$ git log CMMT1...CMMT2  # Show logs from CMMT1 and CMMT2
                         # since they diverged

38.7 Getting a Diff

$ git diff                # Diffs between working tree and stage
$ git diff HEAD^          # Diff from the previous commit to here
$ git diff HEAD^^         # Diff from the 2nd last commit to here
$ git diff HEAD~3 HEAD~2  # Diff from 3rd last to 2nd last commit
$ git diff CMMT           # Diff between CMMT and now
$ git diff CMMT1 CMMT2    # Diff between two commits (older first)

$ git diff CMMT1...CMMT2  # Diff between CMMT2 and the common
                          # ancestor of CMMT1 and CMMT2

$ git diff HEAD~3^!       # Diff between HEAD~3 and its parent
$ git diff -- FILE        # Run a diff just for a specific file
$ git diff HEAD^ -- FILE  # Run a diff just for a specific file

$ git diff -U5          # Show 5 lines of context
$ git diff -w           # Ignore whitespace
$ git diff --name-only  # Only show filenames of changed files
$ git diff --staged     # Diffs between stage and repo
$ git difftool          # Diffs using the configured difftool

38.8 Branches

A local branch looks like branchname. A remote tracking branch looks like remote/branchname.

$ git switch BRANCH         # Switch to a branch
$ git switch --detach HASH  # Detach HEAD to a commit
$ git switch -              # Switch back to previous commit
$ git switch --detach HEAD^   # Switch to previous commit
$ git switch --detach HEAD^^  # Switch to 2 commit ago
$ git switch --detach HEAD~3  # Switch to 3 commits ago
$ git switch --detach HEAD~99 # Switch to 99 commits ago
$ git switch main   # Reattach HEAD to main

$ git branch -v   # List all branches
$ git branch -va  # List all including remote tracking branches
$ git switch -c BRANCH        # Create and switch to BRANCH
$ git branch BRANCH           # Create BRANCH at HEAD
$ git branch BRANCH1 BRANCH2  # Create BRANCH1 at BRANCH2

$ git branch -d BRANCH   # Delete fully merged branch
$ git branch -D BRANCH   # Force delete unmerged branch

Obsolete style (use switch if you can):

$ git checkout CMMT      # Detach HEAD to a commit
$ git checkout HEAD^     # Detach HEAD to previous commit
$ git checkout HEAD~2    # Detach HEAD to second previous commit

38.9 Pulling and Pushing, and Fetching

$ git pull               # Pull from remote and merge or rebase
$ git pull --ff-only     # Only allow fast-forward merges
$ git pull --rebase      # Force a rebase on pull
$ git pull --no-rebase   # Force a merge on pull

$ git push                     # Push this branch to its remote

$ git push REMOTE BRANCH       # Create remote tracking branch and
                               # push to remote

$ git push -u REMOTE BRANCH    # Create remote tracking branch and
                               # push to remote, and use subsequent
                               # `git push` commands for this local
                               # branch

$ git push -u origin branch99  # Example

$ git push --tags              # Push all tags to origin
$ git push REMOTE --tags       # Push all tags to specific remote
$ git push REMOTE tag3.14      # Push single tag

$ git fetch        # Get data from remote but don't merge or rebase
$ git fetch REMOTE # Same, for a specific remote

38.10 Merging

$ git merge CMMT     # Merge commit or branch into HEAD
$ git merge --abort  # Rollback the current merge
$ git mergetool      # Run mergetool to resolve a conflict

$ git checkout --merged FILE   # Unstage resolved files

In a conflict occurs, you can always --abort. Otherwise:

  1. Fix the conflict.
  2. Add the fixed files.
  3. Commit to complete the merge.

38.11 Remotes

$ git remote -v                       # List remotes
$ git remote set-url REMOTE URL       # Change remote's URL
$ git remote add REMOTE URL           # Add a new remote
$ git remote rename REMOTE1 REMOTE2   # Rename REMOTE1 to REMOTE2
$ git remote remove REMOTE            # Delete REMOTE

38.12 Ignoring Files

Add a .gitignore file to your repo. It applies to this directory and all non-submodule subdirectories below it. Add descriptions of files to ignore to this file. Comments behind # are allowed. Blank lines are ignored.

Example .gitignore:

foo.aux     # Ignore specific file "foo.aux"
foo.*       # Ignore all files that start with "foo."
*.tmp       # Ignore all files that end with ".tmp"
frotz/      # Ignore all files in the "frotz" directory
foo[12].txt # Ignore "foo1.txt" and "foo2.txt"
foo?        # Ignore "foo" followed by any single character
frotz/bar   # Ignore file "bar" in directory "frotz"
*           # Ignore everything

Exceptions to earlier rules, also useful in .gitignore files in subdirectories to override rules from parent directories:

*.txt       # Ignore all text files
!keep.txt   # Except "keep.txt"

38.13 Rebasing

$ git rebase CMMT        # Rebase changes onto commit

$ git rebase -i CMMT     # Interactive rebase (squashing commits)

$ git rebase --continue  # Continue processing from conflict
$ git rebase --skip      # Skip a conflicting commit
$ git rebase --abort     # Bail out of rebasing

$ git pull --rebase      # Force a rebase on pull
$ git pull --no-rebase   # Force a merge on pull

38.14 Stashing

Stashes are stored on a stack.

$ git stash push    # Stash changed files
$ git stash         # Effectively the same as "push"
$ git stash FILE    # Stash a specific file
$ git stash pop     # Replay stashed files on working tree
$ git stash list    # List stashed files

$ git stash pop 'stash@{1}'   # Pop stash at index 1
$ git stash pop --index 1     # Same thing
$ git stash drop 'stash@{1}'  # Drop stash at index 1
$ git stash drop --index 1    # Same thing

38.15 Reverting

$ git revert CMMT     # Revert a specific commit
$ git revert -n CMMT  # Revert but don't commit (yet)

$ git revert CMMT1 CMMT2    # Revert multiple commits
$ git revert CMMT1^..CMMT2  # Revert a range (oldeest first)

$ git revert --continue  # Continue processing from conflict
$ git revert --skip      # Skip a conflicting commit
$ git revert --abort     # Bail out of reverting

38.16 Resetting

All resets move HEAD and the current checked out branch to the specified commit.

$ git reset --mixed CMMT  # Set stage to CMMT, don't change WT
$ git reset CMMT          # Same as --mixed
$ git reset --soft CMMT   # Don't change stage or working tree
$ git reset --hard CMMT   # Set stage and WT to CMMT

$ git reset -p CMMT       # Reset file in patch mode

Obsolete usage:

$ git reset FILE   # Same as "git restore --staged FILE"

38.17 The Reflog

$ git reflog      # Look at the reflog

…I admit this section could use a bit more information.

38.18 Cherry-pick

$ git cherry-pick CMMT   # Cherry-pick a particular commit

38.19 Blame

$ git blame FILE                # Who is responsible for each line
$ git blame --date=short FILE   # Same, shorter date format

38.20 Submodules

$ git clone --recurse-submodules URL       # Clone with submodules
$ git submodule update --recursive --init  # If you cloned without

$ git submodule add URL              # Add submodule
$ git add DIR                        # Add to repo
$ git pull --recurse-submodules      # Pull including submodules

$ git submodule status               # Submodule status
$ git ls-tree HEAD DIR               # Show submod pinned commit
$ git submodule init                 # Set up bookeeeping
$ git submodule update               # Bring in missing submods
$ git submodule update --recursive   # Handle submods of submods

Deleting a submodule—do these in order. In this example, DIR is the name of the submodule directory.

$ git submodule deinit DIR
$ rm -rf .git/modules/DIR
$ git config -f .gitmodules --remove-section submodule.DIR
$ git add .gitmodules
$ git rm --cached DIR
$ git commit -m "remove DIR submodule"

38.21 Tags

$ git tag     # List tags
$ git tag -l  # List tags
$ git tag TAG          # Create a tag on HEAD
$ git tag TAG CMMT     # Create a tag on a specific commit
$ git tag -a TAG       # Create an annotated tag
$ git tag -a TAG CMMT  # On a specific commit
$ git tag -a TAG -m "message" # Add a message to the tag
$ git push --tags          # Push all tags to origin
$ git push REMOTE --tags   # Push all tags to specific remote
$ git push REMOTE tag3.14  # Push specific tag
$ git tag -d tagname          # Delete a tag locally
$ git push REMOTE -d tagname  # Delete a tag on a remote

38.22 Worktrees

$ git worktree list   # List worktrees

$ git worktree add DIR CMMT            # Add worktree at CMMT
$ git worktree add --detach DIR CMMT   # Add, detach head at CMMT
$ git worktree add DIR HASH            # Add, detach head at HASH

$ git worktree remove DIR          # Remove worktree
$ git worktree remove --force DIR  # Remove, lose uncommitted mods


  1. https://learn.microsoft.com/en-us/windows/wsl/↩︎

  2. https://beej.us/guide/bggit/↩︎

  3. https://github.com/↩︎

  4. https://gitlab.com↩︎

  5. https://docs.gitea.com/↩︎

  6. https://learn.microsoft.com/en-us/windows/wsl/↩︎

  7. We’re glazing over an important topic here that we’ll come back to later called remote tracking branches.↩︎

  8. And again we’re doing some hand-waving. There are actually three branches. Two of them, main and origin/main are on your local clone. And there’s a third main on the remote origin that your origin/main is tracking. Feel free to ignore this detail until we get to the remote tracking branch chapter.↩︎

  9. https://www.vim.org/↩︎

  10. https://github.com/↩︎

  11. https://cli.github.com/↩︎

  12. https://github.com/cli/cli#installation↩︎

  13. https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent↩︎

  14. https://www.baeldung.com/linux/ssh-private-key-git-command↩︎

  15. https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens↩︎

  16. https://en.wikipedia.org/wiki/Hexadecimal↩︎

  17. I’m stretching it a bit, here. HEAD looks at the commit you’ve switched to. This might not be quite the same as what’s in your project subdirectory if you’ve modified some of the files since the moving HEAD to that commit. The commit is a snapshot, but that snapshot doesn’t include modifications to files until you make another commit that contains them.↩︎

  18. https://learngitbranching.js.org/↩︎

  19. All Git enthusiasts collectively, that is.↩︎

  20. https://github.com/github/gitignore↩︎

  21. The --staged flag is more modern. Older versions of Git used git diff --cached.↩︎

  22. A dot-env (.env) file is one that contains secret information (like login credentials) that is never committed to the repo. It’s usually in the .gitignore just to be sure. Someone related to the project will use a side channel to tell you what to put in it so you can authenticate properly. Support for .env files exists for a variety of languages and frameworks. I’m using my serious voice because this is a serious matter!↩︎

  23. https://tinyurl.com/y5kzpeyk↩︎

  24. https://git-scm.com/book/en/v2/Git-Tools-Rerere↩︎

  25. https://en.wikipedia.org/wiki/Stack_(abstract_data_type)↩︎

  26. https://github.com/beejjorgensen/git-example-repo↩︎

  27. https://en.wikipedia.org/wiki/XZ_Utils_backdoor↩︎

  28. https://en.wikipedia.org/wiki/Social_Security_number#SSNs_used_in_advertising↩︎

  29. https://support.github.com/request?q=pull+request+removals↩︎

  30. Git cleans up “unreachable” commits after some time has elapsed, so they won’t be instantly destroyed. But they’re on borrowed time unless you create a new branch to hold them.↩︎

  31. Who knows what it really does under the hood, but we’re going to use this as a mental model for how things work.↩︎

  32. You can leave off the --mixed since it’s the default.↩︎

  33. No guarantees. You shouldn’t rewrite commit history that is already public!! It makes a big mess!↩︎

  34. Perhaps using git reflog and git cherry-pick or git cherry-pick -n and potentially git add -p, all of which are covered in later chapters. Along with judicious use of rebase, old commits or parts of old commits can be applied while keeping the commit history clean.↩︎

  35. https://en.wikipedia.org/wiki/Battle_of_Mobile_Bay#“Damn_the_torpedoes”↩︎

  36. By default it’s 90 days. You can configure this with the gc.reflogExpire config option.↩︎

  37. Keeping in mind to never rewrite history on anything you’ve pushed, of course.↩︎

  38. Even if the changes were identical, the commit hash would still be different because the hash takes all kinds of other metadata into account.↩︎

  39. https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work↩︎

  40. https://git-scm.com/docs/git-config#_variables↩︎

  41. https://git-scm.com/docs/git-config#_conditional_includes↩︎

  42. https://git-scm.com/docs/git-config#_deprecated_modes↩︎

  43. https://git-scm.com/docs/git-log#_pretty_formats↩︎

  44. https://superuser.com/questions/232373/how-to-tell-git-which-private-key-to-use↩︎

  45. https://www.gnupg.org/↩︎

  46. Setting the PATH is outside the scope of this tutorial, but the short of it is if you can run the diff tool command on the command line (e.g. by running vimdiff), then it is in the PATH. If it says command not found or some such, then it is not in the PATH. Search the Intertubes for how to add something to the PATH in Bash. Or set the Git path config explicitly, as shown in the following paragraph.↩︎

  47. https://www.araxis.com/merge/index.en↩︎

  48. https://www.scootersoftware.com/↩︎

  49. https://sourcegear.com/diffmerge/↩︎

  50. https://kdiff3.sourceforge.net/↩︎

  51. https://apps.kde.org/kompare/↩︎

  52. https://meldmerge.org/↩︎

  53. https://www.perforce.com/products/helix-core-apps/merge-diff-tool-p4merge↩︎

  54. https://www.vim.org/↩︎

  55. https://winmerge.org/?lang=en↩︎

  56. https://www.araxis.com/merge/index.en↩︎

  57. https://www.scootersoftware.com/↩︎

  58. https://www.devart.com/codecompare/↩︎

  59. https://invent.kde.org/sdk/kdiff3↩︎

  60. https://meldmerge.org/↩︎

  61. https://www.perforce.com/products/helix-core-apps/merge-diff-tool-p4merge↩︎

  62. https://www.vim.org/↩︎

  63. https://winmerge.org/↩︎

  64. https://www.vim.org/↩︎

  65. https://vimhelp.org/index.txt.html#normal-index↩︎

  66. https://openvim.com/↩︎

  67. https://chatgpt.com/↩︎

  68. https://git-scm.com/book/en/v2↩︎

  69. https://git-scm.com/docs↩︎

  70. https://shafiul.github.io/gitbook/index.html↩︎

  71. https://wizardzines.com/git-cheat-sheet.pdf↩︎

  72. https://ohshitgit.com/↩︎

  73. https://learngitbranching.js.org/↩︎

  74. https://github.com/apps/github-learning-lab↩︎

  75. https://www.codecademy.com/learn/learn-git↩︎

  76. https://www.atlassian.com/git/tutorials↩︎

  77. https://gitimmersion.com/↩︎

  78. https://github.com/pluralsight/git-internals-pdf?tab=readme-ov-file↩︎

  79. http://sethrobertson.github.io/GitPostProduction/gpp.html↩︎

  80. https://wizardzines.com/zines/git/↩︎

  81. https://wizardzines.com/zines/oh-shit-git/↩︎

  82. https://www.manning.com/books/learn-git-in-a-month-of-lunches↩︎

  83. https://www.amazon.com/Introducing-GitHub-Non-Technical-Peter-Bell/dp/1491949740↩︎

  84. https://www.amazon.com/Git-Pocket-Guide-Working-Introduction/dp/1449325866↩︎

  85. https://www.amazon.com/Version-Control-Git-collaborative-development/dp/1449316387↩︎

  86. https://www.amazon.com/Git-Practice-Techniques-Mike-McQuaid/dp/1617291978↩︎

  87. https://www.amazon.com/Git-Teams-User-Centered-Efficient-Workflows/dp/1491911182↩︎

  88. https://pragprog.com/titles/tsgit/pragmatic-version-control-using-git/↩︎

  89. https://www.amazon.com/Mastering-Git-proficiency-productivity-collaboration/dp/1783553758↩︎


| Contents |