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