Li Zhang
6 min readSep 27, 2020


Git cheatsheet

Reference Resource

Fork and Pull workflow

  • The way the Fork & Pull works is that anyone can Fork a repository and make changes locally. They don’t have the ability to push their potentially damaging code. They can however request that host repository pull their changes if they would like using a Pull Request. (This is a very common workflow in the open source community.)
  1. git remote add upstream
  2. git fetch upstream
  3. git merge upstream/master # merges files on github with my local files
  4. If I think my changes should be merged with the original repository I can make a Pull Request. Click on Compare, review, create a pull request on GitHub.
  5. The owner of the original repository can see how many Pull Requests they have received on the right side of the screen.

Creating mutilple github accounts

  1. create another ssh key for a completely new account on Github
  • ssh-keygen -t rsa -C "Your Email Address" # Generates the key
  1. Give it a name (e.g. xinyixiao)
  2. A public key and randomart are generted again
  3. copy public key to github for setting
  4. We used a unique name for our keys so we have to tell ssh about them.
  • ssh-add ~/.ssh/xixaoxinyi ssh-add ~/.ssh/xinyixiao
  1. touch ~/.ssh/config
  2. define which account we want to work with by associating a keyword to our two different hosts.
User xiaoxinyi IdentifyFile ~/.ssh/xiaoxinyi

HostName github-aliyun
User xinyixiao IdentifyFile ~/.ssh/xinyixiao
  1. git remote add origin git@github-aliyun:xinyixiao/git-aliyun.git
  2. git push origin master

git clone

#clone a specific branch
git clone -b <branch> <remote_repo>

git branch

# create a new branch
git branch feature
# switch to feature branch
git chechout feature
# push branch feature to remote
git push origin feature
# show all braches both locally and remotely
git branch -a
# delete merged branch
git branch -d feature
# delete unmerged branch
git branch -D feature
# delete remote branch
git push --delete origin feature

git add

# add only  modified files
git ls-files --modified | xargs git add

git checkout

# pull a remote branch and create the same local branch
git checkout --track origin/raychar

git cherry-pick

# Copy branch to another branch
git cherry-pick hash

git diff

# diff unstaged files with last commit
git diff

# diff staged files with last commit
git diff --cached

git log

# most used log command
git log --oneline --decorate --all --graph

git merge

# Discard current merge
git merge --abort

# merge branch
git merge branch

# merge non fast forward
git metge --no --FF

git ref

push branch different names

Refspecs can be used with the git push command to give a different name to the remote branch. For example, the following command pushes the master branch to the origin remote repo like an ordinary git push, but it uses qa-master as the name for the branch in the origin repo

git push origin master:refs/heads/qa-master

non-fast-forward update remote repository

A refspec is specified as [+]:. The parameter is the source branch in the local repository, and the parameter is the destination branch in the remote repository. The optional + sign is for forcing the remote repository to perform a non-fast-forward update.

delete remote branches

# use refspecs for deleting remote branches
git push origin :some-feature
git push origin --delete some-feature

fetch specific branched

By default, git fetch fetches all of the branches in the remote repository. The reason for this is the following section of the .git/config file

[remote “origin”]
url = <>
fetch = +refs/heads/\*:refs/remotes/origin/\*

To fetch only the master branch, change the fetch line to match the following

[remote “origin”]
url = <>
fetch = +refs/heads/master:refs/remotes/origin/master

if you want to always push the master branch to qa-master in the origin remote

[remote  “origin”] 
url = <>
fetch = +refs/heads/master:refs/remotes/origin/master
push = refs/heads/master:refs/heads/qa-master

git HEAD

# grandparent of HEAD
git show HEAD~2

# the first parent is from the branch that you were on when you performed the merge, and the second parent is from the branch that you passed to the git merge command.
# first parent merge second parent branch

# The ~ character will always follow the first parent of a merge commit. If you want to follow a different parent, you need to specify which one with the ^ character.

# if HEAD is a merge commit, the following returns the second parent of HEAD
git show HEAD^2

# Only list commits that are parent of the second parent of a merge commit
git log HEAD^2

# Remove the last 3 commits from the current branch
git reset HEAD~3

# Interactively rebase the last 3 commits on the current branch
git rebase -i HEAD~3

git rest

git reset --hard HEAD  # current commit
git reset --hard HEAD^ # parent commit
git reset --hard HEAD^^ # grandparet commit

# Remove the specified file from the staging area, but leave the working directory unchanged.
git reset <file>
# Reset the staging area to match the most recent commit, but leave the working directory unchanged.
git reset
# Reset the staging area and the working directory to match the most recent commit.
git reset --hard

git rm

# rm files from working space
git rm <file>

# untracked files but still in working space
git rm --cached <file>

git rev-parse

# The following returns the hash of the commit pointed to by the master branch
git rev-parse master

git show

# bring back deleted file from some version
git show commit_id:path/to/file > path/to/file

git stash

## By default, running git stash will stash:
# changes that have been added to your index (staged changes)
# changes made to files that are currently tracked by Git (unstaged changes)

## But it will not stash:
# new files in your working copy that have not yet been staged
# files that have been ignored

git stash # stash staged file and tracked but unstaged file
git stash -u # stash untrack file
git stash -a # stash ignore file

# Creating a branch from your stash
git stash branch add-style stash@{1}
# Cleaning up your stash
git stash drop stash@{1}
git stash clear

git stash list
git stash save "add style to our site"

# Viewing stash diffs
git stash show
git stash show -p

# Partial stashes
git stash -p

# rename existing stash

git stash drop stash@{1}
git stash store -m 'refactor virturalenvironment.h|m to virtualenvironment.hh|mm' 0beef13ff5a36dccfee1c58cf7ad1508df524771

# stash untracked files with a stash msg
git stash save -u 'untracked files examples/ARAppCore/VirtualEnvironment.hh|mm'

git submodule

git submodule add ../xx.git submod
git submodule update

git update-index

# This will tell git you want to start ignoring the changes to the file
git update-index --assume-unchanged path/to/file

# When you want to start keeping track again
git update-index --no-assume-unchanged path/to/file


# Ignoring a previously committed file
echo debug.log >> .gitignore
git rm --cached debug.log
git commit -m "Start ignoring debug.log"

# Global Git ignore rules
touch ~/.gitignore
git config --global core.excludesFile ~/.gitignore

# Committing an ignored file
git add -f debug.log
git commit -m "Force adding debug.log"

echo !debug.log >> .gitignore
git add debug.log
git commit -m "Adding debug.log"

# Debugging .gitignore files
git check-ignore -v debug.log


Pull wrong branch into master

git reflog  # find commit hash

git reset --hard <hash>

Create a remote branch and push

git push <remotename> <commit SHA>:refs/heads/<remotebranchname>

Git clone a specific directory from git repository

git init demo  # demo is a local directory

cd demo

git remote add origin repo.git

git config core.sparseCheckout true

echo "specific-dir/*" >> .git/info/sparse-checkout

git pull --depth=1 origin master

Change submodule’s url

git config --file=.gitmodules -l

# modify .gitmodules url
emacs .gitmodules

http 免密码

touch ~/.git-credentials
echo "http://username:password@" >> ~/.git-credentials
git config --global credential.helper store

git status 显示的中文文件乱码

git config --global core.quotepath false