appoint
Copy br = branch
co = checkout
coa = commit --amend --no-edit
pl = !git --no-pager log --color --graph --pretty=tformat:'%C(red)%h%C(reset) -%C(yellow)%d%C(reset) %s %C(green)(%cr) %C(blue)<%an>%C(reset)' --abbrev-commit --date=relative --max-count=3
pls = log --color --graph --pretty=tformat:'%C(red)%h%C(reset) -%C(yellow)%d%C(reset) %s %C(green)(%cr)%C(reset) %C(blue)<%an>%C(reset)' --abbrev-commit --date=relative
fpl = log --color --graph --pretty=tformat:'%C(red)%H%C(reset) -%C(yellow)%d%C(reset) %s %C(green)(%cr)%C(reset) %C(blue)<%an>%C(reset)' --abbrev-commit --date=relative
fl = log -p --graph --color --graph
rlog = "!bash -c 'while read branch; do \n\
git fetch --all --force; \n\
git pl remotes/origin/$branch; \n\
done < <(git rev-parse --abbrev-ref HEAD) '"
commit exclusions
^<rev>
(caret) notation :
To exclude commits reachable from a commit, a prefix ^
notation is used.
E.g. ^r1 r2
means commits reachable from r2 but exclude the ones reachable from r1 (i.e. r1 and its ancestors)
dotted range notations
..
(two-dot) range notation
r1..r2
: commits that are reachable from r2 excluding those that are reachable from r1 by ^r1 r2
...
(three-dot) symmetric difference notation
r1...r2
: called symmetric difference of r1 and r2
It is the set of commits that are reachable from either one of r1 (left side) or r2 (right side) but not from both
commit
get revision number
[!TIP|label:the <value>
can be:]
Copy $ git rev-parse < valu e > ^{commit}
# i.e.:
$ git rev-parse HEAD
e06b245740ac0c73f9454b6d96758e3a4a804901
get abbrev commit ids
[!NOTE|label:references:]
format:
%h
: abbreviated commit hash
rev-list
Copy $ git rev-list HEAD -n 3 --abbrev=11 --abbrev-commit
446c656814d
e747154df34
22d0ee9b131
# or via `git log`
$ git log -n 3 --format= '%h' --abbrev=11
# or
$ git log -3 --format= '%h' --abbrev=11
446c656814
e747154df3
22d0ee9b13
rev-parse
Copy $ git rev-parse --short HEAD
# or
$ git rev-parse --short=7 HEAD
# i.e.:
$ git rev-parse --short HEAD
e06b24574
$ git rev-parse --short=7 HEAD
e06b245
get previous commit id
Copy $ git rev-list --no-walk < commit-i d > ^
get next commit id
[!NOTE] references:
Copy $ git rev-list --no-walk < commmit-i d > ..HEAD | tail -1
branch
full branch name
Copy $ git symbolic-ref HEAD
refs/heads/main
# [or](https://stackoverflow.com/a/62340432/2940319)
$ git rev-parse --symbolic-full-name HEAD
refs/heads/main
branch name
Copy $ git branch --show-current
main
# or
$ git rev-parse --abbrev-ref HEAD
main
# or
$ git symbolic-ref --short HEAD
main
# or
$ git symbolic-ref --quiet --short HEAD || git rev-parse --short
main
# or
$ git symbolic-ref HEAD | sed -e "s/^refs\/heads\///"
main
# [or](https://stackoverflow.com/a/33485172/2940319)
$ git name-rev --name-only HEAD
main
Copy $ git st
HEAD detached at d4beb6ac
...
$ git branch --no-color \
--remote \
--verbose \
--no-abbrev \
--contains |
sed -rne 's:^[^/]*/([^\ ]+).*$:\1:p'
marslo/sandbox
# or
$ git branch --no-color \
--remote \
--verbose \
--no-abbrev \
--contains |
sed -rne 's:^[ \s]*origin/([^\ ]+).*$:\1:p'
or
Copy $ git name-rev --name-only HEAD |
sed -rne 's:^[ \s]*([^\]+/){2}([^~]+).*$:\2:p'
# or
$ git name-rev --name-only HEAD |
sed -rne 's:^[ \s]*remotes/origin/([^~]+).*$:\1:p'
create empty branch
create an empty branch
Copy $ mkdir < MY_FOLDE R > && cd $_
$ git init
$ git remote add origin < REMOTE_UR L >
$ git fetch --all --progress --force
$ git checkout -b < BRANCH_NAM E >
push to remote
Copy $ git add --all .
$ git commit -m 'inital an empty branch'
$ git push --force -u origin HEAD: < BRANCH_NAM E >
git alias .gitalias
:
Copy [alias]
init-repo = "!f() { \
declare help=\"\"\"\
USAGE: git init-repo <REMOTE_URL> [DEFAULT_BRANCH] [LOCAL_DIR] \n\
OPT: \n\
REMOTE_URL: mandatory \n\
DEFAULT_BRANCH: optinal. default is 'master' \n\
LOCAL_DIR: optional. default is current directory: '\"$( pwd )\"' \n\
\"\"\"; \
declare remoteURL=\"$1\"; \
declare defaultBr='master'; \
declare localDir='.'; \
[ 2 -le $# ] && defaultBr=\"$2\"; \
[ 3 -eq $# ] && localDir=\"$3\"; \
if [ 0 -eq $# ] || [ 3 -lt $# ]; then \
echo \"${help}\"; \
else \
[ -d ${localDir} ] || mkdir -p ${localDir}; \
cd ${localDir} ; \
git init && \
git remote add origin ${remoteURL} && \
git fetch --all --force --quiet && \
git checkout -b ${defaultBr}; \
fi \
}; f \
"
get branch name from reversion
branch -a --contians
Copy $ git branch -a --contains a3879d3
* master
remotes/origin/master
# or
$ git branch -r --contains a3879d3
origin/master
name-rev
Copy $ git name-rev a3879d3
a3879d3 master~12
get upstream branch
get current
Copy $ git rev-parse --abbrev-ref --symbolic-full-name @{u}
origin/marslo
# or
$ git for-each-ref --format= '%(upstream)' $( git symbolic-ref -q HEAD )
refs/remotes/origin/marslo
# or for `meta/config`
$ git symbolic-ref -q HEAD
refs/heads/meta/config
$ git for-each-ref --format= '%(upstream)' $( git symbolic-ref -q HEAD )
refs/remotes/origin/meta/config
$ git for-each-ref --format= '%(upstream:short)' $( git symbolic-ref -q HEAD )
origin/meta/config
# [or](https://stackoverflow.com/a/49418399/2940319)
$ git status -bsuno
## master...origin/master
get specific
Copy $ git rev-parse --abbrev-ref gh-pages@{upstream}
origin/gh-pages
# or
$ git for-each-ref --format= '%(upstream:short)' $( git rev-parse --symbolic-full-name meta/config )
origin/meta/config
local
Copy $ git for-each-ref --format= '%(refname:short)' refs/heads/
remote
Copy $ git for-each-ref --format= '%(refname:short)' refs/remotes/origin/
references:
Copy $ git config --global branch.sort -committerdate
Copy $ git for-each-ref --sort=-committerdate refs/heads/
# or using git branch (since version 2.7.0)
$ git branch --sort=-committerdate # DESC
$ git branch --sort=committerdate # ASC
advanced usage
Copy $ git for-each-ref \
--sort=-committerdate \
refs/heads/ \
--format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'
for remote
Copy $ git for-each-ref --sort=-committerdate refs/remotes
more on git tips
Copy git-list-branches-by-date () {
local current_branch = $( git rev-parse --symbolic-full-name --abbrev-ref HEAD )
local normal_text = $( echo -ne '\E[0m' )
local yellow_text = $( echo -ne '\E[0;33m' )
local yellow_bg = $( echo -ne '\E[7;33m' )
git for-each-ref --sort=-committerdate \
--format= $' %(refname:short) \
\t%(committerdate:short)\t%(authorname)\t%(objectname:short)' \
refs/heads \
| column -t -s $'\t' -n \
| sed -E "s:^ (${current_branch}) :* ${yellow_bg}\1${normal_text} :" \
| sed -E "s:^ ([^ ]+): ${yellow_text}\1${normal_text}:"
}
gitalias
Copy [alias]
sb = "! git branch --sort=-committerdate --format='%(HEAD) %(color:red)%(objectname:short)%(color:reset) - %(color:yellow)%(refname:short)%(color:reset) - %(subject) %(color:bold green)(%(committerdate:relative))%(color:reset) %(color:blue)<%(authorname)>%(color:reset)' --color=always"
recent = "! f() { \
declare help=\"USAGE: git recent [remotes|tags] [count]\"; \
declare refs; \
declare count; \
if [ 2 -lt $# ]; then \
echo \"${help}\"; \
exit 1; \
else \
if [ 'remotes' = \"$1\" ]; then \
refs='refs/remotes/origin'; \
elif [ 'tags' = \"$1\" ]; then \
refs='refs/tags'; \
elif [ 1 -eq $# ]; then \
count=$1; \
fi; \
if [ 2 -eq $# ]; then \
count=$2; \
fi; \
fi; \
git for-each-ref \
--sort=-committerdate \
${refs := 'refs/heads'} \
--format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) %(color:green)(%(committerdate:relative))%(color:reset)' \
--color=always \
--count=${count := 5}; \
}; f \
"
[!NOTE|label:reference:]
check refs
Copy $ git status
warning: ignoring broken ref refs/remotes/origin/HEAD
$ git symbolic-ref refs/remotes/origin/HEAD
refs/remotes/origin/new_master
fix warning
Copy $ git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/new_master
# or
$ git remote set-head origin --delete
$ git remote set-head origin --auto
# or
$ git fetch --all --force
$ git remote set-head origin refs/remotes/origin/new_master
get first parent branch
[!NOTE|label:references:]
tag
lightweight VS. annotated
show tags details
Copy # + - commit: lightweight tag
# + - tag: annotated tag
# |
# +-----+
$ git for-each-ref refs/tags
902fa933e4a9d018574cbb7b5783a130338b47b8 commit refs/tags/v1.0-light
1f486472ccac3250c19235d843d196a3a7fbd78b tag refs/tags/v1.1-annot
fd3cf147ac6b0bb9da13ae2fb2b73122b919a036 commit refs/tags/v1.2-light
show tag type via git cat-file -t
Copy # lightweight
$ git cat-file -t v1.0-light
commit
# annotated
$ git cat-file -t v1.1-annot
tag
or
Copy $ git show-ref -d --tags |
cut -b 42- | # to remove the commit-id
sort |
sed 's/\^{}//' | # remove ^{} markings
uniq -c | # count identical lines
sed 's/2\ refs\/tags\// a /' | # 2 identicals = annotated
sed 's/1\ refs\/tags\//lw /'
status
list ignored
[!NOTE|label:references:]
status
Copy $ git status --ignored
On branch master
Your branch is up to date with 'origin/master' .
Ignored files:
( use "git add -f <file>..." to include in what will be committed )
bin/
nothing to commit, working tree clean
# short status
$ git status --ignored --short
!! bin/
$ git status --porcelain --ignored
!! bin/
$ git st --ignored --untracked-files=all
## master...origin/master
!! bin/cfssl
!! bin/cfssl-bundle
!! bin/cfssl-certinfo
!! bin/cfssl-newkey
!! bin/cfssl-scan
!! bin/cfssljson
!! bin/mkbundle
!! bin/multirootca
check-ignore
Copy $ git check-ignore *
bin
$ git check-ignore -v *
.gitignore:4:bin bin
$ git check-ignore -v $( find . -type f -print )
.gitignore:4:bin ./bin/cfssl-scan
.gitignore:4:bin ./bin/cfssl-certinfo
.gitignore:4:bin ./bin/cfssl-bundle
.gitignore:4:bin ./bin/cfssl
.gitignore:4:bin ./bin/cfssl-newkey
.gitignore:4:bin ./bin/multirootca
.gitignore:4:bin ./bin/mkbundle
.gitignore:4:bin ./bin/cfssljso
$ find . -not -path './.git/*' | git check-ignore --stdin
./bin
./bin/cfssl-scan
./bin/cfssl-certinfo
./bin/cfssl-bundle
./bin/cfssl
./bin/cfssl-newkey
./bin/multirootca
./bin/mkbundle
./bin/cfssljson
$ find . -path ./.git -prune -o -print | git check-ignore --no-index --stdin --verbose
.gitignore:4:bin ./bin
.gitignore:4:bin ./bin/cfssl-scan
.gitignore:4:bin ./bin/cfssl-certinfo
.gitignore:4:bin ./bin/cfssl-bundle
.gitignore:4:bin ./bin/cfssl
.gitignore:4:bin ./bin/cfssl-newkey
.gitignore:4:bin ./bin/multirootca
.gitignore:4:bin ./bin/mkbundle
.gitignore:4:bin ./bin/cfssljson
ls-files
Copy $ git ls-files --others --ignored --exclude-standard
# or
$ git ls-files -o -i --exclude-standard
bin/cfssl
bin/cfssl-bundle
bin/cfssl-certinfo
bin/cfssl-newkey
bin/cfssl-scan
bin/cfssljson
bin/mkbundle
bin/multirootca
# or list only directories
$ git ls-files --others --ignored --exclude-standard --directory
bin/
# or from `.gitignore` file
$ git ls-files --ignored --others --exclude-from=.gitignore
bin/cfssl
bin/cfssl-bundle
bin/cfssl-certinfo
bin/cfssl-newkey
bin/cfssl-scan
bin/cfssljson
bin/mkbundle
bin/multirootca
clean
Copy $ git clean -ndX
Would remove bin/
log
short stat
Copy $ git log --show-signature
# or
$ git log --shortstat
show renamed status
Copy $ git log -M --summary | grep rename
# or
$ git log -M --summary | grep -E '^\s*rename.*{.*=>.*}'
show files and status without comments
Copy $ git log --color --stat --abbrev-commit --date=relative --graph --submodule --format= "%H"
more
Copy # or
$ git log --color --stat --abbrev-commit --date=relative --graph --submodule --format= "%h %ad- %s [%an]"
# or
$ git log --color --stat --abbrev-commit --date=relative --graph --submodule --format='%C(red)%h%Creset %C(yellow)(%ad)%Creset %s %C(blue)<%an>%Creset'
e.g.:
Copy $ git log -3 --color --stat --abbrev-commit --date=relative --graph --submodule --format= "%H"
* 50ede51fcc3cf0311fd85b3e9c4a36d4beb89e69
|
| devops/git/gerrit.md | 6 ++++--
| devops/git/git.md | 5 +++++
| 2 files changed, 9 insertions ( + ) , 2 deletions ( - )
* 41d58dabcd0aaee33edd1de7793ffd82c7cffa89
|
| SUMMARY.md | 2 +-
| 1 file changed, 1 insertion ( + ) , 1 deletion ( - )
* 4460a32d8fddbe7c5c434947aea153273ce215d4
|
| devops/git/ {gitStudy.md = > git.md} | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
| 1 file changed, 116 insertions ( + ) , 1 deletion ( - )
show submodule changes
Copy $ git submodule status
$ git log -- < submodule nam e >
get change from .git/objects
Copy $ find .git/objects -type f -printf "%P\n" | sed s,/,,
get change history for deleted files
full-history
Copy $ git log --all --full-history -- < path/to/fil e >
or
Copy $ git log --all --full-history --oneline -- < path/to/fil e >
or
Copy $ git log --oneline --follow -- < path/to/fil e >
or
Copy $ git log --diff-filter=D --summary | find "delete" | grep < filenam e >
--follow
Copy $ git log --follow < path/to/fil e >
Copy $ git log -S 'add' --oneline -3
6f7877c2 update git for fetch more refs after cloned via --single-branch, and add tricky for vim
30ce195e add jenkins plugin jira-steps
913a7f29 update jenkins recommended plugins
or
Copy # -p, --paginate
# Pipe all output into less (or if set, $PAGER) if standard output is a terminal. This overrides the
# pager.<cmd> configuration options (see the "Configuration Mechanism" section below)
$ git pls -S 'add' -p
Copy $ git log --grep= 'jira' --oneline
30ce195e add jenkins plugin jira-steps
d17dd3aa add jira api
or
Copy $ git pls --grep='jira'
rebase
[!TIP]
automatic edit by git rebase -i
inspired from .gitconfig & Is there a way to squash a number of commits non-interactively?
Copy $ COUNT=$1
$ GIT_EDITOR="sed -i -e '2,$COUNT s/^pick /s /;/# This is the 2nd commit message:/d'" git rebase -i HEAD~$COUNT
git alias
Copy [alias]
sq = ! "f() { TARGET=$1 && GIT_EDITOR=\"sed -i -e '2,$TARGET s/^pick /s /;/# This is the 2nd commit message:/,$ {d}'\" git rebase -i HEAD~$TARGET; }; f"
or
Copy $ GIT_SEQUENCE_EDITOR="sed -i 's/^pick ce5efdb /edit ce5efdb /;/^pick ce6efdb /d'" git rebase -i ${SHA}
or edit
Copy $ GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick 134567/e 1234567/'" git rebase -i 1234567^
or sequence.editor
Copy $ git -c sequence.editor='sed -i s/pick/reword/' rebase -i ${SHA}
.gitconfig
Copy [alias]
arebase = ! ~/.marslo/bin/arebase.sh
~/.marslo/bin/arebase.sh
Copy #!/bin/bash
ACTION=$1
COMMIT=$(git rev-parse --short $2)
[[ "$COMMIT" ]] || exit 1
CORRECT=
for A in p pick r reword e edit s squash f fixup d drop t split; do
[[ $ACTION == $A ]] && CORRECT=1
done
[[ "$CORRECT" ]] || exit 1
git merge-base --is-ancestor $COMMIT HEAD || exit 1
if [[ $ACTION == "drop" || $ACTION == "d" ]]; then
GIT_SEQUENCE_EDITOR="sed -i -e '/^pick $COMMIT/d'" git rebase -i $COMMIT^^
elif [[ $ACTION == "split" || $ACTION == "t" ]]; then
GIT_SEQUENCE_EDITOR="sed -i -e 's/^pick $COMMIT/edit $COMMIT/'" git rebase -i $COMMIT^^ || exit 1
git reset --soft HEAD^
echo "Hints:"
echo " Select files to be commited using 'git reset', 'git add' or 'git add -p'"
echo " Commit using 'git commit -c $COMMIT'"
echo " Finish with 'git rebase --continue'"
else
GIT_SEQUENCE_EDITOR="sed -i -e 's/^pick $COMMIT/$1 $COMMIT/'" git rebase -i $COMMIT^^
fi
Copy $ EDITOR="sed -i -e 's/borken/broken/g'" GIT_SEQUENCE_EDITOR="sed -i -e 's/pick/reword/g'" git rebase -i --root
or:
Copy $ VISUAL="sed -i -e '/^[[:blank:]]*Change-Id/ d'" GIT_SEQUENCE_EDITOR="sed -i -e 's/pick/reword/g'" git rebase -i --root
or:
Copy $ GIT_EDITOR="sed -i -e 's/kyewrod/keyword/g'" GIT_SEQUENCE_EDITOR="sed -i -e 's/pick/reword/g'" git rebase -i --root
undo
delete only the latest commit
Copy $ git push origin +<hash_for_delete>^:<branch>
# e.g.:
$ git pl --pretty=format:"%h" --no-patch
* cb46bdc
* 936543c
* a83ac6b
# delete cb46bdc
$ git push origin +cb46bdc^:master
delete multiple commits
revert local
Copy $ git reset --hard HEAD~
# or
$ git reset --hard HEAD^^^
# or
$ git reset --hard <commit_hash>
# or
$ git rebase -i HEAD~<n>
push to remote
Copy $ git push [--force] origin +<branch>
# e.g.:
$ git push [--force] origin +master
revert deleted branches
[!TIP] references:
Copy # find the HEAD of deleted branch
$ git log --graph --decorate $(git rev-list -g --all)
$ git checkout <sha>
$ git checkout -b /branch/name
or find out recent actions
Copy $ git reflog --no-abbrev
or find all losts
Copy $ git fsck --full \
--no-reflogs \
--unreachable \
--lost-found |
grep commit |
cut -d\ -f3 |
xargs -n 1 git log -n 1 --pretty=oneline
revert single file to remotes
Copy $ git checkout origin/<branch> -- <path/to/file>
revert changes in submodule
Copy $ git submodule update -f --init
or
Copy $ git submodule foreach --recursive git reset --hard
or
Copy $ git submodule update -f --recursive
or
Copy $ git submodule foreach --recursive git reset --hard
$ git submodule update --recursive --init
Command Scope Common use cases Discard commits in a private branch or throw away uncommited changes
Switch between branches or inspect old snapshots
Discard changes in the working directory
Undo commits in a public branch
change comments in remote
Copy $ git pl
* a79d384 - (HEAD -> master, origin/master, origin/HEAD) update (11 seconds ago) <marslo>
* 7cef7c7 - update (7 hours ago) <marslo>
* e1d7a64 - update (7 hours ago) <marslo>
# change comments on a79d384
$ git commit --amend
$ git push --force-with-lease origin master
# result
$ git fetch --all --force
$ git pl remotes/origin/master
Fetching origin
* ba49259 - (HEAD -> master, origin/master, origin/HEAD) update a79d384 for change comments (24 seconds ago) <marslo>
* 7cef7c7 - update (7 hours ago) <marslo>
* e1d7a64 - update (7 hours ago) <marslo>
Copy $ git rebase -i HEAD~<n>
And then change pick
to reword
example
Copy $ git pls
* 1e7d979 - (HEAD -> master, origin/master, origin/HEAD) f (24 seconds ago) <marslo>
* 9b89ed7 - c (40 seconds ago) <marslo>
* beb575f - d (51 seconds ago) <marslo>
* 25d010d - e (57 seconds ago) <marslo>
* c502e34 - b (64 seconds ago) <marslo>
* 8890288 - init commit (4 minutes ago) <Marslo Jiao>
$ git rebase -i HEAD~5
reword c502e34 b
pick 25d010d e
pick beb575f d
reword 9b89ed7 c
pick 1e7d979 f
$ git push --force origin master
# or
$ git push origin +master
Copy $ git rebase -i --root
$ git push origin +<branch>
change author and committer
rebase and amend
go to interactive mode
Copy $ git config --local user.name "name"
$ git config --local user.email "name@email.com"
$ git rebase -i <sha>
amend one by one
Copy $ git commit --amend --no-edit --only --author="name<name@email.com>"
# or
$ git commit --amend --no-edit --date="$(git log -n 1 --format=%aD)" --reset-author
$ git rebase --continue
rebase --onto
[!TIP] see also
Copy [alias]
reauthor = !bash -c 'git rebase --onto $1 --exec \"git commit --amend --author=$2\" $1' --
Copy $ git config --local user.name "name"
$ git config --local user.email "<name@email.com>"
$ git rebase --no-edit \
--onto HEAD~9 \
--exec 'GIT_COMMITTER_DATE="$(git log -n 1 --format=%aD)" \
git commit --amend \
--date="$(git log -n 1 --format=%aD)"' \
--author="name<name@email.com>" \ # or --reset-author
HEAD~9'
-x '-CHEAD'
[!TIP]
Copy $ git rebase -i BASE_SHA^ -x \
"git commit --amend --author 'John Doe <johndoe@example.com>' -CHEAD"
check commits with author
Copy # get commits by name
$ git log --oneline --author="name"
# get commits by email
$ git log --oneline --author="<name@email.com>"
mv
case sensitive
error with regular git mv
Copy $ git config --global core.ignorecase true
$ git mv Tig tig
fatal: renaming 'confs/home/Tig' failed: Invalid argument
renmae
Copy $ git mv Tig temp
$ git aa
$ git mv temp tig
$ git aa
$ git st
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: Tig/.tig/marslo.tigrc -> tig/.tig/marslo.tigrc
renamed: Tig/.tigrc -> tig/.tigrc
renamed: Tig/.tigrc_latest -> tig/.tigrc_latest
renamed: Tig/tigrc_2.4.1_1_example -> tig/tigrc_2.4.1_1_example
renamed: Tig/tigrc_Marslo -> tig/tigrc_Marslo
clean
clean untracked directory and item in .gitignore
quick generate .gitignore
Copy # show result
$ curl -skL https://www.gitignore.io/api/groovy
# download
$ curl -skL https://www.toptal.com/developers/gitignore/api/groovy,java,python,go -o .gitignore
using -f
twice if you really want to remove such a directory
Copy $ git st
On branch meta/config
Your branch is based on 'origin/meta/config', but the upstream is gone.
(use "git branch --unset-upstream" to fixup)
Untracked files:
(use "git add <file>..." to include in what will be committed)
my-sbumodule/
nothing added to commit but untracked files present (use "git add" to track)
$ git clean -dfx
Skipping repository my-submodule/
$ git clean -dffx
Removing my-submodule/
diff
diff-highlight
[!NOTE] references:
Copy # centos8
$ rpm -ql git | grep diff-highlight
/usr/share/git-core/contrib/diff-highlight
# or ubuntu
$ dpkg -L git | grep diff-highlight
$ sudo ln -sf /usr/share/git-core/contrib/diff-highlight /usr/local/bin/diff-highlight
Copy $ git log --left-right --graph --cherry-pick --oneline origin/<release>..origin/<dev>
or
Copy $ git rev-list --reverse \
--pretty="TO_TEST %h (<%ae>) %s" \
--cherry-pick \
--right-only origin/<release>...origin/<dev> \
| grep "^TO_TEST "
diff ignore whitespace
[!NOTE|label:references:]
ignore tab
[!TIP|label:tab-in-indent]
Copy $ git config core.whitespace '-tab-in-indent'
$ git diff HEAD^..
ignore tab-in-indent for *.config
and *.ltsv
only
Copy $ cat ~/.gitattributes
File: /Users/marslo/.gitattributes
1 *.config text diff=config whitespace=-tab-in-indent
2 *.ltsv text diff=ltsv whitespace=-tab-in-indent
ignore all
Copy $ git config core.whitespace '-trailing-space,-indent-with-non-tab,-tab-in-indent'
tag
reference :
discribe
Copy $ git describe --tags --long <revision>
# v2.5-0-gdeadbee
# ^ ^ ^^
# | | ||
# | | |'-- SHA of HEAD (first seven chars)
# | | '--- "g" is for git
# | '----- distance : number of commits since last tag
# |
# '---------- last tag name
Copy $ git describe HEAD --tags
or
Copy $ git describe HEAD --all --long
get revision in particular branch
Copy $ git tag -l --sort='creatordate' --merged <branch>
get latest tag
references:
Copy $ git tag -l --sort='creatordate' --merged <branch> | tail -1
or
Copy # the command can be executed in .git folder (! -is-inside-work-tree)
$ git describe --tags --abbrev=0 --always
or
Copy $ git for-each-ref --sort=taggerdate \
--format '%(tag)' \
refs/tags |
tail -1
to get verbose output
Copy $ git for-each-ref --sort=taggerdate \
--format '%(tag) %(taggerdate:raw) %(taggername) %(subject)' \
refs/tags
or
Copy $ git for-each-ref --sort=taggerdate \
--format '%(tag)_,,,_%(taggerdate:raw)_,,,_%(taggername)_,,,_%(subject)' \
refs/tags |
awk 'BEGIN { FS = "_,,,_" } ; { printf "%-20s %-18s %-25s %s\n", $2, $1, $4, $3 }'
or
Copy $ git log --tags \
--simplify-by-decoration \
--pretty="format:%ai %d" |
sort
or formatted date
Copy $ git for-each-ref --sort=taggerdate \
--format '%(tag)_,,,_%(taggerdate:raw)_,,,_%(taggername)_,,,_%(subject)' \
refs/tags |
awk 'BEGIN { FS = "_,,,_" } ; { t=strftime("%Y-%m-%d %H:%M",$2); printf "%-20s %-18s %-25s %s\n", t, $1, $4, $3 }'
or git alias
Copy tags = !"git for-each-ref \
--sort=taggerdate \
--format '%(tag)_,,,_%(taggerdate:raw)_,,,_%(taggername)_,,,_%(subject)' refs/tags \
| awk 'BEGIN { FS = \"_,,,_\" } ; { t=strftime(\"%Y-%m-%d %H:%M\",$2); printf \"%-20s %-18s %-25s %s\\n\", t, $1, $4, $3 }'"
get revision from latest tag in particular branch
Copy $ git rev-list -1 --no-patch $(git tag -l --sort='creatordate' --merged <branch> | tail -1)
Copy $ git tag --points-at <revision>
get tags for HEAD
:
Copy $ git tag --points-at HEAD
or
Copy $ git name-rev --tags --name-only $(git rev-parse <revision>)
example
Copy $ git name-rev --tags --name-only $(git rev-parse HEAD)
get tag and distance (depth)
reference:
man of git-describe
:
The hash suffix is "-g" + an unambigous abbreviation for the tip commit of parent.
The length of the abbreviation scales as the repository grows, using the approximate number of objects in the repository and a bit of math around the birthday paradox, and defaults to a minimum of 7.
Copy $ git describe --long --tags
v1.0.0-epsilon-2-g46b7ebb
| | + -g<has>
| + distance (commits on top)
+ tag name
# or
$ git describe --dirty --tags --long
v1.0.0-epsilon-2-g46b7ebb
| | | |
\___ ___/ | + commit hash of the current commit
most + commits on top
recent
tag
or --all
Copy $ git describe --all --long
Copy $ git describe --dirty --tags --long --match *nightly*
nightly#82-2001310818-1765-gc18894b193
[!TIP] prepend "-" to reverse sort order.
ascending : --sort=<type>
descending : --sort=-<type>
references:
via v:refname
or version:refname
by created data
Copy $ git for-each-ref --sort=creatordate --format='%(refname) %(creatordate)' refs/tags
# or
$ git tag --format='%(creatordate:short)%09%(refname:strip=2)' --sort=creatordate
# or
$ git for-each-ref --sort=taggerdate --format='%(tag) %(taggerdate) %(taggername) %(subject)' refs/tags
# much better
$ git for-each-ref --sort=taggerdate \
--format '%(tag)_,,,_%(taggerdate:raw)_,,,_%(taggername)_,,,_%(subject)' refs/tags |
awk 'BEGIN { FS = "_,,,_" } ; { t=strftime("%Y-%m-%d %H:%M",$2); printf "%-20s %-18s %-25s %s\n", t, $1, $4, $3 }'
checkout
[!NOTE|label:references:]
Copy # make a new blank repository in the current directory
git init
# add a remote
git remote add origin url://to/source/repository
# fetch a commit (or branch or tag) of interest
# Note: the full history up to this commit will be retrieved unless
# you limit it with '--depth=...' or '--shallow-since=...'
git fetch origin <sha1-of-commit-of-interest>
# reset this repository's master branch to the commit of interest
git reset --hard FETCH_HEAD
checkout particular commit and submodules
[!TIP] references:
Copy $ git checkout --recurse-submodules
or
Copy # [optional] create new branch
$ git branch <branch-name> <commit-id>
$ git checkout <branch-name>
$ git checkout <commit-id>
$ git submodule init # optional
$ git submodule update --recursive
or
Copy $ git clean -xfd
$ git submodule foreach --recursive git clean -xfd
$ git reset --hard
$ git submodule foreach --recursive git reset --hard
$ git submodule update --init --recursive
checkout single branch
Copy $ git clone --single-branch --branch <branch name> url://to/source/repository [target dir]
# or
# https://stackoverflow.com/a/13928822/2940319
$ mkdir -p <repo> && cd <repo>
$ git init
$ git fetch origin refs/heads/<branch>:refs/remotes/origin/<branch>
$ git checkout $(git rev-parse origin/<branch>^{commit})
add more branches
Copy $ git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
$ git fetch origin
or
Copy $ cat ~/.marslo/.gitalias
[alias]
# [a]dd [f]etch [r]efs
afr = !bash -c 'git config --add remote.origin.fetch "+refs/heads/$1:refs/remotes/origin/$1"'
$ git afr 'sandbox/marslo/*'
remote
fetch single branch
[!NOTE|label:references:]
with git remote
Copy $ mkdir -p <repo> && cd <repo>
$ git init
# set remote url
$ git remote add -f origin <repoUrl>
# set refsepc
$ git remote set-branches origin <branch>
# update local repo
$ git config core.sparseCheckout true
$ git fetch --all --progress
$ git checkout <branch>
with git config
Copy $ mkdir -p <repo> && cd <repo>
$ git init
# set remote url
$ git config remote.origin.url <repoUrl>
# set refsepc
$ git config [--add] remote.origin.fetch "+refs/heads/<branch>:refs/remotes/origin/<branch>"
# update local repo
$ git config core.sparseCheckout true
$ git fetch --all --progress
$ git checkout <branch>
clone --config
Copy $ git clone -c remote.origin.fetch=+refs/changes/*:refs/remotes/origin/changes/* <repoUrl>
# verify
$ git config --local --get-regexp origin.*
remote.origin.fetch +refs/changes/*:refs/remotes/origin/changes/*
remote.origin.url <repoUrl>
remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
config --add
Copy $ git config --local --get-regexp origin.*
remote.origin.url <repoUrl>
remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
$ git config --add remote.origin.fetch "+refs/changes/*:refs/remotes/origin/changes/*"
$ git config --local --get-regexp origin.*
remote.origin.url <repoUrl>
remote.origin.fetch +refs/heads/*:refs/remotes/origin/*
remote.origin.fetch +refs/changes/*:refs/remotes/origin/changes/*
add more remotes
push to multiple remotes
Copy # remote name
# v
$ git remote set-url --add origin <remoteUrl>
# before
$ git remote -v
origin ssh://path/to/repoUrl (fetch)
origin ssh://path/to/repoUrl (push)
# after
origin ssh://path/to/repoUrl (fetch)
origin ssh://path/to/repoUrl (push)
origin ssh://path/to/remoteUrl (push)
fetch and push to different repos
Copy $ git remote set-url --push origin ssh://path/to/remoteUrl
# before
$ git remote -v
origin ssh://path/to/repoUrl (fetch)
origin ssh://path/to/repoUrl (push)
# after
origin ssh://path/to/repoUrl (fetch)
origin ssh://path/to/remoteUrl (push)
Copy $ git remote set-url --delete --push origin ssh://path/to/remoteUrl
blame
blame in line range
-L <start>,<end>
Copy $ git blame -L 1,3 README.md
a03bebd23 (marslo Nov 2 2020 1) ---
a03bebd23 (marslo Nov 2 2020 2) disqus: false
a03bebd23 (marslo Nov 2 2020 3) ---
$ git blame -L 1,+3 README.md
a03bebd23 (marslo Nov 2 2020 1) ---
a03bebd23 (marslo Nov 2 2020 2) disqus: false
a03bebd23 (marslo Nov 2 2020 3) ---
-L :<funcname>
Copy $ git blame -L :pkgInstallation belloHAKubeCluster.sh
38327eac (marslo 2019-09-17 22:10:53 +0800 test1) function pkgInstallation() {
38327eac (marslo 2019-09-17 22:10:53 +0800 test2) dockerInstallation
38327eac (marslo 2019-09-17 22:10:53 +0800 test3) k8sInstallation
38327eac (marslo 2019-09-17 22:10:53 +0800 test4) cfsslInstallation
38327eac (marslo 2019-09-17 22:10:53 +0800 test5) etcdInstallation
bdfe4340 (marslo 2019-09-23 16:35:08 +0800 test6) helmInstallation
38327eac (marslo 2019-09-17 22:10:53 +0800 test7) }
38327eac (marslo 2019-09-17 22:10:53 +0800 test8)
# or
$ git blame -L '/pkgInstallation/,+3' belloHAKubeCluster.sh
38327eac (marslo 2019-09-17 22:10:53 +0800 test1) function pkgInstallation() {
38327eac (marslo 2019-09-17 22:10:53 +0800 test2) dockerInstallation
38327eac (marslo 2019-09-17 22:10:53 +0800 test3) k8sInstallation
by keywords ( git log -S
)
Copy $ git pls -S pkgInstallation belloHAKubeCluster.sh
...
* 38327ea - update (2 years, 10 months ago) <marslo>
format
-s
Copy $ git blame -s README.md | head -2
a03bebd23 1) ---
a03bebd23 2) disqus: false
-n
, --show-number
Copy $ git blame -n -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac 553 (marslo 2019-09-17 22:10:53 +0800 test1) function pkgInstallation() {
-f
, --show-name
Copy $ git blame -f -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac kubernetes/belloHAKubeCluster.sh (marslo 2019-09-17 22:10:53 +0800 test1) function pkgInstallation() {
-e
, --show-email
[!TIP] This can also be controlled via the blame.showEmail config option.
Copy $ git blame -e -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac (<marslo@gmail.com> 2019-09-17 22:10:53 +0800 test1) function pkgInstallation() {
-l
Copy $ git blame -l -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac9b01d57c13d1865d58d822a81717d60f (marslo 2019-09-17 22:10:53 +0800 test1) function pkgInstallation() {
--date
[!TIP] check : imarslo: date format setup global in ~/.gitconfig
:
Copy [blame]
date="format:%Y-%m-%d %H:%M:%S %p"
Copy $ for i in iso iso-strict relative local rfc short raw human unix 'format:%c' '"format:%Y-%m-%d %H:%M:%S"'; do
cmd="git blame --date=${i} -L '/pkgInstallation/,+1' belloHAKubeCluster.sh";
echo ${cmd}; eval ${cmd}; echo "";
done
git blame --date=iso -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac (marslo 2019-09-17 22:10:53 +0800 test1) function pkgInstallation() {
git blame --date=iso-strict -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac (marslo 2019-09-17T22:10:53+08:00 test1) function pkgInstallation() {
git blame --date=relative -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac (marslo 2 years, 10 months ago test1) function pkgInstallation() {
git blame --date=local -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac (marslo Tue Sep 17 22:10:53 2019 test1) function pkgInstallation() {
git blame --date=rfc -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac (marslo Tue, 17 Sep 2019 22:10:53 +0800 test1) function pkgInstallation() {
git blame --date=short -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac (marslo 2019-09-17 test1) function pkgInstallation() {
git blame --date=raw -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac (marslo 1568729453 +0800 test1) function pkgInstallation() {
git blame --date=human -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac (marslo Sep 17 2019 test1) function pkgInstallation() {
git blame --date=unix -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac (marslo 1568729453 test1) function pkgInstallation() {
git blame --date=format:%c -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac (marslo Tue Sep 17 22:10:53 2019 test1) function pkgInstallation() {
git blame --date="format:%Y-%m-%d %H:%M:%S" -L '/pkgInstallation/,+1' belloHAKubeCluster.sh
38327eac (marslo 2019-09-17 22:10:53 test1) function pkgInstallation() {
--color-lines
[!TIP] references:
example:
Copy [color "blame"]
repeatedLines = 130
--color-by-age
[!TIP] references:
example:
Copy [color "blame"]
highlightRecent = 239, 20 month ago, 240, 18 month ago, 241, 16 month ago, 242, 14 month ago, 243, 12 month ago, 244, 10 month ago, 245, 8 month ago, 246, 6 month ago, 247, 4 month ago, 131, 3 month ago, 137, 2 month ago, 172, 1 month ago, 167, 3 weeks ago, 166, 2 weeks ago, 203, 1 week ago, 202
// others
[color "blame"]
highlightRecent = 237, 20 month ago, 238, 19 month ago, 239, 18 month ago, 240, 17 month ago, 241, 16 month ago, 242, 15 month ago, 243, 14 month ago, 244, 13 month ago, 245, 12 month ago, 246, 11 month ago, 247, 10 month ago, 248, 9 month ago, 249, 8 month ago, 250, 7 month ago, 251, 6 month ago, 252, 5 month ago, 253, 4 month ago, 254, 3 month ago, 231, 2 month ago, 230, 1 month ago, 229, 3 weeks ago, 228, 2 weeks ago, 227, 1 week ago, 226
tricky
--since
Copy $ git blame --since=3.weeks -- foo
# or
$ git blame v2.6.18.. -- foo
for-each-ref
[!NOTE|label:references:]
get refs days ago
Copy while read revision branch commitDate; do
benchmark=$(date +%s --date="1 year ago")
# echo "benchmark: $benchmark"
if [[ commitDate -le benchmark ]]; then
git for-each-ref ${branch} --format='%(refname:short) - %(align:right,20)%(committerdate:format:%Y-%m-%d %H:%M:%S)%(end)'
fi
done < <(git for-each-ref refs/remotes/origin/sandbox --sort=committerdate --format='%(objectname) %(refname) %(committerdate:unix)')
to archive
Copy $ git push origin refs/remotes/origin/sandbox/marslo/test:refs/remotes/archive/sandbox/marslo/test
Total 0 (delta 0), reused 0 (delta 0), pack-reused 0
remote: Processing changes: refs: 1, done
remote: GitMS - update replicated.
To ssh://gerrit.domain.com:29418/storage/ssdfw/devops/jenkins
* [new reference] origin/sandbox/marslo/test -> archive/sandbox/marslo/test
to delete
Copy # delete local refs
$ git update-ref -d refs/remotes/origin/sandbox/marslo/test -m 'already archived in refs/remotes/archive/sandbox/marslo/test'
# delete remote refs
$ git push . :refs/remotes/origin/sandbox/marslo/test
# or delete without `refs/remotes/`
$ git push origin --delete archive/sandbox/marslo/test
$ git push origin --delete origin/sandbox/marslo/test
delete via origin
will get issue internal server error
Copy $ git push origin --force :refs/remotes/origin/sandbox/marslo/test
remote: Processing changes: refs: 1, done
remote: error: ref update is a no-op: DELETE: 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000 refs/remotes/origin/sandbox/marslo/test
To ssh://gerrit.domain.com:29418/storage/ssdfw/devops/jenkins
! [remote rejected] origin/sandbox/marslo/test (internal server error)
error: failed to push some refs to 'ssh://gerrit.domain.com:29418/storage/ssdfw/devops/jenkins'
to retrive
Copy # fetch single ref
$ git fetch origin refs/remotes/archive/sandbox/marslo/test
From ssh://gerrit.domain.com:29418/storage/ssdfw/devops/jenkins
* remote-tracking branch archive/sandbox/marslo/test -> FETCH_HEAD
$ git checkout FETCH_HEAD
HEAD is now at 749bd27d test
# fetch all ref
$ git fetch origin refs/remotes/archive/*:refs/archive/*
remote: Counting objects: 4507, done
remote: Finding sources: 100% (57/57)
remote: Total 57 (delta 20), reused 49 (delta 20)
Unpacking objects: 100% (57/57), 14.52 KiB | 424.00 KiB/s, done.
From ssh://gerrit.domain.com:29418/storage/ssdfw/devops/jenkins
* [new ref] archive/sandbox/marslo/test -> refs/archive/sandbox/marslo/test
* [new ref] archive/sandbox/marslo/sandbox -> refs/archive/sandbox/marslo/sandbox
* [new ref] archive/sandbox/marslo/sample -> refs/archive/sandbox/marslo/sample
format
(subject)
: "the subject line"
%(subject:sanitize)
: "the-subject-line"
[!TIP]
foramtting https://git-scm.com/docs/git-for-each-ref/2.21.0#Documentation/git-for-each-ref.txt---formatltformatgt
field names:
head :
refname:
-> refs/heads/master
refname:lstrip=1
-> heads/master
refname:lstrip=2
-> master
refname:lstrip=-1
-> master
refname:lstrip=-2
-> heads/master
refname:rstrip=1
-> refs/heads
refname:rstrip=-1
-> refs
refname:rstrip=-2
-> refs/heads
refname:strip=1
-> heads/master
refname:strip=2
-> master
refname:strip=-1
-> master
refname:strip=-2
-> heads/master
upstream
-> refs/remotes/origin/master
upstream:short
-> origin/master
upstream:lstrip=2
-> origin/master
upstream:lstrip=-2
-> origin/master
upstream:rstrip=2
-> refs/remotes
upstream:rstrip=-2
-> refs/remotes
upstream:strip=2
-> origin/master
upstream:strip=-2
-> origin/master
push
-> refs/remotes/myfork/master
push:short
-> myfork/master
push:lstrip=1
-> remotes/myfork/master
push:rstrip=1
-> refs/remotes/myfork
push:strip=1
-> remotes/myfork/master
objectsize
-> $((131 + hexlen))
objectsize:disk
-> $disklen
author
-> 'A U Thor <author@example.com> 1151968724 +0200'
authoremail
-> '<author@example.com>'
authoremail:trim
-> 'author@example.com'
authoremail:localpart
-> 'author'
taggeremail:localpart
-> ''
subject:sanitize
-> 'Initial'
contents:subject
-> 'Initial'
objectname
-> $(git rev-parse refs/heads/master)
objectname:short
-> $(git rev-parse --short refs/heads/master)
objectname:short=1
-> $(git rev-parse --short=1 refs/heads/master)
objectname:short=10
-> $(git rev-parse --short=10 refs/heads/master)
tree
-> $(git rev-parse refs/heads/master^{tree})
tree:short
-> $(git rev-parse --short refs/heads/master^{tree})
tree:short=1
-> $(git rev-parse --short=1 refs/heads/master^{tree})
tree:short=10
-> $(git rev-parse --short=10 refs/heads/master^{tree})
authordate
-> 'Tue Jul 4 01:18:44 2006 +0200'
committer
-> 'C O Mitter <committer@example.com> 1151968723 +0200'
committername
-> 'C O Mitter'
committeremail
-> '<committer@example.com>'
committeremail:trim
-> 'committer@example.com'
committeremail:localpart
-> 'committer'
committerdate
-> 'Tue Jul 4 01:18:43 2006 +0200'
objectname:short=1
-> $(git rev-parse --short=1 refs/heads/master)
objectname:short=10
-> $(git rev-parse --short=10 refs/heads/master)
creator
-> 'C O Mitter <committer@example.com> 1151968723 +0200'
creatordate
-> 'Tue Jul 4 01:18:43 2006 +0200'
tags:
refname
-> refs/tags/testtag
objectsize
-> $((114 + hexlen))
objectsize:disk
-> $disklen
'*objectsize:disk'
-> $disklen
'*deltabase'
-> $ZERO_OID
'*objecttype'
-> 'commit'
authoremail:localpart
-> ''
committeremail:trim
-> ''
committeremail:localpart
-> ''
contents
-> `'Tagging at 1151968727``
object
-> $(git rev-parse refs/tags/testtag^0)
objectname
-> $(git rev-parse refs/tags/testtag)
objectname:short
-> $(git rev-parse --short refs/tags/testtag)
'*objectname'
-> $(git rev-parse refs/tags/testtag^{})
tagger
-> 'C O Mitter <committer@example.com> 1151968725 +0200'
taggername
-> 'C O Mitter'
taggeremail
-> '<committer@example.com>'
taggeremail:trim
-> 'committer@example.com'
taggeremail:localpart
-> 'committer'
taggerdate
-> 'Tue Jul 4 01:18:45 2006 +0200'
creator
-> 'C O Mitter <committer@example.com> 1151968725 +0200'
creatordate
-> 'Tue Jul 4 01:18:45 2006 +0200'
subject
-> 'Tagging at 1151968727'
subject:sanitize
-> 'Tagging-at-1151968727'
contents:subject
-> 'Tagging at 1151968727'
date format
[!TIP] references:
format:
strftime :
%a
: Abbreviated weekday name
%b
: Abbreviated month name
%c
: Date and time representation appropriate for locale
%d
: Day of month as decimal number (01 – 31)
%H
: Hour in 24-hour format (00 – 23)
%I
: Hour in 12-hour format (01 – 12)
%j
: Day of year as decimal number (001 – 366)
%m
: Month as decimal number (01 – 12)
%M
: Minute as decimal number (00 – 59)
%p
: Current locale's A.M./P.M. indicator for 12-hour clock
%S
: Second as decimal number (00 – 59)
%U
: Week of year as decimal number, with Sunday as first day of week (00 – 53)
%w
: Weekday as decimal number (0 – 6; Sunday is 0)
%W
: Week of year as decimal number, with Monday as first day of week (00 – 53)
%x
: Date representation for current locale
%X
: Time representation for current locale
%y
: Year without century, as decimal number (00 – 99)
%Y
: Year with century, as decimal number
%z
, %Z
: Either the time-zone name or time zone abbreviation, depending on registry settings
how to use
Copy $ git for-each-ref --sort=-taggerdate refs/tags \
--format='%(committerdate)'
Mon Aug 30 21:50:57 2021 +0800
$ git for-each-ref --sort=-taggerdate refs/tags \
--format='%(committerdate:relative)'
9 months ago
$ git for-each-ref --sort=-taggerdate refs/tags \
--format='%(committerdate:raw)'
1630331457 +0800
$ git for-each-ref --sort=-taggerdate refs/tags \
--format='%(committerdate:iso)'
2021-08-30 21:50:57 +0800
$ git for-each-ref --sort=-taggerdate refs/tags \
--format='%(committerdate:rfc)'
Mon, 30 Aug 2021 21:50:57 +0800
$ git for-each-ref --sort=-taggerdate refs/tags \
--format='%(committerdate:local)'
Mon Aug 30 21:50:57 2021
$ git for-each-ref --sort=-taggerdate refs/tags \
--format='%(committerdate:format:%Y-%m-%d %I:%M %p)'
2021-08-30 09:50 PM
$ git for-each-ref --sort=-taggerdate refs/tags \
--format='%(committerdate:format:%Y-%m-%d %H:%M:%S)'
2021-08-30 21:50:57
color
[!TIP|label:usage:]
example
Copy $ git for-each-ref --sort=-taggerdate refs/tags \
--format='%(color:yellow)%(committerdate:iso)%(color:reset)' \
--color
=always
2021-08-30 21:50:57 +0800
$ git for-each-ref --sort=-taggerdate refs/tags \
--format='%(color:blue)%(committerdate:iso)%(color:reset)' \
--color=always
2021-08-30 21:50:57 +0800
condition
[!TIP|label:references:]
%(if)...%(then)...%(else)...%(end)
%(align:<number>,left) ... %(end)
example
Copy $ git for-each-ref --sort=-taggerdate refs/tags \
--format='%(if)%(committerdate)%(then)%(committerdate:format:%Y-%m-%d %I:%M %p)%(else)%(taggerdate:format:%Y-%m-%d %I:%M %p)%(end)'
2021-08-30 09:50 PM
$ git for-each-ref --sort=-taggerdate refs/tags \
--format='%(align:left,50)[%(objecttype) : %(refname:short)]%(end) (%(committerdate:format:%Y-%m-%d %H:%M)) <%(committername)>' \
--color \
--count=10
[commit : sandbox/marslo/tag-1] (2021-08-30 21:50) <marslo>
alias
Copy [alias]
### [p]retty [t]ag
pt = "!git for-each-ref --sort=-taggerdate refs/tags --format='%(color:red)%(objectname:short)%(color:reset) - %(align:left,38)%(color:bold yellow)[%(objecttype) : %(refname:short)]%(color:reset)%(end) %(subject) %(color:green)(%(if)%(taggerdate)%(then)%(taggerdate:format:%Y-%m-%d %H:%M)%(else)%(committerdate:format:%Y-%m-%d %H:%M)%(end))%(color:reset) %(color:blue)%(if)%(taggername)%(then)<%(taggername)>%(else)<%(committername)>%(end)%(color:reset)' --color --count=10"
pts = "!git for-each-ref --sort=-taggerdate refs/tags --format='%(color:red)%(objectname:short)%(color:reset) - %(color:bold yellow)[%(objecttype) : %(refname:short)]%(color:reset) - %(subject) %(color:green)(%(if)%(taggerdate)%(then)%(taggerdate:format:%Y-%m-%d %H:%M)%(else)%(committerdate:format:%Y-%m-%d %H:%M)%(end))%(color:reset) %(color:blue)%(if)%(taggername)%(then)<%(taggername)>%(else)<%(committername)>%(end)%(color:reset)' --color"
### [p]retty [b]ranch
pb = "! git for-each-ref refs/heads refs/remotes --sort=-committerdate --format='%(color:red)%(objectname:short)%(color:reset) - %(color:bold yellow)%(committerdate:format:%Y-%m-%d %H:%M:%S)%(color:reset) - %(align:left,20)%(color:cyan)<%(authorname)>%(color:reset)%(end) %(color:bold red)%(if)%(HEAD)%(then)* %(else) %(end)%(color:reset)%(refname:short)' --color --count=10"
pbs = "! git for-each-ref refs/heads refs/remotes --sort=-committerdate --format='%(color:red)%(objectname:short)%(color:reset) - %(color:bold yellow)%(committerdate:format:%Y-%m-%d %H:%M:%S)%(color:reset) - %(align:left,20)%(color:cyan)<%(authorname)>%(color:reset)%(end) %(color:bold red)%(if)%(HEAD)%(then)* %(else) %(end)%(color:reset)%(refname:short)' --color"