Made a mistake once by running git reset --hard HEAD^
. All my commits are gone. To undo it, its' just run git reflog
. Git keeps a log of all ref updates (e.g., checkout, reset, commit, merge). You can view it by typing:
$ git reflog
To undo the commit:
$ git reset 'HEAD@{1}'
$ git reset --soft HEAD~1
$ du -hs
With git filter-branch
:
# pathname is the file to remove, commitHASH is the starting hash to traverse, else it will traverse from the first commit
$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch pathname' commitHASH
With bfg
:
# Installation
$ brew cask install java
$ brew install bfg
# Running bf, note it only cleans the commit history
$ bfg --delete-files *.mp4
$ bfg --replace-text passwords.txt
$ bfg --delete-folders .git
# Run this to remove the files
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
When replacing text, create a file called passwords.txt
for example for mapping the text to another pattern:
PASSWORD1 # Replace literal string 'PASSWORD1' with '***REMOVED***' (default)
PASSWORD2==>examplePass # replace with 'examplePass' instead
PASSWORD3==> # replace with the empty string
regex:password=\w+==>password= # Replace, using a regex
# n is the number of commits previously that you want to squash
$ git rebase -i HEAD~n
$ git rebase -i COMMIT_HASH
git reset
git checkout .
git clean -fdx
$ git rm -r --cached node_modules
$ git commit --amend
Select a commit from a different branch and add it as a new commit
$ git cherry-pick YOUR_COMMIT_HASH
$ git branch -m old-name new-name\
# or if you are in the same directory
$ git branch -m new-name
# Delete the old-name remote branch and push the new-name local branch.
$ git push origin :old-name new-name
# Reset the upstream branch for the new-name local branch. Switch to the branch and then:
$ git push origin -u new-name
$ git fetch origin
$ git reset --hard origin/master
$ git clean -f // clean local file
$ git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin
$ git fetch --all
# Then, you have two options:
$ git reset --hard origin/master
# OR If you are on some other branch:
$ git reset --hard origin/<branch_name>
$ git log -1
Output:
commit 706b92ba174729c6a1d761a8566a74f0a0bf8672 (HEAD -> master, origin/master)
Author: alextanhongpin <[email protected]>
Date: Sun Feb 11 23:57:57 2018 +0800
refactor: improve naming
(END)
Press Q
to exit.
$ git log -1 --pretty=%H
# Output
706b92ba174729c6a1d761a8566a74f0a0bf8672
$ git log -1 --pretty=%h
# Output
706b92b
$ echo $(git log -1 --pretty=%H)
NAME := acmecorp/foo
TAG := $$(git log -1 --pretty=%!H(MISSING))
IMG := ${NAME}:${TAG}
LATEST := ${NAME}:latest
build:
@docker build -t ${IMG} .
@docker tag ${IMG} ${LATEST}
push:
@docker push ${NAME}
login:
@docker log -u ${DOCKER_USER} -p ${DOCKER_PASS}
# Tag the repository
$ git tag -a v0.0.1 -m "version v0.0.1"
# Check
$ git describe
v0.0.1
# Perform a commit
$ git commit -am 'chore: do something'
$ git describe
v0.0.1-1-g9ba5c76
alias gst='git status'
alias gcm='git commit -S -am'
alias gco='git checkout'
alias gl='git pull origin'
alias gpom="git pull origin master"
alias gp='git push origin'
alias gd='git diff | mate'
alias gb='git branch'
alias gba='git branch -a'
alias del='git branch -d'
$ git config --get remote.origin.url
$ git ls-remote —get-url
# Use this.
$ git remote get-url origin
# https://github.com/alextanhongpin/go-github-scraper-sg.git
$ basename $(git ls-remote --get-url) .git
$ basename `git remote get-url origin` .git
# go-github-scraper-sg
# View other configs that can be used
$ git config -l
$ git config --get user.name
# alextanhongpin
# Alternative is whoami, but this will return the name of the personal user, not the github username.
$ git push origin --delete branchname
- feat: A feature that is visible to end users
- fix: A bugfix that is visible for end users
- chore: A change that doesn’t impact end users (e.g .changes to CI Pipeline)
- docs: A change in the README or documentation
- refactor: A change in production code focused on readability, style and / or performance
$ git remote update --prune
$ git branch -D $(git branch)
Find out what are the latest branch in progress.
$ git fetch --prune
$ git branch —sort=-committerdate
http://karma-runner.github.io/4.0/dev/git-commit-msg.html https://365git.tumblr.com/post/3308646748/writing-git-commit-messages https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html https://dev.to/maxpou/enhance-your-git-log-with-conventional-commits-3ea4 https://seesparkbox.com/foundry/semantic_commit_messages
$ git branch —-merged
$ git branch —-no-merged
# cleanup unnecessary files and optimise the local repository (compact your repo)
$ git gc
# prune all unreachable object from the object database
$ git prune
# verifies the connectivity and validity of the objects in the database (validate that your repo is sane)
$ git fsck
# (prune your remote working directory)
$ git remote update --prune
- Checkout to the branch you want to rename $ git checkout old-name
- Rename branch name locally: $ git branch -m
- Delete old branch from remote: $ git push origin
- Reset the upstream branch for the new branch name: $ git push origin -u new-name
$ git config --global push.followTags true
git restore -s <SHA1> -- <filename>
git restore -s somebranch -- <filename>
E.g. To download the folder https://github.com/alextanhongpin/pkg/tree/master/authheader
:
# Replace tree/master with trunk
$ svn export https://github.com/alextanhongpin/pkg.git/trunk/authheader
You can add an alias to ease the creation of docker-compose
templates in projects:
alias init-db=svn export https://github.com/alextanhongpin/docker-samples/trunk/postgres/docker-compose.yml
Ensure you have a changelog edited in your current branch. Currently there's no way to find out what is the first commit from the current branch, unless I refer to the original branch where it originated from. Usually it will be main/master
, but probably a better way to do it is to write another script to find the origin.
#!/bin/bash
if [[ $(git diff develop -- CHANGELOG.md | wc -l) -eq 0 ]];then
echo "Don't forget to add CHANGELOG.md"
exit 1;
fi
$ git rebase -X theirs ${branch} # Short option
https://stackoverflow.com/questions/2945344/how-do-i-select-a-merge-strategy-for-a-git-rebase
$ touch .git/hooks/post-checkout
$ chmod u+x .git/hooks-post-checkout
The .git/hooks/post-checkout
:
#!/bin/bash
# The post-checkout hook receives three parameters
# $1: Ref of previous head
# $2: Ref of new head
# $3: Whether this is a file checkout (0) or branch checkout (1).
# This is a file checkout - do nothing
if [ "$3" == "0" ]; then exit; fi
BRANCH_NAME=$(git symbolic-ref --short -- HEAD)
NUM_CHECKOUTS=`git reflog --date=local | grep -o ${BRANCH_NAME} | wc -l`
# If the refs of the previous and new heads are the same
# and the number of checkouts equals one, a new branch has been created
if [ "$1" == "$2" ] && [ ${NUM_CHECKOUTS} -eq 1 ]; then
echo "new branch created"
else
echo switched branch ${BRANCH_NAME}
fi
Useful when you screw up and wants to revert back the original file.
$ git checkout $(git rev-parse master) -- path-to-file
$ git add --all # Add your changes
$ git commit --amend # Apply to the last commit
# NOTE: You need to force push the commit to origin if it has been pushed
You are already working on the branch and the commits are messy. You want to recreate the branch with commits that are arranged nicely.
Say if you are working on branch feature/foo
:
# Create a new temp branch.
$ git checkout -b feature/foo-tmp
# Create the patch file for all new changes on that branch relative to your main branch
$ git diff origin/feature/foo origin/main > out.patch
# Apply all the changes to this branch
$ git apply out.patch
# Do your rebase magic, git patch or git add -i
...
# Once you are done, drop the old branch
$ git branch -D feature/foo
# Rename the current branch.
$ git branch -m feature/foo
# Force push the changes if necessary
$ git push +feature/foo
Use git push --force-with-lease
.
https://stackoverflow.com/questions/52823692/git-push-force-with-lease-vs-force
$ touch 1.md
$ echo 1 > 1.md
$ gcmsg 'first commit'
$ touch 2.md
$ echo 'Two\n2' > 2.md
$ gcmsg 'second commit'
# Now, update 1.md to 'One\n1'
$ echo 'One\n1' > 1.md
# Get the first commit hash
$ git log -n 2
$ git commit --fixup <first-commit-hash>
# There should be 3 entries now
$ git log -n 3
# We want to squash the 3rd commit into the first by using git rebase --autosquash
# However, git rebase requires the parent, and the first commit does not have a parent
# So we use the --root option instead
$ git rebase -i --fixup --root