Skip to content

Instantly share code, notes, and snippets.

@hicaro
Last active December 15, 2020 15:25
Show Gist options
  • Save hicaro/eaf1280d84a69eeb48934f99c1a05f61 to your computer and use it in GitHub Desktop.
Save hicaro/eaf1280d84a69eeb48934f99c1a05f61 to your computer and use it in GitHub Desktop.
Git useful commands
# create new branch
git branch <branch name>
# create new branch and checkout to it
git checkout -b <branch name>
# upload new branch to remote
git push origin <branch name>
# delete local branch
git branch -d <branch name>
# delete remote branch
git push origin :<branch name>
# show branch mapping local/remote
git remote show origin
# remove stale remote branches
git remote prune origin
# remove merged branches
git branch --merged | egrep -v "(^\*|master|develop)" | xargs git branch -d
# merge a specific commit from a branch to another
git checkout <target branch>
git cherry-pick <hash>
# --edit: changes the message
# --no-commit <hash1> <hash2>: pulls in changes and stages them, but does not commit
# -x: adds source SHA to commit message
# --signoff: adds current users's name to commit message
# change CRLF to LF on commit - Unix-like systems
git config --global core.autocrlf input
# change LF to CRLF on checkout and converts back on commit
git config --global core.autocrlf true
# difference between HEAD and previous commit
git diff HEAD^
# difference between HEAD and 5 commits ago
git diff HEAD~5
# difference between HEAD and specific commit
git diff <hash>
# difference between 2 commits
git diff <hash> <another hash>
# difference between two branches
git diff <branch> <another branch>
# difference between two tagged commits
git diff <tag> <another tag>
# purging history
# make a backup before changing history
git clone <repo> <new repo>
# for each commit in the specified branch, apply filters to the snapshot, and create a new commit
# filter for rewriting the tree and its contents
git filter-branch --tree-filter <command>
# remove "passwords.txt" from project root
git filter-branch --tree-filter "rm -f passwords.txt"
# remove video files from any directory
git filter-branch --tree-filter "find . -name
# filter for rewriting the index - operates on staging area
git filter-branch --index-filter <command>
# remove "passwords.txt" form staging area
git filter-branch --index-filter "git rm --cached --ignore-unmatch passwords.txt"
# ome filters will generate empty commits that leave the tree untouched.
# this option instructs git filter-branch to remove such commits if they have exactly one or zero non-pruned parents
git filter-branch -f --prune-empty -- --all
# Log options
# %ad - Author date
# %an - Author name
# %h - SHA hash
# %s - Subject
# %d - Ref names
git log --pretty=format:"%h %ad - %s [%an]"
# filter logs by date range
git log --since=1.month.ago --until=2.weeks.ago
# branch to be rebased
git checkout <branch name>
# target is the branch that will be used as base for rebasing
git rebase <target branch>
# interactive rebase - option -i or --interactive
git rebase -i <target branch>
# p, pick - use commit
# r, reword - use commit, but edit its message
# e, edit - use commit, but stop for amending
# s, squash - use commit, but meld it into previous commit
# f, fixup - like 'squash', but discard this commit's log message
# x, exec - run command (the rest of the line using shell)
# reference logs, or "reflogs", record when the tips of branches and other references were updated in the local repository
git reflog <subcommand> <options>
# reset based on reflog entry
git reset --hard HEAD@{#}
# reset basically moves the HEAD pointer to another commit behind it
# and updates Index and Working Directory, depending on the used flag
# undo last commit and add files back to staging area -> undo `git commit`
# Step 1: `--soft` simply changes the HEAD pointer, no changes on the `Index` or `Working Directory`,
# which is the reason why the files show in the stagging area (Files in HEAD != Files in Index)
git reset --soft HEAD~
# undo last commit and unstage changes -> undo `git commit` and `git add`
# Step 2: `--mixed` (default) will change the commit HEAD points to
# and update the `Index` with the contents of whatever `HEAD` now points to so they're the same.
git reset [--mixed] HEAD~
# undo last commit and discard files -> undo `git commit`, `git add`, and discard changes
# Step 3: `--hard` will, besides updating the HEAD and updating the `Index`,
# update the `Working Directory` with whatever is in the updated `Index`
# this flag is the most dangerous one for reset, once it overwrites the content of the `Working Directory`
git reset --hard HEAD~
# reset with a path -> undo `git add`
# if a path is provided, reset will skip the Step 1, once we'll be working with subsets of a commit
# and apply the other 2 steps, updating `Index` with whatever is in `HEAD`.
# it does not accept `--hard` -> use `git checkout <hash> file.txt` instead
git reset [--mixed] [HEAD] file.txt
# if a specific commit hash is given, reset will update `Index` with the content of `file.txt` existing in that commit
git reset [--mixed] <hash> file.txt
# replace message from and/or add more changed to last commit
git commit --amend -m "<new message>"
# Notation:
# Both ~ and ^ on their own refer to the parent of the commit (~~ and ^^ both refer to the grandparent commit, etc.)
# But they differ in meaning when they are used with numbers:
# * ~2 means up two levels in the hierarchy, via the first parent if a commit has more than one parent
# * ^2 means the second parent where a commit has more than one parent (i.e. because it's a merge)
# store un-commited files (needs to be added to staging area - only gets tracked files)
git stash [save | push]
# --include-untracked: all untracked files are also stashed
# --all: ignored files are stashed in addition to the untracked files
# --keep-index: stashed files and leaves them in the staging area - same as git stash; git stash apply
# restore previous stash entry - #0 is default
git stash apply [stash@{#}]
#list stashed items
git stash list --stat
# remove stash entry
git stash drop [stash@{#}]
# permorm apply followed by drop - git stash apply; git stash drop
git stash pop
# show the changes recorded in the stash entry as a diff between the stashed contents and the commit back when the stash entry was first created
git stash show [stash@{#}]
# --patch: shows file's diffs
# check a new branch out automatically and drops the stash entry
git stash branch <branch name> [stash@{#}]
# remove all stash entries
git stash clear
# add a repo as a internal submodule
git submodule add <url>
# when changing submodules code, checkout a branch first
# when cloning a repo with submodules do:
git submodule init
git submodule update
# merge commits with no branch
git checkout <branch>
git merge <hash> # no-branch commit's hash
# pushing submodules
# first push /submodule repo
# then push parent repo
# abort a push if submodules haven't been pushed
git push --recurse-submodules=check
# psuh parent and submodule commits
git push --recurse-submodules=on-demand
# create an alias
git config alias.pushall "push --recurse-submodules=on-demand"
# add tag
git tag <tag name>
# upload tags to remote
git push --tags
# list tags
git tag -l
# delete local tag '<tag name>'
git tag -d <tag name>
# delete remote tag '<tag name>'
git push origin :refs/tags/<tag name>
# alternative approach
git push --delete origin <tag name>
git tag -d <tag name>
# delete all local tags
git tag -l | xargs git tag -d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment