# Git筆記 (Window) ## 一、Git branch(分支)基本語法 * 檢視程式碼編輯歷史紀錄 $ git blame <fileName> --- * 檢視目前所有branch $ git branch --- * 創造一個新的branch(加location(id)則會在該紀錄點創造branch) $ git branch <createName> <location(id)> --- * 刪除branch $ git branch -d <branchName> --- * 將HEAD權限轉移branch $ git switch <branchName> $ git checkout <location> $ git checkout -b <branchName> // 如果有該branchName則HEAD權限移過去,若沒有則在HEAD位置創建該branchName再將HEAD權限移過去。 :::warning * 若是要將HEAD權限回溯至沒有設置branch的紀錄點時,用**checkout**輸入該location(id)編碼前四碼,而若回溯沒有branch或非master的紀錄時,commit後若沒有建立新的branch,此時commit將會在HEAD switch到其他分支時,將無設置branch的此段隱藏。 ::: 舉例: 1. 用checkout回溯到備註為aaa.html的紀錄(該紀錄點無任何的branch),接著commit出testcommit3的紀錄點(如下圖) ![](https://i.imgur.com/DshXaGD.png) 2. 在aaa.html的紀錄沒有任何branch的情況下,當switch回main或其他branch後,在aaa.html的所有的commit紀錄都會被隱藏(如下圖)。 ![](https://i.imgur.com/sw9aEcI.png) 3. 所以編輯完後切記要在該紀錄點上創造一個branch作為新的分支,以便紀錄該次所有編輯。 :::warning 上述狀況可以利用reset或checkout輸入該消失點的location(id)來找回該commit。 ::: --- ## 二、合併分支(手法一:merge) $ git merge <branchName> 1.確認Head有在要合併的branch(這邊以master為例)。 ![](https://i.imgur.com/sw9aEcI.png) 將master貼紙移動至newbranch的位置,並非真的將master和newbranch兩者合併。 (不能往前合併比自己時間舊的branch。) ![](https://i.imgur.com/HlWRjwU.png) --- ## 三、複雜分支合併 示範:如何將下途中cat合併至dog(下圖為示範用初始資料夾) ![](https://i.imgur.com/mU9Z4i8.png) 1. 首先將Head權限切換至cat後,接著輸入指令合併dog $ git merge dog -m 'TwoInOne2' 2. 合併後即可完成cat和dog的合併,並產生出一個新的commit備註為TwoInOne2。 ![](https://i.imgur.com/6NJgx9S.png) :::warning 冷知識: 過程中[A合併B]和[B合併A]雖然結果一樣,但檔案軌跡歷史會不一樣。舉例的情況,下方圖片cat(Head)合併dog合併後會將dog的檔案歷史軌跡收割起來顯示,而非cat的歷史軌跡。 ![](https://i.imgur.com/o8OX1hQ.png) ::: --- ## 四、合併程式衝突solution * 若兩個檔案合併時同一行出現不同的code時會發生衝突,進而導致合併執行一半後error。解決方式為先修正兩個檔案中衝突的code,並在存檔後將該檔案重新add和commit一次(rebase 不是commit,是 rebase --continue),完成後再執行一次下方則會繼續自動完成後續合併動作。 :::warning 注意: 若直接執行該檔案add和commit,也可以排除git出錯的狀況,但實際並不會解決程式中衝突的狀況,須謹記。 ::: ## 五、合併分支(手法二:rebase) * rebase指令作用為改變根基,將分支接到另一個分支上。 舉例: 1. cat(Head)和 dog 做 rebase $ git rebase dog ![](https://i.imgur.com/mU9Z4i8.png) 2. 成功即可看到cat分支根基被移植到dog上。 ![](https://i.imgur.com/ptgEFcH.png) :::info ### rebase和merge的差異 * 兩者之間差異在歷史時間軸,rebase將自身根基由(a)複製到(b)時,而會讓原本a的commit消除(狀況可參照前面分支提到沒有branch被消除的狀況),而merge (a) 到 (b) 的時候,則可以收割b的歷史軌跡。 ::: ## 六、reset * reset功能可看作是become的概念,指令是將版本回溯至指定的location,並且同時對檔案的變動進行處理,下方為指令運用方式。 $ git reset <location> --<mixed>|<soft>|<hard> :::info ### reset 檔案處理方式 mixed : 移置工作目錄 soft : 放入暫存區 hard : 移除 ### 相對定位 'branchName(Head)^' = 倒退一次 commit branchName(Head)/^ = 倒退一次 commit branchName(Head)~x = 倒退x次 commit :::success 因為^在zsh中會無法辨別,運用單引號或/可以解決無法辨識問題,輸入指令setopt noEXTENDED_GLOB則可以直接解決無法辨識問題,直接輸入branchName(Head)^。 ::: 舉例: 1.選擇版控的資料夾 ![](https://i.imgur.com/GqiKZm0.png) 2.設置reset指令 $ git reset main~2 --soft // 倒退兩層並保留檔案在暫存區 $ git reset 'main^^' --soft // 倒退兩層並保留檔案在暫存區 ![](https://i.imgur.com/lpzq7vK.png) ![](https://i.imgur.com/V8YQwlf.png) 3.重新將暫存區的檔案commit回去 $ git commit -m 'TwoInOne' 4.即可完成reset和commit備註為TwoInOne ![](https://i.imgur.com/LoHCepi.png) --- ## reflog 移動軌跡表 若不小心在reset中用hard消除了檔案或rebase發現後悔了,可以透過reflog找尋動作紀錄的location(id),並運用reset還原。 --- ## blame查找程式碼的編輯紀錄 查找檔案中每一行編輯的歷史紀錄(人員,日期,時間,段落) $git blame <file> ## 回家作業(3/7前繳交) 1. zsh ^解法 2. PDF作業+錄製