git淫技奇巧

語言: CN / TW / HK

前言

新的一年,開啟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命令相對較多,而且也需要有一定了解入手才好,不然會把隊友心態搞崩的,rebasemerge的最終目的都是合併程式碼,但是考慮的維度不一樣

  • 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操作介面如下,將不需要的記錄改為ssuqash表示將當前記錄與上一個記錄合併),wq儲存後會彈出第二張圖的介面,將commit資訊改為自己能看懂的後儲存即可

1.png

2.png

onto

git rebase --onto <newparent> <oldparent>

git rebase --onto後可以接收三個引數,新增第三個引數時會生成新的分支,並指定HEAD的指向,沒有相應的場景理解,所以我們先了解兩個引數的情況。兩個引數時第一個引數是新的父級,第二個是舊的父級,改變父級的指向,舉兩個栗子

栗子一

3.jpg

如上圖,在feature2分支上rebasemaster

git rebase master

之後提交記錄便是A-B-C-D'-F'-G',因為Dfeature2feature1的共同提交記錄,若是不想存在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'commitHashd開始變化,記錄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

reasetrevert均可以用作版本回退,適用場景不同

  • 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

所以當版本只是臨時切換時,revertreset更合適

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

結語

多操作有助於理解