General info
git
documentation https://git-scm.com/docs/git- all commands, divided into high level and low level ones https://git-scm.com/docs/git#_git_commands
git reset
,git restore
andgit revert
https://git-scm.com/docs/git#_reset_restore_and_revert https://stackoverflow.com/a/58003889- Identifier terminology,
<object>
,<tree-ish>
,<commit-ish>
, etc. https://git-scm.com/docs/git#_identifier_terminology<commit-ish>
vs<tree-ish>
: https://stackoverflow.com/q/23303549/
- https://git-scm.com/docs/gitglossary
git <command>
documentation:https://git-scm.com/docs/git-<command>
- Pro Git book (living) https://git-scm.com/book/en/v2 https://github.com/progit/progit2
- Release notes
- Highlights from Git releases
- https://github.blog/2019-08-16-highlights-from-git-2-23
- new commands
git switch
andgit restore
- new commands
- https://github.blog/2019-08-16-highlights-from-git-2-23
Configuration
- new syntaxes and options since v2.46.0
for example,
git config KEY VALUE
=>git config set KEY VALUE
https://git-scm.com/docs/git-config#_deprecated_modes https://github.blog/open-source/git/highlights-from-git-2-46/ - Syntax of config files (
.git/config
,$HOME/.gitconfig
) https://git-scm.com/docs/git-config#_syntax - Print pathnames in Unicode, other than octal UTF-8 (ref)
git config set [--global] core.quotepath off
- Diff non-UTF8 files:
# Suppose the .tex files are in GBK encoding $ cat .git/config [diff "gbk"] textconv = "iconv -f gbk -t utf-8" $ cat .gitattributes *.tex diff=gbk
- Show whitespace changes in
git diff
(doc)$ git config set [--global] diff.wsErrorHighlight all
- Pretty one-line
git log
based on https://ma.ttias.be/pretty-git-log-in-one-line/# set pretty format and alias git config set --global pretty.logline "%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cr) %C(cyan)<%an>%Creset" git config set --global alias.logline "log --graph --pretty=format:logline --abbrev-commit" # use git alias $ git logline
Show status
- Show individual files in untracked directories (ref)
git status [-u | --untracked-files]
Clone and fetch
- Shallow clone:
git clone --depth=<num> [--no-single-branch]
--depth
implies--single-branch
, thus thefetch = +refs/heads/DEFAULT_BRANCH:refs/remotes/origin/DEFAULT_BRANCH
line in.git/config
, which makes new branches pushed to remote not auto-tracked locally- To overwrite
--single-branch
, rungit remote set-branches REMOTE BRANCH
or directly edit.git/config
- To query all
remote.*.fetch
settings,git -P config get --all --show-names --regexp 'remote\..*\.fetch'
- To overwrite
- Convert a shallow clone to full clone (ref)
git fetch --unshallow
- Fetch a specific commit
git fetch --depth=1 origin <commit>
- Fetch a specific tag
https://stackoverflow.com/a/54635270 short form
git fetch --no-tags origin tag <tag>
-n
https://git-scm.com/docs/git-fetch#Documentation/git-fetch.txt--n see also Git configremote.<name>.tagOpt
.
Commit changes
- Update commit author (and email)
https://git-scm.com/docs/git-commit#Documentation/git-commit.txt---authorltauthorgt
git commit --amend --author="Author <[email protected]>"
- Batch sign-off
--signoff
, no short formgit rebase --signoff <commit>
Workflow
- Keep branch clean with
--fixup
and--autosquash
(article)# `--fix` automatically marks your commit as a fix of a previous commit # The resulted commit message will be "fixup! <msg of referred commit>" git commit --fixup <commit> # `--autosquash` automatically organizes merging of fixup commits and associated normal commits git rebase [-i] --autosquash <commit>
Branching and Merging
- Create a local branch that tracks a remote one (doc)
git fetch <remote> <branch>:<local branch>
- Delete a remote-tracking branch (the corresponding local branch is unchanged, ref)
git branch --delete --remotes <remote>/<branch>
- Track new remote branch after a shallow clone (ref)
wait for test:
# shallow clone git clone --depth=<num> <repository> [<directory>] # change the list of branches tracked git remote set-branches <remote> '*' # or git remote set-branches --add <remote> <new_branch> # add track to new remote branch git fetch <remote> <new_branch>
git fetch --update-shallow <remote> <branch>
- Include a commit summary in merge commit
git merge --no-ff --log <branch>
Switch to a branch or commit-ish
git switch BRANCH
git switch -c/--create NEW_BRANCH [START_POINT]
git switch ---detach START_POINT
Back to clean working directory
git stash list
# -a/--all also takes ignored files into consideration
git stash [push] [-u | --include-untracked] [(-m | --message) <message>]
git stash pop
git stash show [--stat] [--patch] [-u | --include-untracked] [stash@{0}]
git stash drop [stash@{0}]
Restore files from index or some commit
# restore working tree (-W/--worktree) from HEAD
git restore [--] <pathspec>...
# restore index from HEAD
git restore --staged [--] <pathspec>...
# -S/--staged and -W/--worktree can be used in together
# -p/--patch: select hunks interactively
# -s/--source=<tree>: restore from <tree>
Tags
# add a lightweight tag
git tag -a <tag>
# add an annotated tag
git tag -a <tag> -m "annot"
# list only lightweight tags
# ref: https://stackoverflow.com/a/67687543
git for-each-ref refs/tags | grep commit
# list only annotated tags
git for-each-ref refs/tags | grep -v commit
Push to remote
- Push single tag (Q&A)
Differences between annotated (
# to resolve tag/branch name clashes, use "refs/tags/<tag>" git push <remote> <tag>
-m <message>
) and unannotated tags: this Q&A
Change remote
- Delete remote branch or tag
git push --delete <remote> <branch/tag>
Show log
- List commits that changed a specific file (ref)
git log --follow -- filename
- Show first commit (ref)
git log --reverse
Large File Storage (LFS)
- homepage: https://git-lfs.github.com/
- docs: https://github.com/git-lfs/git-lfs/tree/main/docs/man
- NOTE: GitHub Pages doesn't support Git LFS. (source)
# install and init
brew install git-lfs
git lfs install
# track/untrack files by extension
git lfs track "*.gif"
git lfs untrack "*.gif"
# Equivalent to add/remove line
# *.gif filter=lfs diff=lfs merge=lfs -text
# to/from `.gitattributes`
# fetch and checkout lfs files
git lfs fetch
git lfs checkout
# retrack files (after untrack them from lfs)
# QA: https://stackoverflow.com/q/35011366/
git add --renormalize .
Misc
- Force or cancel pager
https://git-scm.com/docs/git#Documentation/git.txt--p
https://git-scm.com/docs/git#Documentation/git.txt--P
git [-p | --paginate] <command> git [-P | --no-pager] <command>
- Clean up unlinked commits (ref)
git reflog expire --expire=now --all git gc --prune=now
- Shorten local clone, just to save disk space (ref)
git fetch --depth=1 git reflog expire --expire-unreachable=now --all git gc --aggressive --prune=all
- Diff between arbitrary files:
git diff --no-index <file a> <file b>
- List all (local) references (heads, remotes, stash, and tags)
https://git-scm.com/docs/git-for-each-ref
https://git-scm.com/docs/git-show-ref
git [--paginate] for-each-ref [--format="%(refname)"] # or git [--paginate] show-ref --head --dereference
- List all commits, including unreachable ones
https://git-scm.com/docs/git-rev-list
git --paginate rev-list --all --no-commit-header --pretty=oneline
- Count the commits on current branch (ref)
git rev-list --count HEAD
- Describe a commit even without reachable tags
https://git-scm.com/docs/git-describe#Documentation/git-describe.txt---always saw in https://github.com/tuna/thuthesis/commit/bd0481059cf97bf9fa89638ab5cd5bc2abd27fa9, for the request raised in tuna/thuthesis#979
git describe --tags --always # the first reachable tag is "v3.1.2" # v3.1.2-21-gc6cd52d # no tag is reachable # gc6cd52d
gh api
https://cli.github.com/manual/gh_api- adding parameters (via
-f/--raw-field
or-F/--field
) changes the default HTTP method fromGET
toPOST
The default HTTP request method is
GET
normally andPOST
if any parameters were added. Override the method with-X/--method
.- so
gh api /repos/muzimuzhi/hello-github-actions/issues/26/comments -f body='Send by GitHub CLI'
works butgh api /repos/denoland/vscode_deno/commits -f per_page=2
(without-X GET
) failed with errorgh: Not Found (HTTP 404)
- feature request to only switch to
POST
when body parameters were added is made in cli/cli#6877 (comment)
- so
- adding parameters (via
- debug
PAGER= GH_DEBUG=1
https://cli.github.com/manual/gh_help_environmentGH_DEBUG=api
also logs HTTP traffic