關於Git工具亂彈

For 高老師Git課程簡易項目紀錄,此篇比較適合對Git有概念且會操作的人。另外高見龍講課真的專業級,可以講得很輕鬆詼諧,然後切入中心觀念。針對講課項目內容去展開細項。

  • init / config 跳過

    • git config list 經驗說
      • 在某些專案中,當有多層發包需求時,承包商可能會希望隱藏實際的開發情況,讓業主無法看出這些多層發包的細節。使用 git config local 可以針對特定專案進行配置,這樣即使專案中有不同的開發者進行 commit
        • 例如,你可以為某個專案設置統一的提交者名稱和郵件地址:
  • git add . (all file attatch) 很危險又不負責任的指令,有可能把沒做完的檔案Attach

    • 什麼時候做Commit ? 完成feature,或是做一個段落想commit就commit..? 未做完會下wip(Work In Progress)註解。
    • commit message 是什麼?
    • . here 當下資料夾路徑所有檔案做Attach
    • all 整個專案檔案做Attach
  • git commit (https://www.conventionalcommits.org/en/v1.0.0-beta.3/)

  • 你覺得什麼是git commit ? 為何要設計做兩段式操作(add、commit)?

    • 講師舉廚娘在做料理SOP,做菜過程中分步驟去拍照,寫講義。拍照可以視為add,而commit是根據拍照開始具體定稿這個步驟的內容。所以git在此的設計原因在於讓開發者可以彈性地去歸類與紀錄開發功能。而git commit具體操作其實就是建置快照(只針對差異性做存取),而版本就是每個時間點的快照。
  • git checkout (殊途同歸)

  • 分散式?

    • git為典型的分散式版控
      • 容錯性高 : 每個人都有完整的版本庫副本 (就算Git),就算版控Server掛了,每個開發者在本地都擁有完整的專案歷史紀錄和所有版本的檔案(包括 .git 資料夾 中的完整版本庫信息),還是可以做同步程式碼的動作。
      • 可離線操作
  • Git Graph

  • 貼紙:分支是Git很大的賣點,Git的分支很便宜!!

    • 便宜意思是,一個分支只會佔電腦40bytes空間,所以他建置成本很便宜。
    • 貼紙 : 另外,他有點像是貼紙的概念當你創建一個新分支時,實際上你只是貼了一個新標籤,這個標籤指向當前的提交!!你可以很輕鬆地在多個分支之間切換,並在每個分支上進行獨立的開發工作。由於每個分支只是一個指向提交的指標,當你切換分支時,Git 只需要更新這個指標來指向不同的提交。
    • 分支實際會是.git/refs/heads下的檔案(檔名即是分支名稱)
    • 資料夾與檔案其實是一樣的東西,例如你新增一個aa檔案,你就無法在同一個路徑新增一個aa資料夾。而git branch資料夾也是一樣的設計概念操作.
    • Git的分支不是一個資料夾每新增一個分支,heads下就會多一個檔案,所以分支其實很小。真實的Snapshot會放在objects資料夾下。
    • 分支,只是貼在某個commit上的貼紙
    • -HEAD檔案,refs/heads/分支 (git checkout 分支name)

image

  • git switch 與 git restore 為 git checkout 的分別功能?

  • 孤兒分支,

  • git checkout - (兩分支切換,-表上一個分支)

  • 忘記切換分支,就做commit直接改分支name(就像改檔案名稱一樣),例如要commit dev,但commit 到 main分支。直接用git command或是用Tool去rename。把dev改成main,main改成dev即可。 不過! 絕對不要到.git file去改檔名!!!

  • git merge ,撕貼紙去貼領一個commit刪bracnh就像把貼紙撕掉一樣如果要把

  • add cat 2 (main) (cat)

  • add cat 1

  • add ee

  • add dd

如果要把main貼紙貼到ee很簡單

  1. 先刪除main
  2. 然後在add ee新增貼紙 main切分支
  • Merge合併,a 合併 b,b合併a有什麼不同 (合併有點像是在移動貼紙)
    • 誰往前走不一樣 (往下節點走)
    • a 合併 b,節點內容就是bb合併a,節點內容就是a.(例如下狗合併貓,內容就是貓的檔案變更紀錄)
    • 看起來沒什麼不同,那誰要主?

image

  • Rebase 合併

    • Re(變換) + base(根基)。下例,dog,cat base為同一個點。rebase有點像是

      image

    • 如果你亂砍分支..會發生節點,沒有被指向,所以他會被隱藏,例如下面,你把dog砍掉, add dog2 add dog 1就會消失

      image

      如果要復原,可以重新Create bracnh 指向原節點

      image

      image

      git 沒有刪除commit這件事情,commit不見其實是被隱藏起來!

    • rebase細部流程如下
      image

    image

  • Merge跟Rebase合併有什麼優點

    • Rebase會造成歷史紀錄被修改
    • Rebase新手不容易Recovery
    • 如果在意歷史紀錄用Merge,不在意的話就rebase**
  • Merge衝突發生處理

    • git merge abort 放棄合併
    • 處理衝突決定保留所有還是做為條修改..在重新git add..跟commit
  • 對Reset誤解
    C1->C2->C3->C4->C5(M*)

    • git reset(有become的意味) xxnode
      • mixed (預設值) M*移到C3,C4,c5放到工作目錄
      • soft M*移到C3,C4,c5放到暫存區
      • hard M*移到C2,C3,C4就刪掉了(不見隱藏)
  • 聽說 hard不要用

  • reset mix / soft

    • 還原到未commit,讓我們可以增加檔案然後重新再送commit
    • 還原的點常用的位置
      • HEAD^ 退一個commit的parent (git reset HEAD^ hard)
      • HEAD ^^ 退2個Commit
      • HEAD~[number] 只退回數量的commit (git reset HEAD~8 hard)
      • git reset 930 hard (如果知道點位hard照程成git flow跑掉,都可以recovery,只要重新reset到最初的節點.)..這樣看來reset還真有become的意味
  • 符號說明

    • ^ caret
      • Head^ = Head^1 往前第一個parent移動
      • Head^2 往前第二個parent移動
    • ~ tilde
      • 實質上往前第幾個parent移動
  • 經過rebase的合併要怎麼進行reset

    • ORIG_HEAD 記錄比較重大操作的軌跡,但只會記錄最後一次紀錄
    • 所以可以透過這個來做退回
    • git reset ORIG_HEAD hard
    • 不小心使用hard模式Reset了,救得回來ㄇ? YES.
  • git commit amend => 修正最後的commit

git reflog > head 移動軌跡

小練習(bracnh2)

  • 開bracnh2

  • 開merge合併

  • 刪除此次合併,回到合併前狀態

  • 要怎麼取消剛剛這次合併.

    • merge -> git reset
    • rebase -> 要找到剛剛的節點

問題集

以下哪一個指令會造成HEAD移動
git checkout
git merge
git rebase..

若刪除已經合併的分支會發生什麼問題?
若刪除尚未合併的分支會造成什麼問題?

  • 節點合併 & 節點修改 透過rebase (互動式rebase)

    • 修改結點commit訊息
      • EDITOR ='code wait' git rebase bb0c

    Windows : $env:EDITOR="code wait" git rebase interactive bb0c9c2ab94514d95bb898c51b3cedb1c0675320

image

image

合併結點 (壓縮cat1&cat2,壓縮dog1&dog2)

原先
image

更改後
image
image
image
image
image

更改完後

image

更改完後,線上跟Local會對不起來,如果這支分支feat只有你再維護可以直接-f push。但千萬不要強推共用分支..

接著我們要將這個node,拆成cat1,cat2一個,cat3,cat4一個 (看影片..帶整理)


遠端(Remote部分)

新增遠端節點名稱
git remote add origin git@
推到遠端main
git push origin main

  • u 代表,上游的分支自動配置
    git push -u origin main

如果你近期常push哪一個分支ex feat/123
git push -u origin feat/123

git push origin main其實是 git push origin main:dev (遠端:dev),本地的main推上去形成一個dev分支

所以 git push origin main 其實是 git push -u origin main:main 本地的main推上去變main分支 (所以你想遠端分支名稱與本地一樣,在同個Name一樣才可以簡寫)

git push origin :dev,把空的推上去形成dev..表把遠端dev刪除

git pull origin main ,pull其實不是拉回來的意思pull =git fetch + git merge

git fetch origin main,把遠端main拉下來,但Local節點是舊的,此時就要做merger..單純的fetch不會有衝突,merge才會以機會發生衝突

git pull rebase = git fetch + git rebase

PR跟MR有什麼不同? Pull = (Fetch+Merge), MR(Merge),其實只是角度不同但最終都是要做Merge Request. Pul意思是請你拉下來看一下,沒問題能否Merge Approve..

git gcobjects一開始記錄的是完整備份,而gc下完後,會做差異備份(移動到package裡面)


情境題

某個分支部分Commit做的不錯想收進來,但又不想合併整個分支
git cherrypick (挑選對自己有利的)

Select a repo