CRPER
https://juejin.im/post/5de8d849e51d455808332166
前言
彙總下我在項目中高頻使用的git命令及姿勢。
不是入門文檔,官方文檔肯定比我全面,這裡是結合實際業務場景輸出。
使用的 Git版本:git version 2.24.0
git log
查看日誌,常規操作,必備
<code># 輸出概要日誌,這條命令等同於
# git log --pretty=oneline --abbrev-commit
git log --oneline
# 指定最近幾個提交可以帶上 - + 數字
git log --oneline -5
# 提供類似 GUI 工具的 log 展示
git log --graph --date=relative --pretty=tformat:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset'
/<code>
git status
查看工作區狀態的東東,不如GUI直觀,但是命令行也有一些用的
<code># 等同 git status --long,查看當前工作區暫存區變動
git status
# 概要信息 (--short)
git status -s
# 查詢工作區中是否有stash存在(暫存的東西),有則提醒該工作區有幾個 stash
git status --show-stash
/<code>
git checkout
用來切換到對應記錄的,可以基於分支,提交,標籤。
切提交和標籤一般用來熱修復或者老版本需要加新特性。
<code># 分支切換
git checkout dev # local branch
# 切換遠程分支
git checkout origin/test # remote branch
# 基於遠程分支創建本地分支,並跟蹤對應來自 'origin' 的遠程分支
git checkout --track origin/feature-test # new local branch wih remote branch
# 基於本地分支開出新分支
git checkout -b testbranch # new local branch with current branch
# 徹底丟棄某個文件的改動
git checkout -- file
# 放棄本地所有改動
git checkout .
# 切換上一個分支
git checkout -
/<code>
git commit
天天打交道的命令,這裡說一些很常見的姿勢
<code># 新修改的內容,添加到上次提交中,減少提交的日誌
# --no-edit:是跳過進入編輯器,直接提交
# git commit --amend這條命令等同於
# $ git reset --soft HEAD^
# $ ... do something tree ...
# $ git commit -c ORIG_HEAD
git commit --amend --no-edit
# 跳過校驗直接提交,包括任何 githooks
git commit --no-verify -m "xxx"
# 帶提交概要信息
git commit -m "xxx"
# 指定目錄格式提交
# -t <file>, --template=<file>
# 也可以從全局或者項目級別指定提交的模板文件
# git config [--global] commit.template xxx
# 現在一般都是 用社區的npm規範包,commitizen 和 commitlint 來規範提交
git commit -t templateFile
# 提交信息從文件讀取,可以結合上面的一起用
git commit -F
/<file>/<file>/<code>
git reset
不得不說,代碼回滾中這個命令也是用的很多,而且是 --hard
<code># 硬性回滾,簡單粗暴,直接拋棄回滾之後改動(log 還是有保留,內容不要而已)
git reset --hard commit_sha1
# 軟性回滾, 跟 rebase 常規用法差不多的效果,可以把提交的東西丟回暫存區和工作區,
# HEAD 的指向改變會對應的 commit,之後再考慮怎麼 commit
git reset --soft commit_sha1
# 軟回滾一個版本,可以理解為撤銷最近一次的 commit
git reset --soft HEAD~1
# 清除暫存區但保留工作區變動。
git reset --mixed commit_sha1
# 保留工作區和暫存區之間的差異。
git reset --merge commit_sha1
# 保留工作區和HEAD之間的差異
git reset --keep commit_sha1
/<code>
git revert
一般用於master 的代碼回滾,因為多人在上面協作,
revert 可以平穩的回滾代碼,但卻保留提交記錄,不會讓協作的人各種衝突!
<code># 回滾到某個 commit
git revert commit-sha1
/<code>
git rebase
變基在項目中算是很頻繁的,為什麼這麼說。
比如你開發一個新的 feature, 遵循最小化代碼提交的理念。
在整個功能開發完畢的時侯,會有非常多的 commit,用 rebase 可以讓我們的commit記錄很乾淨
<code># 帶 -i 可以進入交互模式,效果如下
git rebase -i git-sha1|branch(HEAD)
# 若是中間毫無衝突,變基則一步到位,否則需要逐步調整。
git rebase --continue # 提交變更後繼續變基下一步
git rebase --skip # 引起衝突的commits會被丟棄,continue提示沒有需要改動的也可以用這個跳過
git rebase --abort # 若是變基改殘廢了,但是走到一半,可以徹底回滾變基之前的狀態
/<code>
- pick: 是保留該 commit(採用)
- edit: 一般你提交的東西多了,可以用這個把東東拿回工作區拆分更細的 commit
- reword: 這個可以重新修改你的 commit msg
- squash: 內容保留,把提交信息往上一個 commit 合併進去
- fixup: 保留變動內容,但是拋棄 commit msg
- drop: 用的比較少,無用的改動你會提交麼!!!
突然發現截圖還有幾個新的行為,估計是新版本帶來的,從字面上就可以看出來大體的意思, 就是把回滾和打標籤這些放到變基中簡化操作。
溫馨提示
- 本地提交之前,最好把基準點變為需要合併的分支,這樣提交 PR/MR 的時侯就不會衝突(本地來解決衝突)
- 不要在公共分支上變基!!!一變其他協作者基本都一堆衝突!除非你們有很清晰的分支管理機制
git merge
<code># --ff 是指fast-forward命令,當使用ff模式進行合併時,將不會創造一個新的commit節點。
# --no-ff,保留合併分支的提交記錄,一般主幹用的比較多.
# --ff-only 除非當前HEAD節點為最新節點或者能夠用ff模式進行合併,否則拒絕合併並返回一個失敗狀態。
# --squash 則類似 rebase squash,可以把合併多個 commit 變成一個
git merge --no-ff branchName
/<code>
git pull
git pull中用的最多是帶--rebase(-r)的方式(變基形式拉取合併代碼),保持分支一條線。
默認的pull會走ff模式,多數情況會產生新的commit,部分參數與 merge提供一致。
git push
當本地分支存在,遠程分支不存在的時侯,可以這樣推送關聯的遠程分支
<code># 這樣會直接新建一個同名的遠程分支
git push origin localbranch
# 刪除遠程分支(--delete)
git push -d origin branchName
# 推送所有標籤
git push --tags
# 推送 commit 關聯的 tags
git push --follow-tags
# 強制推送(--force)
git push -f origin branchName # 一般合理的項目,主幹都做了分支保護,不會允許強推行為
# 有時候真的需要強推的時侯,但可不可以柔和一點呢?
# 就是當前遠程分支和你本地一致,沒有別人提交的情況下可以強推
# --force-with-lease: 若是遠程有人提交,此次強推失敗,反之成功
git push --force-with-lease
/<code>
git remote
這個東西用在你需要考慮維護多個地方倉庫的時侯會考慮,或者修改倉庫源的時侯
<code># 常規關聯本地 git init 到遠程倉庫的姿勢
git remote add origin url
# 新增其他上游倉
git remote add github url
# 修改推送源
git remote set-url origin(或者其他上游域) url
/<code>
git branch
該命令用的最多的就是刪除本地分支,重命名分支,刪除遠程分支了
<code># 分支刪除,拷貝,重命名,參數若是大寫就等同多了--force,強制執行
# -c, --copy : 複製分支,
# -C:等同於 --copy --force
# -d, --delete: 刪除分支
# -m, --move:移動或者重命名分支
git branch -d branchName
git branch -M oldBranch newNameBranch
# 手動指定它的當前分支的上游分支,兩個寫法一致的
# 有關聯一般也有取消關聯,--unset-upstream
git branch --set-upstream-to=origin/xxx
git branch --set-upstream-to origin xxx
/<code>
git stash
暫存用的最多時侯就是你擼代碼擼到一半,突然說有個緊急 BUG 要修正。
或者別人在你這裡需要幫忙排查代碼,你這時候也會用到。
強烈建議給每個 stash 添加描述信息!!!
<code># 緩存當前工作區的內容到stashName, save 這個現在不怎麼推薦用,圖方便也能用
# -a|--all: 除了未跟蹤的文件,其他變動的文件都會保存
# -u|--include-untracked:包括沒有添加到暫存區的文件
git stash save stashName
git stash -u save stashName
# 現在基本推薦用 push,因為有 pop,語義上和維護上更清晰
# 上面有的參數,它也有,還有-m 來備註這個 stash 的大概情況
git stash push -m "更改了 xx"
# 有保存那肯定也有取用的
# pop: 取會刪除對應的保存記錄
# apply: 取但保留記錄
# 0就是--index,這個東西哪裡來的呢?
git stash apply stash@{0}
git stash pop stash@{0}
# 查看stash 保存記錄
# eg: stash@{0}: On dev: 測試
git stash list
# 只想刪除暫存記錄怎麼辦:
# clear : 清空所有 stash
# drop: 清除指定的 stash
git stash clear # 慎用!
git stash drop stash@{0}
# 想看 stash 做了什麼改動,類似簡化版的git diff
git stash show stash@{0}
/<code>
git reflog
這個命令的強大之處,是記錄了所有行為,包括你 rebase,merge, reset 這些
當我們不小心硬回滾的時侯,或變基錯了都可以在這裡找到行為之前的commit,然後回滾。
當然這個時間回溯也只在本地有用,你推送到遠程分支的破壞性改動,該涼還是得涼。
<code># 最近五次行為,不帶-n 則默認所有
git reflog -5
/<code>
git cherry-pick
這個東西你可以理解為你去買橘子,你會專門挑一些符合心意的橘子放到購物籃中。你可以從多個分支同時挑取部分需要的 commit 合併到同一個地方去,是不是賊騷。這貨和變基有點類似,但是僅僅類似,挑過來的 commit 若是沒有衝突則追加。有衝突會中斷,解決後 --continue
<code># 在當前分支挑其他分支的 commit,把那部分的變動那過來
git cherry-pick commit-sha1
# 支持一次性拿多個
git cherry-pick master~4 master~2
# 支持區間, 區間中間是 ..
git cherry-pick startGitSha1..endGitSha1
# --continue:繼續 pick,一般有衝突解決後才需要這樣
# --skip:跳過這次進入隊列下一次行為
# --abort : 完全放棄 pick,恢復 pick 之前的狀態
# --quit: 未衝突的自動變更,衝突的不要,退出這次 pick
# 這幾個狀態跟變基差不多,解決衝突繼續,跳過處理,放棄這次pick,不輸出錯誤
/<code>
git rm
這個命令在舊的版本用的比較最多的姿勢是為了重新索引.gitignore 的範圍
<code># 刪除某個文件的索引
# --cache 不會刪除硬盤中的文件,只是 git 索引(緩存)的關係!!!
git rm --cache -- file
# 遞歸清除全部所有索引(也可以理解為緩存吧),這個姿勢適合重新讓.gitignore 新範圍生效
git rm -r --cached .
git add .
git commit -m "xxx"
/<code>
git rev-parse
這個估計一般人用的不是很多,可以通過這個快速獲取部分git 倉庫的信息
我在弄腳本的時侯就會從這裡拿東西
<code># 獲取最新有效的commit
# --short:顯示七位的 sha1,不帶就是全部
# --verify: 校驗是否有效commit
# HEAD: 當前分支的head 指向
git rev-parse --short HEAD --verify
# 顯示倉庫的絕對路徑
git rev-parse --show-toplevel #eg: /Users/linqunhe/Code/aozhe/thinking-ui
# 顯示版本庫.git 目錄所在的位置
git rev-parse --git-dir
# 顯示所有關聯引用的 git sha1
git rev-parse --all
/<code>
git diff
對於這個命令,在終端比對用的不是很頻繁,除了少量改動的時侯可能會用這個看看。
其他情況下我更傾向於用 GUI 工具來看,因為比對更加直觀。
總結
git 的常用命令其實很好掌握,很多命令都有 Linux 的影子。
列出來的命令都是高頻使用的,或許有一些更騷的姿勢沒有摸索到,
有更好建議的,或者發現不對之處的請留言,會及時修正,謝謝閱讀。
閱讀更多 大架構文摘 的文章