Git #
References:
- Version Control (Git) · the missing semester of your cs education
- Git - Reference
- How to Write a Git Commit Message
Basic terms:
- tree: folder
- blob: file
- HEAD: the current state of the files that you’re looking at
- stage: telling git about changes
- commit: record the staged changes
Config #
Set editor #
Ref: How can I set up an editor to work with Git on Windows? - Stack Overflow
Set a different editor than $EDITOR:
git config --global core.editor vimUseful Aliases #
Oh-My-Zsh Git Plugin #
References:
- All aliases: ohmyzsh/plugins/git/git.plugin.zsh at master · ohmyzsh/ohmyzsh
- Cheatsheet · ohmyzsh/ohmyzsh Wiki
# git status
gst
# git pull
gl
# git push
gp
# git checkout master/main
gcm
# git commit -m
gcmsg "message here"
# All cached changes
# git diff --cached
# git diff --staged
gds
# git diff --word-diff
gdw
# git log --oneline --decorate --graph
glog
# git remote --verbose
grvChange git CLI language #
Does not work in tmux for reasons unknown.
In ~/.zshrc:
# Use languages other than default shell language
alias git='LANG="zh_CN.UTF-8" git'Observe Things #
Logs #
See all files changed with each commit: (credit)
git log --statOne-line graphic log: (credits: new, old); (tformat is preferred over format, see credit)
git log --all --decorate --oneline --graph
# old version:
git log --graph --full-history --all --date=short --pretty=tformat:'%Cred%h%Creset %C(bold green)%ad%Creset %s %C(yellow)%d%Creset %Cblue<%an>%Creset'Diff #
Difference between most recent commit and second most recent commit: (credit)
git diff HEAD^ HEADDifference between branches: (credit)
git diff branch_1..branch_2Difference between staged (added) changes and most recent commit:
git diff --stagedOnly list changed file names and status:
Meaning of the marks
A: AddedC: CopiedD: DeletedM: ModifiedR: RenamedT: Type (i.e. regular file, symlink, submodule, …) changedU: UnmergedX: UnknownB: Broken pairing
# Newest commit
git diff --name-status HEAD~1..HEAD
# Compare the current state and some previous commit
git diff --name-status <commit>
# Compare two previous commits
git diff --name-status <new-commit>..<old-commit>Files #
Show all files under git version control:
# r for recursive
git ls-tree -r --full-tree --name-only HEAD
# or
git ls-filesFind out how many files are being tracked: (credit)
# All files
git ls-files | wc -l
# Some kind of file (e.g. Markdown)
git ls-files | grep "\.md$" | wc -lBlame #
Reference: Git - git-blame Documentation
# Inspect lines 20~30
git blame a-file.md -L 20,30
# Inspect from start of file to line 30
git blame a-file.md -L ,30
# Inspect from line 20 to end of file
git blame a-file.md -L 20,Remote #
Show all remote URLs:
git remote --verbose
git remote -vCommit-Level Operations #
Interactive chunk-staging:
git add --patch somefile.txt
git add -p somefile.txtChange last commit message:
git commit --amendGently squash last two (or any number of) commits: (credit)
git reset --soft HEAD~2
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"Undo last commit: (credit)
git reset HEAD~1Apply Late .gitignore #
Commit first:
git commit -m "add/change .gitignore"
subl .gitignoreAdd something to .gitignore, for example:
# Things to ignore
**/.DS_Store
**/*.pdf
# Things to keep
!roadmap.pdfApply changes:
git rm -r --cached . && git add . && git commit -m "apply .gitignore"git bisect #
TBA
Repository-Level Operations #
Change file extension #
Ref: Changing file extensions in bulk using Git Bash | Samantha Miller
This command works recursively.
find . -name '*.pug' -exec sh -c 'git mv "$0" "${0%.pug}.html"' {} \;Branches #
See all branches:
git branch
# See some more info
git branch --verbose
git branch -vCreate branch:
git branch my-new-branch
git checkout my-new-branch
# or
git checkout -b my-new-branchChange branch name:
git branch -m master main
git push -u origin main
# external action required: go to origin (e.g. GitHub)
# and change the default branch
git push origin --delete masterMove files changes to another branch: (credit)
# p for patch
git checkout <other_branch_name> <files/to/grab in/list/separated/by/spaces> -pMerge master to new branch: (credit)
git pull origin masterDelete local branch:
git checkout master
git branch -d my-old-branchDelete all gone local branches: (credit)
git remote prune originDelete remote branch:
git push -d origin my-old-branchMerge Master into Branch #
Credit: GitHub
# From your project repository, bring in the changes and test.
git fetch origin
git checkout -b "my-branch" "origin/my-branch"
git merge "master"
# Merge the changes and update on remote.
git checkout "master"
git merge --no-ff "my-branch"
git push origin "master"Remove sensitive data from history #
Haven’t tried: Removing sensitive data from a repository - GitHub Docs
Split Repo #
Credit: git subtree - Detach (move) subdirectory into separate Git repository - Stack Overflow
# Prepare the old repo
cd <big-repo>
git subtree split -P <name-of-folder> -b <name-of-new-branch>
# Create new repo
mkdir ~/<new-repo> && cd ~/<new-repo>
git init
git pull </path/to/big-repo> <name-of-new-branch>
# Clean old repo
cd <big-repo>
git rm -rf <name-of-folder>Submodule #
Add #
# Default branch
git submodule add <remote-URL>
# Specify branch
git submodule add -b <branch-name> <remote-URL> <preferred-folder-name>
# Track a specific branch after init
git submodule set-branch --branch <branch-name> <folder-name>Initial pull submodule:
git submodule update --init --recursiveUpdate (Fetch) #
Update all submodules: (credit)
git submodule update --remoteShow list of all submodules: (credit)
# Either will work
git ls-tree -r HEAD
git submodule statusEdit #
Make changes to submodules (in .gitmodules), then do git submodule update --init --recursive --remote (credit)
[submodule "something"]
path = something
url = https://github.com/something/something.git
ignore = untracked
branch = new-branchChange the directory name for a submodule: (credit)
- Update
.gitmodules. - Run
git add .gitmodules - Run
git mv /path/to/old/directory /path/to/new/directory - Run
git add .
Change remote URL for a submodule: (credit)
git submodule set-url <path> <newurl>Remove #
The easy way: git rm <path-to-submodule>
The hard way: (credit)
- Delete the relevant section from the
.gitmodulesfile. git add .gitmodules- Delete the relevant section from
.git/config. git rm --cached <path-to-submodule>rm -rf .git/modules/<path-to-submodule>rm -rf <path-to-submodule>
Pre-Commit #
TBA…
Git Flow #
References:
- Learn Version Control with Git - Workflows with git-flow (中文版)
- petervanderdoes/gitflow-avh: AVH Edition of the git extensions to provide high-level repository operations for Vincent Driessen’s branching model
- Command Line Arguments · nvie/gitflow Wiki
Installation:
brew install git-flow-avhInitialise: (-d means using default branch names)
git flow init -dWrite new feature:
# Before beginning
git flow feature start my-new-feature
# After final commit
git flow feature finish my-new-featureDebugging #
UTF-8 character in filename are displayed in numbers #
git config --global core.quotepath false