1 - Git
git
# mkdir blog && cd blog
# git init
# git remote add origin git@github.com:tukeof/tukeof.github.io.git
git clone git://github.com/tukeof/tukeof.github.io.git blog
cd blog
git add *.md
git commit -m 'initial project version'
git push -u origin master
remote
# 添加一个新的远程Git存储库
git remote add <shortname> <url>
git remote add origin git@github.com:tukeof/tukeof.github.io.git
git remote add origin ssh://username@127.0.0.1/reponame
git remote -v
git remote update
# 也会改变所有远程跟踪分支名称
git remote rename branch1 branch2
git remote rm branch1
git remote show origin
# 在本地新建一个tmp分支,并将远程origin仓库的master分支代码下载到本地tmp分支
git fetch origin master:tmp
# 比较本地代码与刚刚从远程下载下来的代码的区别
git diff tmp
# 合并temp分支到本地的master分支
git merge tmp
# 删除tmp分支
git branch -d tmp
# 取回远程主机某个分支的更新,再与本地的指定分支合并
git pull origin master:<branch_name>
add, rm, commit, log
# -a,--all,自动暂存已修改和删除的文件
git commit -a -m 'message'
# 从工作目录和暂存区域中删除文件
git rm <file>
# 仅从暂存区域中删除目录
git rm -r -cached <dir>
git mv README.md README
# mv README.md README
# git rm README.md
# git add README
# --amend
# 占用当前暂存区域并将其用于提交。如果自上次提交后没有进行任何更改,那么快照将看起来完全相同,并且将更改的是提交消息。
git commit --amend
# 撤销对暂存区的更改
git reset HEAD <file>
# 丢弃工作目录中的更改
git checkout - <file>
svn
# clone
svn co https://localhost/user/repo
svn co https://localhost/username/repo -r some_version
svn checkout https://localhost/username/repo/dir1/dir2/proj1
arc
# Phabricator
git clone https://github.com/phacility/libphutil.git
git clone https://github.com/phacility/arcanist.git
# 将 some_install_path/arcanist/bin 加入到$PATH变量中
# 权限认证
arc install-certificate
arc set-config editor "vim"
# 开分支(git branch),或查看当前分支和关联的 revision
arc feature
# 创建或更新 revision,范围是 origin/master 到最新提交,包括暂存区的内容
arc diff
# 所有 revision 和状态
arc list
# 当前分支上的 commit 会全部被 land, 会先 pull --rebase 再 push
arc land
# 查看 diff 的范围等信息
arc which
Phabricator
// apply patch to current branch
arc patch --diff <patch_version_number> --nocommit --nobranch
2 - Git Checkout
branch
# list all branch, include local and remote
git branch -a
# delete branch
git branch -d <local_branch>
git push origin --delete <remote_branch>
# list tags
git log --pretty=oneline --abbrev-commit
git show <tag_name>
# tag a tag based on a commit, default cid is `HEAD`
git tag <tag_name> <commit_id>
git tag -a <tag_name> -m "message for tag" <commit_id>
# dangerous operation, it's better no-modification until checkout to `HEAD`
git checkout <tag_name>
#
git checkout -b <bra_name> <tag_name>
git tag -l "<prefix>*"
git push origin <tag_name>
# push all tags
git push origin --tags
# delete a local tag
git tag -d <tag_name>
# delete a remote tag
git push origin :refs/tags/<tag_name>
stash
# list the stash entries that you currently have. stash@{0} is the latest entry
git stash list
# save all uncommitted changes
git stash
# apply all uncommitted changes
git stash apply
merge-base
git merge-base origin/master HEAD
rebase
# Assume the following history exists and the current branch is "topic":
# A - B - C topic
# /
# D - E - F -G master
git switch topic
git rebase master
git rebase master topic
# would be
# A'--B'--C' topic
# /
# D---E---F---G master
graph LR
E --> A --> B --> C(C topic)
D --> E --> F --> G(G master)
mkdir git-repo && cd git-repo
git init --bare
export remote_url=$(pwd)
cd ..
git clone $remote_url git
cd git
# D
echo $(uuidgen) > D && git add . && git commit -m 'D' && git push -u origin master
# D - E
echo $(uuidgen) > E && git add . && git commit -m 'E' && git push -u origin master
git checkout -b topic
git switch master
# D - E - F
echo $(uuidgen) > F && git add . && git commit -m 'F' && git push -u origin master
# D - E - F - G
echo $(uuidgen) > G && git add . && git commit -m 'G' && git push -u origin master
git switch topic
# A
# /
# D - E - F
echo $(uuidgen) > A && git add . && git commit -m 'A' && git push -u origin topic
# A - B
# /
# D - E - F
echo $(uuidgen) > B && git add . && git commit -m 'B' && git push -u origin topic
# A - B - C topic
# /
# D - E - F master
echo $(uuidgen) > C && git add . && git commit -m 'C' && git push -u origin topic
revert
# revert to previous commit
git revert <previous-commit>
reset
# discard changes and reset files to master
git reset --hard origin/master
git reset --hard HEAD
# or save changes
git reset --soft HEAD
# discard changes and reset to current branch
git checkout . && git clean -xdf
3 - Git Config
config
git help config
man git-config
git config --list
# 提交时转换为LF,检出时转换为CRLF
git config --global core.autocrlf true
# 提交时转换为LF,检出时不转换
git config --global core.autocrlf input
# 提交检出均不转换
git config --global core.autocrlf false
# 拒绝提交包含混合换行符的文件
git config --global core.safecrlf true
# 允许提交包含混合换行符的文件
git config --global core.safecrlf false
# 提交包含混合换行符的文件时给出警告
git config --global core.safecrlf warn
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.s status
git config --global alias.unstage 'reset HEAD - '
git config --global alias.last 'log -1 HEAD'
# git config --global alias.l '!ls -lah'
git config --global alias.url 'remote get-url --all origin'
# git config --global core.editor "'C:/Options/Notepad++/notepad++.exe' -multiInst -nosession"
git config --global core.editor vim
.gitconfig
[user]
name = yourname
email = youremail
[http]
#proxy = socks5://127.0.0.1:1080
[https]
#proxy = socks5://127.0.0.1:1080
[core]
autocrlf = input
safecrlf = true
[alias]
co = checkout
br = branch
ci = commit
s = statcus
last = log -1 HEAD
lg = log --graph
url = remote get-url --all origin
.ssh/config
ssh-keygen -t rsa -b 4096 -C "youremail"
host *
AddKeysToAgent yes
UseKeychain yes
TCPKeepAlive yes
ServerAliveInterval 60
ServerAliveCountMax 5
host github.com
user git
hostname github.com
port 22
identityfile ~/.ssh/id_rsa
4 - Git Hook
pre-commit
# https://pre-commit.com/#usage
pip install pre-commit pre-commit-hooks
# write to .git/hooks/pre-commit
pre-commit install
exclude: >
(?x)(
^a/|
^b/c/|
^d/e/__init__.py
)
default_language_version:
python: python3
repos:
- repo: https://github.com/PyCQA/isort
rev: 5.9.3 # tag
hooks:
- id: isort # sort imports
- repo: https://github.com/psf/black
rev: stable
hooks:
- id: black # code formatter
- repo: https://github.com/pycqa/flake8
rev: 4.0.1
hooks:
- id: flake8 # check the style and quality
language_version: python2.7
stages: [manual]
pre-push
5 - Git How-To
undo untracked
git reset --hard <commit_id>
# show which will be removed, include untracked directories
# -n --dry-run, Don't actually remove anything
git clean -d -n
# delete anyway, no confirm
git clean -d -f
undo not staged change
(removal or modification)
# in stage space but changed by external
# touch a && gti add a && rm a, then a has not staged changes
# discard changes in working directory
git restore <files>
# or
git checkout <files>
# update what will be committed
git add <files>
# caused by removal
git rm <files>
# or
git rm --cached <files>
undo add
# undo stage
git restore --staged <files>
# remove from staged space
git rm --cached d
undo commit
# message
git commit --amend -m 'message which will cover the old one'
# undo commit, but not undo add
# --soft, do not touch the index file nor the working tree
# --hard, match the working tree and index to the given tree
# --mixed, reset the index but not the working tree (default)
git reset --soft HEAD^
# undo <n> commits
git reset --soft HEAD~n
merge commit
# reapply n commits
git rebase -i HEAD~n
# pick
# squash
# ...
# squash
git add .
git rebase --continue
# git rebase --abort
git push --force
delete the last commit
# where git interprets x^ as the parent of x
# + as a forced non-fastforward push.
git push master +<second-last-commit>^:master
# or
git reset HEAD^ --hard
git push master -f
delete the second last commit
# this will open an editor and show a list of all commits since the commit we want to get rid of
# simply remove the line with the offending commit, likely that will be the first line
git rebase -i <second-last-commit>^
git push master -f
6 - Git Log
status
git init --bare /path/to/repo/.git
# git remote add origin /path/to/repo/.git
git clone /path/to/repo
# 显示工作目录和当前HEAD提交之间存在差异的路径
git status
# --short
# A added.c
# M modified.cc
# R renamed.h
# D deleted.hh
git status -s
diff
# 将工作目录中的内容与暂存区域中的内容进行比较
git diff
# --cached,将暂存更改与上次提交进行比较
git diff --staged
git diff oldCommit..newCommit
log
# 按反向时间顺序列出在该存储库中进行的提交
git log
# -p,patch 显示每次提交中引入的差异(补丁输出)
# -2 仅显示最后两个条目
# --stat 在每个提交条目下方打印一个已修改文件的列表,已更改的文件数以及这些文件中添加和删除的行数
# --shortstat 仅显示--stat命令中已更改/插入/删除行。
# --pretty=oneline 在一行上打印每个提交
git log --pretty=oneline
# 短哈希 - 作者名,日期 :注释
git log --pretty=format:"%h - %an, %ar : %s"
# --graph 添加一个很好的小ASCII图,显示您的分支和合并历史记录
git log --pretty=format:"%h %s" --graph
git log -<n>
# --since, --after
# --until, --before
git log --since=2.weeks
git log --since="2008-01-15"
git log --since="2 years 1 day 3 minutes ago"
# --committer 执行提交的用户
# --author 作出修改的用户
# 在提交消息中搜索关键字
git --author=<author> --grep="keyword"
# 可以指定--author和--grep搜索条件的多个实例
# 这将限制提交输出到与任何--author模式和任何--grep模式匹配的提交
# --all-match 会进一步将输出限制为与所有--grep模式匹配的提交
# 仅显示提交添加或删除与字符串匹配的代码的提交
git log -S function_name
Option | Description of Output |
---|
%H | Commit hash |
%h | Abbreviated commit hash |
%T | Tree hash |
%t | Abbreviated tree hash |
%P | Parent hashes |
%p | Abbreviated parent hashes |
%an | Author name |
%ae | Author email |
%ad | Author date (format respects the –date=option) |
%ar | Author date, relative |
%cn | Committer name |
%ce | Committer email |
%cd | Committer date |
%cr | Committer date, relative |
%s | Subject |