gitdocumentation 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 restoreandgit reverthttps://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 switchandgit restore
- new commands
- https://github.blog/2019-08-16-highlights-from-git-2-23
- new syntaxes and options since v2.46.0
for example,
git config KEY VALUE=>git config set KEY VALUEhttps://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 logbased 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
- aliases
https://git-scm.com/docs/git-config#Documentation/git-config.txt-alias
- shell command aliases are always run with
shGIT_TRACE=1 git <alias> ...shows the actual commands (/bin/sh -c); alternatively,git var GIT_SHELL_PATHshows the path tosh; https://stackoverflow.com/a/46698535 https://stackoverflow.com/a/65086817
- shell command aliases are always run with
- Show individual files in untracked directories (ref)
git status [-u | --untracked-files]
- Shallow clone:
git clone --depth=<num> [--no-single-branch]--depthimplies--single-branch, thus thefetch = +refs/heads/DEFAULT_BRANCH:refs/remotes/origin/DEFAULT_BRANCHline in.git/config, which makes new branches pushed to remote not auto-tracked locally- To overwrite
--single-branch, rungit remote set-branches REMOTE BRANCHor directly edit.git/config - To query all
remote.*.fetchsettings,git -P config get --all --show-names --regexp 'remote\..*\.fetch'
- 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>-nhttps://git-scm.com/docs/git-fetch#Documentation/git-fetch.txt--n see also Git configremote.<name>.tagOpt.
- 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> - Reuse last commit message (after a failed attempt)
# -e/--edit -F/--file git commit [--edit] --file .git/COMMIT_EDITMSG
Workflow
- Keep branch clean with
--fixupand--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 # see also boolean config `rebase.autoSquash` git rebase [-i] --autosquash <commit>
- 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_POINTBack 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>...
# restore both the working tree and the index
git restore --staged --worktree [--] <pathspec>...
# -S/--staged and -W/--worktree can be used in together
# -p/--patch: select hunks interactively
# -s/--source=<tree>: restore from <tree># add a lightweight tag
git tag -a <tag>
# add an annotated tag
git tag -a <tag> -m "annot"
# list lightweight tags only
# ref: https://stackoverflow.com/a/67687543
git for-each-ref refs/tags | grep commit
# list annotated tags only
git for-each-ref refs/tags | grep -v commit
# list tags by descending semver numbers
# https://git-scm.com/docs/git-tag#Documentation/git-tag.txt---sortkey
git tag --sort -v:refnamePush 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>
- List commits that changed a specific file (ref)
git log --follow -- filename
- Show first commit (ref)
git log --reverse
- 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 .- 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
- Check whether a
pathnamewould be ignored, and if true, by which gitignore pattern https://git-scm.com/docs/git-check-ignoregit check-ignore [-v|--verbose] PATHNAME - Show Git logical (?) variable(s)
git var GIT_SHELL_PATH
- Binary search on commit history
https://git-scm.com/docs/git-bisect
git bisect start git bisect bad/old [REV] git bisect good/new [REV...] git bisect run zsh -c "command && exit 0 || exit 1"
gh apihttps://cli.github.com/manual/gh_api- adding parameters (via
-f/--raw-fieldor-F/--field) changes the default HTTP method fromGETtoPOSTThe default HTTP request method is
GETnormally andPOSTif 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
POSTwhen body parameters were added is made in cli/cli#6877 (comment)
- so
- adding parameters (via
- debug
PAGER= GH_DEBUG=1https://cli.github.com/manual/gh_help_environmentGH_DEBUG=apialso logs HTTP traffic
- just a command runner https://github.com/casey/just (README contains single-page doc) https://just.systems/ (multi-page doc)
- cheatsheet https://cheatography.com/linux-china/cheat-sheets/justfile/
- usage
# run the default recipe just # run specified recipe(s) just RECIPE... # dry run (-n) just --dry-run # list recipes just --list
- notice
- each recipe line is executed by a new shell https://github.com/casey/just?tab=readme-ov-file#setting-variables-in-a-recipe https://github.com/casey/just?tab=readme-ov-file#changing-the-working-directory-in-a-recipe
if ... { ... } else { ... }must has anelsebranch
- limitations
- not enough shell-portable utilities
- no recipe variable
- no recursive call (run
justin a recipe and inherit current settings and variables)
- https://pre-commit.com/ (only 1st-level ToC bookmarks, pity) https://github.com/pre-commit/pre-commit
- CI, free for open source repos
https://pre-commit.ci/
- auto fix PR commits
- autoupdate hooks
- config https://pre-commit.ci/#configuration
- usage
# install $ uv tool install pre-commit # add .pre-commit-config.yaml (".yml" is NOT supported) # ... # install the ".git/hooks/pre-commit" script $ pre-commit install # run against all files (init run) $ pre-commit run --all-files [<hook-id>] # run against staged files # the "pre-commit" hook runs "pre-commit run" $ pre-commit run [--files FILE...] [<hook-id>]
- config
- starter
.pre-commit-config.yamlhttps://pre-commit.com/#2-add-a-pre-commit-configurationrepos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: - id: check-case-conflict - id: check-illegal-windows-names - id: check-merge-conflict - id: check-toml - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace
- run arbitrary commands
repos: - repo: local hooks: - id: just-lint-all name: run just lint-all recipe language: system entry: just lint-all pass_filenames: false
pre-commit autoupdate [--freeze]update repo versions https://pre-commit.com/#pre-commit-autoupdate
- starter
- caches
pre-commit gcclean unused cached repos https://pre-commit.com/#pre-commit-gc- location
~/.cache/pre-commithttps://pre-commit.com/#managing-ci-caches
git commit --no-verifybypass thepre-commithooks (and several more) https://git-scm.com/docs/githooks#_pre_commit- practices https://github.com/muzimuzhi/latex-zutil/blob/main/.pre-commit-config.yaml https://github.com/crate-ci/typos/blob/master/.pre-commit-hooks.yaml
- repo https://github.com/BurntSushi/ripgrep
- docs
- guide https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md
- faq https://github.com/BurntSushi/ripgrep/blob/master/faq.md
- full doc is only provided as manpage
- manpage as HTML https://manpages.debian.org/testing/ripgrep/rg.1.en.html
- whitelist rules
- whitelist files under hidden directory
To search inside files under
.github, only the rule!.github(with optional leading and trailing/s) without any trailing glob patterns works, and none of the following work.see the example in!.github/** !.github/**/*.* !.github/workflows
ripgrepitself https://github.com/BurntSushi/ripgrep/commit/387df97d85291f75511dc77329395931af348b34
- whitelist files under hidden directory
To search inside files under
- Low false-positive source code spell checker https://github.com/crate-ci/typos https://github.com/crate-ci/typos/blob/master/docs/reference.md
- usage
# run typos [-c/--config CUSTOM_CONFIG] # auto fix (-w/--write-chagnes) typos -w # list unclassified files typos --config .github/typos.toml --file-types | rg ': -$'
- config
https://github.com/crate-ci/typos/blob/master/docs/reference.md
- config file
[._]?typos.tomlin non-Python projectstypos -c/--config <CUSTOM_CONFIG>
- config reference
- config file
- GitHub Actions integration
https://github.com/crate-ci/typos/blob/master/docs/github-action.md
jobs: spelling: name: Spell check with Typos runs-on: ubuntu-latest # one workaround https://github.com/crate-ci/typos/pull/1192 # already used in https://github.com/muzimuzhi/latex-zutil - name: Install wget if: runner.os == 'Windows' run: choco install wget --no-progress # needs "wget", which is missing from GH Windows runners - name: Spell Check Repo uses: crate-ci/[email protected]