Git Command Reference

This page is a non-exhaustive and growing reference of popular git commands and tips. Note: Do not include the < > brackets around the actual branch names, etc., they are used in the examples below to indicate a place holder.

Add

# add / removes all
git add .

# use `-n` to do a dry run
git add -n .

Amend

# combine any staged changes with the contents of the previous commit
git commit --amend

# same as above and change the commit message
git commit --amend -am "my new commit message"

Branch

# list local branches
git branch

# list remote and local branches
git branch -a

# list remote branches
git branch -r

# rename current branch
git branch -m <newname>

# rename a local branch
git branch -m <oldname> <newname>

# push a new local branch to remote and track
git push -u origin <branchname>

Clone

Cloning is the first step when getting a repository from the server.

# download the repository into the current directory
git clone <url>

# download the repository into the current directory with a sub directory name you supply
git clone <url> <directory>

Checkout

# checkout and create new branch
git checkout -b <branchname>

# the new branch head will point to <startpoint>
# <startpoint> can be a branchname, remote-alias/branchname, commithash or tag
git checkout -b <branchname> <startpoint>

# copy file from another branch
git checkout <branchname> -- <filename>

# checkout a tag to a new branch
git fetch origin
git checkout tags/<tagname> -b <branchname>

# restore file deleted locally that still exist on remote
git checkout -- <filename>

Cherry Pick

# merge a specific commit into the current branch
git cherry-pick <commithash>

Config

# set email for repo
cd path/to/repo
git config user.email "gilfoyle@piedpiper.com"

# set username for repo
cd path/to/repo
git config user.name "gilfoyle"

# confirm
git config user.email
git config user.name

# git config --global core.excludesfile [file]
git config --global core.excludesfile somefile

In Git version 2.16+, git command output is sent to the editor. To change this, set pager.branch false. more info

# set paged output for git branch to off
git config --global pager.branch false

Delete

# delete local branch
git branch -d <branchname>

# delete remote branch
git push origin :<branchname>

# Git 1.7+
git push origin --delete <branchname>

Diff

# diff of what is changed but not staged
git diff

# diff of what is staged but not yet commited
git diff --staged

# diff between two local branches
git diff branch_a..branch_b

# write the diff to a file
git diff branch_a..branch_b > C:\diff.txt

# common ancestor diff
git diff branch_a...branch_b

Notes

  • Press q to exit diff
  • You can also add a file or folder name after the commands

Fetch

# checkout a remote branch that does not exist on local
git fetch origin
git checkout --track origin/<remote branch name>

# checkout a remote branch to a new local branch
git fetch origin <remote branch name>:<local branch name>

Init

# initialize an existing directory as a Git repository
git init

Log

# commit logs for the active branch.
git log

# list commits on branchA that are not on branchB
git log branchB...branchA

# list commits that changed a file
git log  --follow somefile

# not in origin
git log origin..HEAD

# one line
git log --pretty=oneline

# last commit only with truncated hash
git rev-parse --short HEAD

# find in commit messages
git log --oneline | grep sometext

# list commit logs with indication of any paths that moved
git log --stat -M

# show any object in Git in human-readable format
git show <SHA>

Notes

  • git log outputs with the less program, making it scrollable. Type q to exit. Type h for help.
  • origin..HEAD specifies all the commits reachable from the current commit (i.e. HEAD), but not from origin.

Pull

# fetch and merge any commits from the tracking remote branch
git pull

# get rid of 'your branch is ahead of origin <branchname> by X commits
git pull origin <branchname>

Rebase

# reapply commits on top of another base tip
git rebase

# squash four commits into one
git rebase -i HEAD~4

Here’s an easy way to non-interactively merge the last X commits into the first. In this example, we’re merging the last 3 commits into commit 1.

# note that this is HEAD-2, not HEAD-3
git reset --soft HEAD~2

# this automatically uses `commit 1` message
git commit --amend -C HEAD

Notes

  • Squash info: Git Book Chapter 6.4: Git Tools - Rewriting History. The editor will list the 4 commits starting with the oldest. Replace the word “pick” with “squash” next to each commit you want to squash into the commit before it.
  • Editor: press i to enter inline insert mode. Use the delete key to erase from left to right, press esc to exit insert mode, then type :x (now the cursor is at the bottom) and hit enter to save and exit.
  • You can edit your last commit message before pushing with git commit --amend

If you’ve already pushed commits to GitHub, and then squash them locally after, you will have to force the push to your branch.

git push origin <branchname> --force

Reset

# can be used to undo previous uncommitted add(s)
git reset

# unstage a file while retaining the changes in working directory
git reset somefile

# reset to previous state
git reset --hard

# reset to previous commit
git reset --hard <commit hash>

# reset to origin
git reset --hard origin/<branchname>

git reflog to show what has been done with git session

Rm

# remove unstaged changes, e.g., added file or files
# note `-r` is needed to recurse
git rm -r --cached .

git rm --cached somefile

Stash

Temporarily store modified, tracked files in order to change branches

# stash changes in a dirty working directory
git-stash

# remove and apply stash
git-stash pop

# list stashes
git stash list

# apply stash
git-stash apply

# remove a stash
git stash drop <stashid>

Tag

# add a lightweight tag to by specifying the
# commit checksum (or part of it) at the end of the command
git tag sometagname ed40a9deaa0
git push origin sometagname

# delete a tag
git tag -d sometagname
git push origin :refs/tags/sometagname

Working with Forks

Forks are a concept created by GitHub. On a standard git server, the equivalent would be like cloning a repo to a git server and then cloning it from that server to your local computer. Then add the original repo as the upstream from the local computer.

Scenario, you attempt to fetch upstream and get fatal: 'upstream' does not appear to be a git repository. e.g.,

git fetch upstream
fatal: 'upstream' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

You will need to configure a remote that points to the upstream repository. for example, add a remote with the alias, upstream to your repo:

git remote add upstream https://github.com/wodby/docker4wordpress.git

# verify
git remote -v

Syncing a fork

Fetch the branches from the upstream repository.

git fetch upstream

Merge upstream branches using git merge upstream/<branchname>. e.g., merge master branch into your local fork master:

git checkout master

git merge upstream/master

Creating a Fork From GitHub to GitLab or Bitbucket

If you just want to track changes, first make an empty repository in GitLab, Bitbucket or whatever else you may be using and clone it to your computer.

Then add the GitHub project by declaring an alias named upstream using remote add, e.g.,

git remote add upstream https://github.com/user/repo

This will allow you to fetch and pull from the upstream repo. e.g.,

# fetch
git fetch upstream master

# pull
git pull upstream master

When there are any changes, you can fetch and pull them from the respective branch. Given your permissions on the upstream repo, you may also be allowed to push or merge.

To get the upstream branch you pulled onto your GitLab, Bitbucket, etc. server, and then merge that into your master branch and push to origin. Use this example,

# switch to origin master
git checkout master

# merge the upstream alias master into your master
git merge upstream/master

# push to your origin repo master branch
git push

GitLab also has repository mirroring to allow the mirroring of repositories to and from external sources. It can be used to mirror branches, tags, and commits between repositories.

Tips & Tricks

Share & Update

Retrieving updates from another repo and updating local repo

# clean up deleted remote git branches
git remote prune origin

# add a git URL as an alias
git remote add <alias> <url>

# fetch down all the branches from that Git remote
git fetch <alias>

# merge a remote branch into your current branch to bring it up to date
git merge <alias>/<branch>

# transmit local branch commits to the remote repository branch
git push <alias> <branch>

Discard changes / commits

# discard local changes for all unstaged file
git checkout -- .

# discard local commits
git reset --hard origin/<branchname>

Merge Repositories

Merge repo_a into repo_b

cd path/to/repo_b

git remote add repo_a path/to/repo_a

git fetch repo_a

git merge repo_a/master

git remote remove repo_a

Merge a branch from another repository into a branch in a different local repository. For two repositories, foo and bar located in the current directory, this example merges master from bar into a new branch in foo.

cd foo

# add the bar repo to foo
git remote add bar ../bar

# fetch --all from remote
git remote update

# create a new branch in foo
git checkout -b barmaster

# merge master from bar into the new branch
git merge bar/master

since git 2.9 you can use the option --allow-unrelated-histories with git merge

Change Remote Origin

When the remote origin repository has been renamed, the URL needs to be reset.

List existing remotes to get the address format, ssh or https of the remote to change.

Example

git remote -v
origin	git@bitbucket.org:gilfoyle/gilfoylehacks.git (fetch)
origin	git@bitbucket.org:gilfoyle/gilfoylehacks.git (push)

Use git remote set-url to change the origin url. e.g.,

git remote set-url origin git@bitbucket.org:gilfoyle/gilfoylehacks2.git

Another example - suppose you cloned a repo on GitHub using https and you’re ready to push changes up to the remote origin. You might receive this message output after entering your username and password:

remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.

In addition to updating your configuration to connect to GitHub with SSH, you will need to change the remote from HTTPS to SSH, For example,

git remote set-url origin git@github.com:gilfoyle/gilfoylehacks.git

Git Basics - Working with Remotes

Clone into an existing folder?

This can’t be done, however, workaround by cloning to a new directory, then moving the .git directory into the existing directory.

git clone https://gitlab.com/myrepo.git temp

# move .git from temp to myrepo directory
mv temp/.git myrepo/.git

# delete temp directory
rm -rf temp

Remove Commits after Specified Commit

If for some reason you need to remove recent commits, you can force a push to reset the origin to a particular commit hash. This will remove any commits that were pushed after it that commit hash.

git push origin +<commithash>:<branchname>

# for example
git push origin +ed40a9deaa0:master

The + is interpreted as forced push.

Another way to do the same thing is with git reset. For example,

# reset to previous commit in current branch
git reset --hard <commit hash>

# force push
git push origin -f

SSH Keys

How to create ssh keys for multiple git accounts on a the same host. Generate a ssh key pair for each account using the respective e-mail address associated with it.

ssh-keygen -t rsa -b 4096 -C "username@example.com"

When you’re prompted to “Enter a file in which to save the key,” Edit the filename so the key pair can be mapped to the account. e.g., id_rsa_gitlab

Enter a file in which to save the key (/Users/you/.ssh/id_rsa_gitlab): [Press enter]
ssh-agent
# start the ssh-agent
eval $(ssh-agent -s)

# add the key
ssh-add ~/.ssh/id_rsa_gitlab

More info: Generating a new SSH key and adding it to the ssh-agent

Create a Config file

touch ~/.ssh/config

Edit the config file to map the ssh key to its unique Host value. For example, github.com for the personal account and github.com-work for the work account. e.g.,

.ssh/config
# github personal
Host github.com
    HostName github.com
    User richard.hendricks
    IdentityFile ~/.ssh/id_rsa_github

# github work account
Host github.com-work
    HostName github.com
    User richard.hendricks@piedpiper.com
    IdentityFile ~/.ssh/id_rsa_github_piedpiper

Host gitlab.com
    HostName gitlab.com
    User richard.hendricks
    IdentityFile ~/.ssh/id_rsa_gitlab

Clone repos using the unique host value. e.g.,

git clone git@github.com-work:githubaccount/somerepo.git

This will set the repo’s .git/config remote origin as needed. e.g.,

[remote "origin"]
    url = git@github.com-work:githubaccount/somerepo.git

Additional Resources

comments powered by Disqus