Git CheatSheet

Cherry-pick

NOTE: cherry-pick from current to another branch is impossible, you always need to checkout!

# pick the commit from "feature" branch to "main" branch
git checkout main
git cherry-pick abc123

# pick multiple non-consecutive commits
git cherry-pick abc123 def456 ghi789

# pick a range of commits
git cherry-pick abc123..def456

# resolve conflicts (if occur)
git cherry-pick --continue

# Abort the cherry-pick
git cherry-pick --abort

Stash

By default git SKIP untracked or ignored files for stash.

# Stash modified/staged files
git stash

# Stash modified/staged/untracked files
git stash -u

# Stash modified/staged/untracked/ignored files
git stash -a

# Stash modified/staged files with message
git stash save "stash message"

# Show all available stashes
git stash list

# Get stash to working gir & delete the stash (last or specified)
git stash pop
git stash pop stash@{1}

# Get stash to working gir, but not delete the stash  (last or specified)
git stash apply
git stash apply stash@{1}

# Recover dropped stash (you need to know it's hash)
git stash apply [stash-hash]

# Delete stash (last or specified)
git stash drop
git stash drop stash@{1}

# Show stash diff (last or specified)
git stash show
git stash show stash@{1}

# Show all details (the patch)
git stash show -p stash@{1}

# Create branch from stash & delete stash (last or specified)
git stash branch [branch-name]
git stash branch [branch-name] stash@{1}

Remote, Fetch, Pull, Push

Retrieving updates from another repository and updating local repos

# Add a git URL as an alias
git remote add [alias] [URL]
git remote add origin [email protected]:owner/repo.git

# Fetch down all branches from remote repo
git fetch
# or with alias
git fetch origin

# Fetch and delete remote branches locally (if it does not exist on remote)
git fetch --prune

Pull

# Fetch and merge commits from the current tracking remote branch
git pull

# Fetch with --prune and merge
git pull --prune

# Pull only if it can be “fast-forwarded” (without creating new commits)
git pull --ff-only

# fetch specified branch
git fetch origin [branch]:[branch]

Push

# push current branch to linked upstream
git push

# push current branch and set tracking (reference for the current branch)
git push --set-upstream origin [branch]
git push -u origin [branch]

# Push local branch commits to remote branch
git push origin [branch]

# Force push (with changing history)
git push origin [branch] --forse   =   git push [alias] +[branch]

Merge, Rebase

Merge

# merge the specified branch’s history into the current one
git merge [branch]

# merge the specified branch’s history into the current one
# fail if linear history fails
git merge [branch] --ff-only

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

Rebase

# Rebase the current branch onto the specified branch,
# which means the commits from the current branch will be
# reapplied on top of the specified branch
git rebase [branch]

# Interactive Rebase all commits that go before specified one (using hash)
git rebase -i 972078a

# Interactive Rebase last 3 commits (using offset)
git rebase -i HEAD~3

# Interactive Rebase starting from zero commit (root)
git rebase -i --root

Doc: https://git-scm.com/docs/git-rebase

Checkout, Branch

checkout

# Switch to another branch and check it out into your working directory
git checkout [branch-name]

# Create branch on your local machine and checkout to it:
git checkout -b [new-branch-name]

switch

# Create a local branch from the fetched remote branch (Git 2.23+)
git switch [branch-name]

# In this case Git is guessing that you are trying to checkout
# and track the remote branch with the same name.
# This can be disabled with --no-guess
git switch [branch-name] --no-guess

# -c to create a new local branch
git switch -c [local-branch-name] origin/[remote-branch-name]

branch

# Show all local branches
git branch

# Show all local branches & last commit message
git branch -v

# Show branches & related remote branch (upstream) & last commit
git branch -vv

# Show all remote branches
git branch -r
git branch --remotes

# Show local & remote branches
git branch --all
# List branches available for checkout
git branch -v -a

# Show of branches that already was merged with current
git branch --merged

# Show of branches that not merged with current
git branch --no-merged

# Create a new branch at the current commit
git branch [branch-name]

# Rename branch
git branch --move [old-branch-name] [new-branch-name]

# Relate remote and current branches
git branch --set-upstream-to=origin/[branch-name]
git branch -u origin/[branch-name]

Delete (remove) branch:

# Delete local branch only if it was fully merged
git branch -d [branch-name]

# Force delete local branch
git branch -D [branch-name]

# Delete branch from remote repo
git push origin --delete [branch-name]
# Or a short variant
git push origin :old_branch

add, commit, status, log, show

commit

# commit your staged content as a new commit snapshot
git commit -m "your commit message"

# add & commit
git commit -am "your commit message"

# Append current changes to last commit
git commit --amend

# Append current changes to last commit (adds changes files too)
git commit -a --amend

# Append current changes to last commit (take massage from last commit)
git commit -a --amend --no-edit

# Create empty commit
git commit --allow-empty -m 'create branch'

status

# show modified files in working directory, staged for your next commit
git status

diff

# diff of what is changed but not staged
git diff

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

# show the diff of what is in branchA that is not in branchB
git diff branchB...branchA

show

# show changes of the last commit
git show

# show any object in Git in human-readable format
git show [SHA]

log

# show commits in the current branch’s history
git log

# see the git log of a specific branch
git log <branch-name>

# Show all tree (even if HEAD is detached to another commit)
git log --all

# Show only last 5 commits
git log --oneline -n5

# show the commits on branchA that are not on branchB
git log branchB..branchA

# display the commit history of a specific file,
# tracing its changes even if it has been renamed or moved
git log --follow [file]

# Show compact
git log --oneline

# Show tree
git log --graph
git log --graph --oneline

add

# Stage all repo files (not from .gitignore)
git add .

# Stage all changes in <directory> for the next commit.
git add [directory]

# Stage all changes in <file> for the next commit.
git add [file]

Tagging

# list all tags
git tag
git tag -l
git tag --list

# see tag data along with the commit that was tagged
git show v1.4

# search for tags that match a particular pattern
git tag -l "v1.8.5*"

# create a simple tag (holds only commit)
git tag v1.4

# create an annotated tag  (holds commit and tag data)
git tag -a v1.4 -m "Version 1.4"

# create a tag later for commit 9fceb02
git tag -a v1.2 9fceb02

# push tag
git push origin v1.5

# push all tags
git push origin --tags
git push --tags

# delete tag (local only)
git tag -d v1.4

# delete tag remotely
git push origin --delete v1.4

# checkout the tag commit
git checkout v1.4

clone, init (create repo)

# Create Git repo in current folder
git init
git init <project name>

# Create remote repo in current folder by URL
git clone <URL>

# Copy remote repo in specified folder by URL
git clone <URL> <folder>

# Copy remote repo with only specified branches
git clone -b <branch_name> --single-branch <URL>

# Copy remote repo with only specified branches in specified folder
git clone -b <branch_name> --single-branch <URL> <folder>

# Copy remote repo with 5 commits last only (limit history)
git clone <URL> --depth=5 <folder>

config - (settings, setup, option)

Remote

# view remote URLs
git remote -v

# add remote repo (takes two arguments)
git remote add origin [email protected]:USERNAME/REPOSITORY.git

# change a remote repository's URL (takes two arguments)
git remote set-url origin [email protected]:USERNAME/REPOSITORY.git

# rename a remote repository (takes two arguments)
git remote rename origin my_name

More: https://docs.github.com/en/get-started/getting-started-with-git/managing-remote-repositories

List

# Show all settings
git config --list
# Or see files: `~/.gitconfig` (user wide) `.git/config` (repo wide)

# Show global options only
git config --global --list

# Show system options only
git config --system --list

# Show options and files where they defined (global, user, repo, etc...)
git config --list --show-origin

Get

# Show option value
git config user.name
# or
git config --get user.name

# Show option value and file where it places
git config --show-origin user.name

# Show option value from specified scope
git config --system user.name

Set

# Set exact setting
git config --global user.name "[Kama]"
git config --global user.email "[[email protected]]"

# Set automatic command line coloring for Git for easy reviewing
git config --global color.ui auto
# Set `core.autocrlf=true` in global scope
git config --global core.autocrlf true

# Set system wide .gitignore patern for all repos
git config --global core.excludesfile [file]

Remove / Unset

# Remove option from repo scope
git config --unset user.name

# Remove option from global scope
git config --global --unset user.name

Tracking (rm mv)

# delete the file from project and stage the removal for commit
git rm [file]

# Remove single file from git stage
git rm --cached www/.env

# change an existing file path and stage the move
git mv [existing-path] [new-path]

Revert

# Creates new commit in which all changes of another commit will be reverted
git revert 0ad5a7a6

# Revert by modifying your working tree and index without creating a commit
git revert -n 0ad5a7a6
git revert --no-commit 0ad5a7a6

# The target commit is 2 commits behind HEAD on the current branch
git revert HEAD~2

# Revert a set of Git commits, between two revisions.
# The older commit should come first, followed by the newer commit.
# Revert these two commits, plus every commit in between them.
git revert HEAD~5..HEAD~2

# Revert merge and leave only 1 parent
git revert -m 1 HEAD
git revert --mainline 1 HEAD

Reset

reset

git reset   =   git reset --mixed HEAD

git reset HEAD
git reset [hash]

# reset last two commits
git reset HEAD~2

# reset all: commit history, stage snapshot, working dir
git reset --hard [hash]

# reset: commit history, stage snapshot
git reset --mixed [hash]

# reset: commit history
git reset --soft [hash]

# unstage a file, but retaining the changes in working dir
git reset [file]

reflog

# log of all ref updates (e.g., checkout, reset, commit, merge)
git reflog

# undo the specified operation
git reset HEAD@{1}
git reset d27924e

Grep (serach)

# Search "search_query" in working dir
git grep -n search_query

# Find commits where ZLIB_BUF_MAX exists
git log -S ZLIB_BUF_MAX --oneline

# Search with Regex
git log -G regex --oneline

Submodules

https://git-scm.com/docs/git-submodule

# initializes all the submodules which have been added to the project
# but not initialized yet. In other words, this sets up the submodule
# project to be fetched and updated.
git submodule update --init

# provides information about your submodules. Shows the current commit
# that each submodule is on, including an optional short status if any
# of the commits have not been checked out.
git submodule status

# go into your submodules and fetch and update them to the latest commit
# on their main branch (pull the latest changes from the remote repository).
# checkout submodules to the latest commit on the branch specified in
# .gitmodules file. For example if new commits have been made to the submodule
# remote repo you can call "update --remote" to get those new changes.
git submodule update --remote

# checkout all submodules to the expected commit - commit that currently
# specified for submodule (it may be in .gitmodules file). For example
# if your .gitmodules file has been changed to specify a different commit
# then calling "update" makes the submodule checkout that commit.
git submodule update

# Update specific submodule
git submodule update --remote path/to/submodule

# Unregister specified submodule in git. And Clears submodule folder (files)
# leaves only one file with hash (dir).
git submodule deinit path/to/submodule  # eg: git submodule deinit wp-content/plugins/nwp-agegate
# Unregister all submodules
git submodule deinit --all

-

See: https://education.github.com/git-cheat-sheet-education.pdf