git淫技奇巧
前言
新的一年,開啟2023
的第一篇。git
命令很多,但平時用的最多的一定是下邊幾個
git init
git pull
git add .
git commit -m 'xx'
git push
沒錯,就是這幾個命令幫助大家完成了工作,簡單且親切。但只會這幾個命令難以應付工作的複雜度,如:
- 提交記錄複雜且混亂怎麼辦
- 單個功能多次提交,其實只完成一個功能怎麼辦
- 只需要某個分支的某幾次提交怎麼辦
- 強推程式碼覆蓋掉丟失程式碼怎麼辦
so,瞭解更多的命令會讓這些事情事半功倍
cherry-pick
cherry-pick
是一個非常實用的命令,他的作用就是可以將某次的提交記錄合併到需要的分支去。
本司因為專案會存在好幾個環境,常常切換完分支後忘記切回來,導致一些改動沒有在需要的分支進行,這個時候就可以使用cherry-pick
將需要的程式碼合併過來,比起手動操作cherry-pick
簡單且安全
git cherry-pick <commitHash>
rebase
rebase
命令相對較多,而且也需要有一定了解入手才好,不然會把隊友心態搞崩的,rebase
和merge
的最終目的都是合併程式碼,但是考慮的維度不一樣
-
merge
簡單無腦,有衝突處理就好,不會變基(其實就是不會改變提交記錄的hash值),對新手及其友好,提交記錄比較詳細,但是提交記錄也會相對混亂,不利於查詢記錄。複雜場景難以支援 -
rebase
最主要的問題是會變基,多人合作時需要注意,提交記錄便於後期維護查詢,可以支援較多複雜場景
基礎使用
git rebase <branch>
如果branch
有新的提交,就會涉及到變基,變基就會導致提交記錄即hash
值的變化,如果這些變化的記錄在變基前已經提交到遠端,再次推送程式碼就要強推git push --force
,強推程式碼也存在風險(推送前有新的提交),所以最好使用git push --force-with-lease
若是有衝突rebase
會停止,解決完衝突後執行git add .
後無需再次commit
,執行git rebase --continue
即可。建議不熟悉的同學先單獨玩一下,瞭解清楚什麼叫做變基
取消此次rebase
,執行git rebase --abort
合併commit記錄
git rebase -i HEAD~<num>
或者
git rebase -i <commitHash>
需要合併幾次提交num
填寫幾即可,常用來處理一個功能多次提交,且諸多提交毫無意義,如
asda3365 登入3
xczx3365 登入2
16cxc365 登入1
164fxcx1 註冊3
164f3123 註冊2
164f5456 註冊1
這樣的記錄可以合併為註冊
和登入
兩條記錄,此vim
操作介面如下,將不需要的記錄改為s
(suqash
表示將當前記錄與上一個記錄合併),wq
儲存後會彈出第二張圖的介面,將commit
資訊改為自己能看懂的後儲存即可
onto
git rebase --onto <newparent> <oldparent>
git rebase --onto
後可以接收三個引數,新增第三個引數時會生成新的分支,並指定HEAD
的指向,沒有相應的場景理解,所以我們先了解兩個引數的情況。兩個引數時第一個引數是新的父級,第二個是舊的父級,改變父級的指向,舉兩個栗子
栗子一
如上圖,在feature2
分支上rebase
到master
即
git rebase master
之後提交記錄便是A-B-C-D'-F'-G'
,因為D
是feature2
和feature1
的共同提交記錄,若是不想存在D
的記錄則可以執行如下命令
git rebase --onto master feature1
之後提交記錄便是A-B-C-F'-G'
,改變feature2
父級為master
栗子二
目前有如下提交a-b-c-d-e-f
62d13c5 (HEAD -> master) f
49978ef e
e7bfae0 d
9b87061 c
2bded9a b
ef4f20d a
如果想刪除c
這條記錄可以執行,其含義是將舊父級c
更新為新的父級b
git rebase --onto 2bded9a 9b87061
而後提交記錄變更為a-b-d'-e'-f'
,commitHash
從d
開始變化,記錄c
消失
faec99a (HEAD -> master) f
61a8631 e
50cca8f d
2bded9a b
ef4f20d a
pull --rebase
git pull 相當於 git fetch + git merge
git pull --rebase 相當於 git fetch + git rebase
--force-with-lease
rebase
那邊也提到了強推程式碼,強推程式碼一直是不被推薦的,因為即使操作的再快也無法保證在提交之前有其他的提交,所以git
提供了新的命令
git push --force-with-lease
此命令提交前會檢查是否有新的提交,若有新的提交則會提交失敗
注意--force-with-lease
失敗後再執行一次也會強制提交覆蓋
reset、revert
reaset
和revert
均可以用作版本回退,適用場景不同
reaset
回退版本後會丟失該版本之後的提交記錄,推送至遠端時需要強推程式碼
有如下提交
5f21366 (HEAD -> master) d
a542921 c
795a7b0 b
4001e19 a
回退到b
git reset --hard 795a7b0
提交記錄如下
795a7b0 (HEAD -> master) b
4001e19 a
revert
反做版本後不會丟失提交記錄,會產生新的反做記錄
有如下提交
5f21366 (HEAD -> master) d
a542921 c
795a7b0 b
4001e19 a
反做提交記錄b
git revert -n 795a7b0
有衝突,繼續
git add .
git revert --continue
提交記錄不會丟失
471cceb (HEAD -> master) Revert "b"
5f21366 d
a542921 c
795a7b0 b
4001e19 a
所以當版本只是臨時切換時,revert
比reset
更合適
stash
工作中常遇到開發了一部分需要到其他分支處理問題的情況,但本次改動又不足以提交,這個時候就需要stash
暫存程式碼,等問題處理完畢在切回來繼續開發,涉及到的命令如下
git stash // 暫存
git stash save "message" // 暫存 + 備註
git stash pop // 應用最近一次暫存的修改,並刪除暫存的記錄
git stash apply // 應用某個儲存, git stash apply [email protected]{$num} ,num預設為0
git stash list // 檢視所所有暫存
git stash clear // 刪除所有暫存
merge
合併分支,並將分支上的提交合併成一次提交,合併過來後續通過git add .
和git commit -m 'xx'
重新提交程式碼
git merge <branch> --squash
commit
commit
資訊填寫有誤可以通過以下命令修改
git commit --amend
結語
多操作有助於理解