技術筆記(8)git的部分進階功能

静候霜白發表於2024-03-12

技術筆記(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 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到過去的節點後,又做了一部分修改並提交,導致脫離所有的現有分支。
      • 在此狀態下直接切換到某一分支的話,本次提交會直接丟失。
      • 解決:新建一個分支去接管

相關文章