技術筆記(8)git的部分進階功能
-
學習筆記:
-
與分支有關的git操作 branch、checkout、merge
-
檢視分支:
- 檢視當前分支資訊:git branch
- 檢視遠端分支資訊:git branch -r
- 檢視所有分支資訊,包括本地和遠端:git branch -a
-
分支與分支:
- 切換到某分支:git checkout
- 從當前節點新建一個分支:git checkout -b
git - 刪除掉一個分支:git branch -d
- 將某個分支合併到當前分支:git merge
- 切換到某分支:git checkout
-
回到過去或將來某個提交節點:
-
回撤到某個提交點,檔案也回到那個狀態:
git reset --hard
-
回撤到某個提交點,檔案保留被修改後的狀態:
git reset --soft
-
-
-
處理merge conflict
-
少量已修改的檔案的處理方式:
- 首先 cd <衝突檔案所在目錄>,例如:cd ~/Documents/Sample
- vi <衝突檔名>,例如:vi a.txt
- 輸入i,進入insert模式,將想要的最終結果修改好
- 按esc鍵退出insert模式,再按:鍵進入命令模式
- 輸入wq,退出該檔案
- 再次將衝突的檔案add、commit之後,即順利解決merge conflict
-
大量且難修改可供參考的處理方式:
- git checkout --ours <路徑或檔名> 保留當前分支的內容
- git checkout --theirs <路徑或檔名> 保留對方分支的內容
-
-
忽略無須版本管理的檔案 .gitignore
-
例如:在Unity遊戲開發中,大部分時候只需要管理專案裡的Asset、ProjectSetting、UserSetting檔案。而可由Unity自動生成的且佔容量極大的Library檔案就沒有版本管理的必要。
-
在.gitignore檔案中的輸入格式:
- 忽視某個特定檔案:memo.txt
- 忽視特定擴充名:*.avi
- 作為例外情況,不忽視該檔案:!study.avi
- 忽略特定目錄:study_asset/something_good/
- 忽視根目錄下的子目錄:/sunofbeatch/
- 註釋行:用兩個#擴起來
-
-
撤銷過去的提交,回滾提交 Revert
- 實際上是在現在提交一個相反的,與過去的目標提交相抵消,並非直接讓過去的提交消失
- git revert
- git revert HEAD~3 逆轉當前分支當前節點往回數的第三次提交
- git revert
^... 把這兩次提交之間的所有提交以此逐個逆轉 - git revert -n
^... 用一次提交逆轉這些提交 - revert中發生衝突,與merge中衝突的處理方法一致
-
提交歷史合併為一條直線,變基 Rebase
-
rebase的邏輯是把所有歷史提交都重新生成新的提交,所以提交id會改變
-
但改變提交歷史有一定的風險,最好不要把遠端倉庫已有的分支進行rebase,否則用普通的方法就無法成功推送了
-
引用知乎使用者“一個小號”的舉例:
-
原連結:https://www.zhihu.com/question/36509119/answer/1990894567
一個好的 commits history,應該是這樣的:
* e2e6451 (HEAD -> master) feture-c finished |\ | * 516fc18 C.2 | * 09112f5 C.1 |/ * c6667ab feture-a finished |\ | * e64c4b6 A.2 | * 6058323 A.1 |/ * 2b24281 feture-b finished |\ | * c354401 B.4 | * 4bfefb8 B.3 | * eb13f72 B.2 | * c2c62b9 B.1 |/ * bbbba82 init
而不是這樣的:
* 9f0c13b (HEAD -> master) feture-c finished |\ | * 55be61c C.2 | * e18b5c5 merge master | |\ | |/ |/| * | ee549c2 feture-a finished |\ \ | * | 51f2126 A.3 | * | 72118e2 merge master | |\ \ | |/ / |/| | * | | 6cb16a0 feture-b finished |\ \ \ | * | | 7b27b77 B.3 | * | | 3aac8a2 B.2 | * | | 2259a21 B.1 |/ / / | * | 785fab7 A.2 | * | 2b2b664 A.1 |/ / | * bf9e77f C.1 |/ * 188abf9 init
也不是這樣的:
* b8902ed (HEAD -> master) C.2 * a4d4e33 C.1 * 7e63b80 A.3 * 760224c A.2 * 84b2500 A.1 * cb4c4cb B.3 * 2ea8f0d B.2 * df97f39 B.1 * 838f514 init
-
-
但說實話,什麼時候用,怎麼用,還是有一定疑惑
-
另記錄一個可供參考的git分支模型:
- https://zhuanlan.zhihu.com/p/385969268
-
-
合併多個提交,互動式變基 Squash
- 把幾個相連的提交合併成一個新的提交,衝突解決與merge類似
- 同樣的,由於涉及更改提交歷史,慎重啊我的朋友
- 還有不能對已經在遠端倉庫中存在的提交進行互動式變基
-
拉取的具體實現 Pull
- 實際上先從遠端倉庫的遠端分支fetch到本地倉庫裡看不到的遠端跟蹤分支,再merge到我們能看到的本地分支。
- 有個中介
- 而只fetch的話,就是隻獲取遠端分支的變化,先不急著改到本地分支
-
暫存未提交的內容,貯藏 Stash
- 當前功能做到一半,但還不適合提交。此時需要先去做另一部分的功能,或者merge另一個提交。此時就可以先把這部分沒做完的貯藏起來,先搞定別的,再回來繼續慢慢做。
-
從其他分支上獲取特定提交,遴選 cherry-pick
- 即把另一個分支的某次提交,直接拿來吧你!
-
detached HEAD狀態
- 指不屬於任何分支的無從屬狀態,一般發生於reset到過去的節點後,又做了一部分修改並提交,導致脫離所有的現有分支。
- 在此狀態下直接切換到某一分支的話,本次提交會直接丟失。
- 解決:新建一個分支去接管
-