Git Reference Guide

Overview

This document contains of list of Git commands I find useful. The tables will grow as I learn more. Errors are likely, but should diminish over time as I learn, correct, and add to the material below. The reference tables are broken down into the different major actions: Cloning, Editing, Staging, Stashing, Committing, Pulling and Fetching, etc.

Because this document was never originally intended for public release, it contains a couple of figures from the Atlassian Git Tutorial that need replaced.

Command Aliases

The following aliases are defined in my ~/.zshrc file. They are a sub-selection of those defined in prezto’s Git module.

Command Description
gia git add
gcm git commit --message
gf git fetch
gfm git pull (remember that pull = fetch + merge)
gfr git pull --rebase
gp git push
gwd git diff (w = working directory)
gws git status --ignore-submodules=${_git_status_ignore_submodules}
gs git stash
gsl git stash list
gsp git stash pop

Cloning

Command Description
git clone <repo_addr> Clone a repository from <repo_addr>. Assumes repository does not contain submodules.
git clone --recurse-submodules <repo_addr> Clone a repository and all of its submodules

Editing

Editing files and undoing changes.

Git keeps track of differences between the current state of a file and it’s last commit

Looking for Changed Files

Command Description
git status See an inventory of changed, staged, and committed files
git diff <master_branch> <remote_branch> Compare a local branch with its remote branch. View the difference as both the names of the changed files and the differences within the files.
git diff --name-status <master_branch> <remote_branch> Compare a local branch with its remote branch. View the difference as the names of the changed files. Example: git diff --name-status master upstream/master

Undoing changes

Command Description
git checkout -- <file> Discard all changes to a single file permanently.
git reset --hard Discard all changes to all files permanently. Includes staged files.
git stash Discard all local changes to all files, but save them for possible re-use later. See Sec. ‘Stashing’ for detail.

Staging

The staging area (also called the index) is the holding location for all changes that you want committed. You can add and remove files from the staging area so that your commit includes exactly the changes you want to include.

Add Files to Staging

Command Description
git add <file1> <file2> ... Stage file(s). Save all changes in <file1>, <file2> for the next commit.
git add <directory> Stage all files under directory <directory> for the next commit.
git add -A Stage all files (new, modified, deleted). Equivalent to git add .
git add . Stage all files (new, modified, deleted). Equivalent to git add -A.

Remove Files from Staging

Command Description
git reset HEAD <file> Remove a single file from staging, but do not discard changes.
git reset Remove all files from staging, but do not discard changes.

Stashing

Stashing saves the modifications you’ve made to one or more local files for later reuse, and then reverts those files to match the HEAD commit (your last committed change).

Command Description
git stash Stash all files, i.e. save all changes since your last commit for possible re-use and then revert those files to HEAD.
git stash push <path> Stash a single file. Use instead of git stash save which is depreciated.
git stash push "message" <path> Stash a single file with a message.
git stash list List all stash entries
git stash pop Apply the last stash (first-in, first-out) and remove the stash from your list of stashes.
git stash pop N Apply specific stash N and remove the stash from your list of stashes.
git stash apply Apply the last stash and but do not remove the stash from your list of stashes.
git stash drop N Drop a specific stash, e.g. git stash drop 0
git stash clear Clear all saved stashes.

Committing

Committing Changes and Undoing Committing Changes

Command Description
git commit -m "My message" Commit (record) changes to the (local) repository with message “My message”.
git commit Commit changes to the repository. Bring up the preferred text editor to write the commit message. Commit will automatically occur after saving the message and exiting the editor.
git reset --soft HEAD~1 Reset (undo) the most recent local commit, assuming the commit hasn’t been pushed

Amending the Last Commit

The git commit --ammend command allows one to modify the most recent commit by replacing it with an entirely new commit with its own reference. The mistake won’t be visible in your history.

Be careful when doing this to public commits. You could possibly replace a commit that other developers have based their work upon.

If you want to modify multiple or older commits, use git rebase.

Example 1: You committed, but made a mistake in your commit log message.

As long as nothing has been staged, run:

git commit --amend -m "an updated commit message"

Example 2: You forgot to add a file to your last commit

After staging the missing file, run:

git commit --amend --no-edit

This will add the missing file without changing the commit message.

Pulling and Fetching

Command Description
git fetch <remote> Fetch all the branches from the <remote> repository
git fetch <remote> <branch> ` Fetch a single branch <branch> from the ` repository
git pull <remote> Fetch the remote copy of the current branch, then create a local merge commit containing the content of the diverged remote commit. Typically used in the sequence: git pull <remote> then git merge origin/<current-branch>
git pull --rebase <remote> Fetch the remote copy of the current branch and append the commits on top of the local commit history. This does not create a new commit. See Fig. 2.
Recommendation: For most uses, git pull --rebase is preferred to git pull.
git push -u origin <bname> Push local <bname> to to (remote) origin and track the remote branch (so e.g. you can use the argument-less git pull). -u is short for --set-upstream

Difference Between Git and Git Rebase

Figure 1: Git Pull Example. Figure taken from the [Git
Pull](https://www.atlassian.com/git/tutorials/syncing/git-pull) section
of the [Atlassian Git
Tutorial](https://www.atlassian.com/git/tutorials/learn-git-with-bitbucket-cloud){#fig:git-pull}

Figure 2: Git Pull Rebase Example. Figure taken from the [Git
Pull](https://www.atlassian.com/git/tutorials/syncing/git-pull) section
of the [Atlassian Git
Tutorial](https://www.atlassian.com/git/tutorials/learn-git-with-bitbucket-cloud){#fig:git-pull-rebase}

Examples

Example: Merge a branch into master

git checkout master     # Switch to the 'master' branch
git pull origin master  # Make sure the branch is up to date
git merge <bname>       # Merge the <bname> branch
git push origin master  # Push changes to origin/master

Merging and Rebasing

Merging

Command Description
git merge <bname> Merge the branch <bname> into the current branch (usually the master branch). To merge a branch into the master branch, see the example below this table.

Rebasing

Rebasing is the process of moving of moving or combining a sequence of commits to a new base commit.

There are two types of rebasing: standard mode and interactive mode.

In standard mode, you automatically take the commits of the current branch and apply them to the base branch of interest, usually master.

In interactive rebase, you can alter and change individual commits. You can remove, split, or alter commits allowing you to alter your own history before committing. Develops like this because they can develop a feature and then polish their development history before committing.

For additional information, see Atlassian’s ‘git rebase’ tutorial

Command Description
git rebase <base> Rebase the current branch into the head of branch <base>. Automatic standard mode rebase.
git rebase --interactive <base> Interactively rebase the current branch into the head of branch <base>. -i is equivalent to --interactive.

Interactive rebase will launch an editor window, showing the history of commits.

Interactive rebase editing
session{fig:git-rebase-interactive}

This is the point where you can

After exiting the editor, Git will proceed through each of the commits from the top of the commit history to bottom, acting as instructed by the verb in front of each commit (e.g. pick, reword, etc.). By default, they are all pick (use the commit without stopping) but they can be changed.

The full list of options:

Command Description
p, pick <hash> Use commit
r, reword <hash> Use commit, but edit the commit message
e, edit <hash> Use the commit, but stop for editing
s, squash <hash> Use the commit, but meld into previous commit
f, fixup <hash> Like “squash”, but discard this commit’s log message
x, exec <command> Run command (the rest of the line) using shell
b, break <hash> Stop here (continue rebase later with git rebase --continue)
r, drop <hash> remove commit
l, label <label> label current HEAD with a name
t, reset <label> reset HEAD to a label
m, merge <hash> Create a merge commit using the original merge commit’s message (or the onlne, if no original merge commit was specified). Use -c to reword the commit message.

Either the short form or long form of the verb can be used (e.g. p or pick)

After exiting the editor, the repository will be in rebase mode. You will have to manually address each commit in the commit history that was editing from pick to a new verb.

Reword

git commit --amend
git rebase --continue

To see the difference between the addressed commit.

Working with Branches

Get Information on Local and Remote Branches

Command Description
git branch Show all local branches
git branch -r Show all remote branches
git branch -a Show all remote and local branches
git remote update origin --prune Update the local list of remote branches

Create a Local Branch

Command Description
git branch <bname> Create a new local branch called <bname>
git checkout -b <bname> Create and checkout (switch to) local branch <bname>.

Checkout a Branch

Command Description
git checkout <bname> Checkout branch <bname>. If the branch does not exist and exactly maches a branch name on a single remote, Git will create a local tracking branch. This intelligent, shortened command can be used instead of the explicit command below.
git checkout --track origin/<bname> Checkout a local branch from a remote- tracking branch to create a local tracking branch.

Delete a Branch

Command Description
git branch -d <bname> Delete local branch <bname>. -d is equivalent to --delete.
git branch -D <bname> Force delete local branch <bname>. -D is equivalent to --delete --force.
git push origin -d <bname> Delete remote branch <bname>. -d is equivalent to --delete.

Viewing History

View Commit Differences

Command Description
git show --name-status Get basic information on your last commit: commit message, date, commit message, and modified files.
git diff HASH Get the difference between the latest commit and the specific commit given by HASH. Commit hashes can be found using commit log.
git diff HASH~ HASH Show the difference between commit HASH and the proceeding commit.
git show HASH Show the difference between commit HASH and the proceeding commit, plus commit details (message, author, date).

View Text Log

Command Description
git log See the entire commit history
git log -n See the last n commits
git log --oneline See compact commit history log with IDs.
git log <file> See commit history for a single file

View Graphical Log

Command Description
git log --graph Terminal graphical view of all branches
git log --graph --decorate --oneline Compact, terminal graphical view of all branches
gitk Launch the Git repository browser application.

Submodules

Updating a submodule or multiple submodules

Command Description
git submodule update --init Update a single submodule (from within the submodule)
git submodule update --recursive --remote Update all submodules from within the enclosing parent folder

Remove a Submodule

There are three steps to removing a submodule:

Step 1: Tell Git you no longer care about a submodule

git submodule deinit -f -- <path/to/submodule>

There will no longer be an attempt to update a submodule during a git submodule update call, and the submodule.<name> section will be removed from the .git/config file.

This step does not remove the submodule from the working tree however.

Step 2: Remove the submodule from the working tree

git rm -f <path/to/submodule>

Using git rm instead of just rm removes the submodule from the working, the Git link from the Index, and the submodule.<submodule_name> section from the .gitmodules file. If you delete a submodule using just rm -rf and then re-add the submodule, it won’t be possible. The repository will have been corrupted.

Step 3: Remove the residual .git/module/<path-to-submodule> directory

rm -rf .git/modules/<path-to-submodule>

git rm -rf leaves the submodule section in .git/modules/path/to/submodule/. Remove it explicitly.

Cleaning up the Repository

Command Description
git clean -f Remove all untracked files (e.g. temporary vim files, temporary HTML files I’ve created from markdown text, etc.)
git rm --cached <file> Stop tracking file <file>. Needed, for example, when we add a file to .gitignore that had previously been tracked.

Troubleshooting

Permission Denied (Public Key)

Problem: A Git remote action (push, clone, pull, etc.) fails with a Permission Denied error, but public/private keys have been added.

Solution: On macOS, this can occur because the private key has not been added to macOS’s SSH authorization agent (ssh-agent). The ssh-agent holds private keys and their passphrases for public key authentication.

ssh-add -K ~/.ssh/path_to_privatekey/id_rsa

The -K flag is unique to macOS systems and when included adds the private key’s passphrase in macOS Keychain.

On current macOS versions (10.14 and above), the keys added via ssh-add do not persist between logins. The following should be added to your ~/.ssh/config file:

Host *
  AddKeysToAgent yes
  UseKeychain yes

Another useful command:

ssh-add -A

Get the Authentication Agent to load all keys whose passphrases are stored on Keychain.

Glossary

index

A single large file in ./.git/index. It lists all files in the current branch, their SHA1 checksums, timestamps, and their file names.

local repository

The hidden directory .git containing the history of every file

origin

An alias on your system for a particular remote repository.

By convention, the name is origin, although it could be any arbitrary name.

workspace

The directory tree of all files you can see and edit

working tree

The working directory

Files that you are currently working on.