@@ -366,7 +366,7 @@ git log --pretty=oneline
366366
367367如果你想要看某個檔案或某個資料夾的變動, 可以這樣使用, 範例如下
368368
369- * [ Youtube Tutorial - Git Log:資料夾移動後 Log 消失?用 --follow 找回檔案歷史!(等待新增) ] ( xx )
369+ * [ Youtube Tutorial - Git Log:資料夾移動後 Log 消失?用 --follow 找回檔案歷史!] ( https://youtu.be/AGO3PyMTqds )
370370
371371``` cmd
372372git log -- folder
@@ -1726,16 +1726,30 @@ git stash
17261726假如你想要更清楚自己這次的 stash 原因是什麼,或是這是正在開發什麼功能
17271727可以使用以下指令
17281728
1729- 範例
1729+ 範例, 預設只會加入已經追蹤的, 也就是要先執行 ` git add . `
17301730
17311731``` cmd
1732+ # 舊語法
17321733git stash save "我是註解"
17331734```
17341735
17351736``` cmd
1737+ # 新語法
1738+ git stash -m "我是註解"
1739+ ```
1740+
1741+ 如果你想把沒追蹤的也加入進去, 使用以下語法, 這樣就不用執行 ` git add . ` 了
1742+
1743+ ``` cmd
1744+ # 舊語法
17361745git stash save -u "feature"
17371746```
17381747
1748+ ``` cmd
1749+ # 新語法
1750+ git stash -u -m "feature"
1751+ ```
1752+
17391753參數說明
17401754
17411755` -u ` | ` --include-untracked `
@@ -1801,6 +1815,130 @@ git stash drop 0
18011815git stash drop stash@{0}
18021816```
18031817
1818+ ## git worktree 指令
1819+
1820+ * [ Youtube Tutorial - 別再用 git stash 了!受 Claude 啟發的 Git Worktree,實現真正的平行開發] ( https://youtu.be/9FOHZo7Gc28 )
1821+
1822+ (會介紹這個的原因是因為看了一下 claude code 的東西, 發現裡面有使用到這個指令)
1823+
1824+ 這個的概念是類似複製(但本質不是複製)一個全新乾淨的專案出來, 優點是可以不影響原本的資料夾,
1825+
1826+ 如果你的分支是要做版本升級, 蠻適合使用 worktree 來處理的.
1827+
1828+ 簡單說是 空間隔離 的概念.
1829+
1830+ 假如現在你有一個專案名稱是 repo, 路徑是
1831+
1832+ ``` cmd
1833+ cd /home/twtrubiks/demo/repo
1834+ ```
1835+
1836+ 目前的 main 分支狀況
1837+
1838+ ``` cmd
1839+ git log
1840+ * 62f3d61 - (HEAD -> main) first commit
1841+ ```
1842+
1843+ 然後現在開發了一個功能, 建立了一個 feature_1 分支
1844+
1845+ ``` cmd
1846+ git switch -c feature_1
1847+ ```
1848+
1849+ 開發到一半, 目前 feature_1 的狀況如下, 還沒開發完 step_2 寫到一半也不想要 commit
1850+
1851+ ``` cmd
1852+ ❯ git status
1853+ On branch feature_1
1854+ Untracked files:
1855+ feature1.py
1856+ ```
1857+
1858+ ``` cmd
1859+ git log
1860+ * d716943 - (HEAD -> feature_1) step_1 (1 second ago)
1861+ * 62f3d61 - (main) first commit (5 minutes ago)
1862+ ```
1863+
1864+ 突然有一個需求需要 hotfix,
1865+
1866+ 這時候如果不使用 ` git stash ` , 改使用 ` git worktree ` 的方式,
1867+
1868+ 首先, 從 main 分支開一個 worktree 出來, 執行底下的 code
1869+
1870+ ``` cmd
1871+ git worktree add ../repo-hotfix main
1872+ ```
1873+
1874+ 在上層目錄你會發現, 多了一個 repo-hotfix 資料夾, 它裡面是 main 的分支,
1875+
1876+ 如果你到這個資料夾底下觀看, 你會發現 ` .git ` (這是一個** 檔案** ,而不是資料夾),
1877+
1878+ 裡面只有一行文字,如下
1879+
1880+ ``` cmd
1881+ cat .git
1882+ gitdir: /home/twtrubiks/demo/repo/.git/worktrees/repo-hotfix
1883+ ```
1884+
1885+ 這時候你就可以進去 ` /home/twtrubiks/demo/repo-hotfix `
1886+
1887+ 然後依照團隊的流程再開一個分支,
1888+
1889+ ``` cmd
1890+ git switch -c hotfix-1
1891+ ```
1892+
1893+ 接著可以使用 ` git worktree list ` 觀看
1894+
1895+ ``` cmd
1896+ ❯ git worktree list
1897+ /home/twtrubiks/demo/repo [feature_1]
1898+ /home/twtrubiks/demo/repo-hotfix [hotfix-1]
1899+ ```
1900+
1901+ 這裡面是完全獨立而且和 repo 資料夾隔離的,
1902+
1903+ (這裡可以設定你需要在這個分支的版本, 例如這個分支可能是使用 python 3.13)
1904+
1905+ 然後你在這裡面把你的功能開發完畢, 然後 push 上去跑 PR流程這樣, 到這邊結束.
1906+
1907+ 你可以回到 repo 專案底下繼續開發, 剛剛的工作狀態包含未追蹤的檔案都原封不動的在那邊.
1908+
1909+ 如果確定不需要這個 worktree, 使用底下的指令刪除即可.
1910+
1911+ ``` cmd
1912+ git worktree remove ../repo-hotfix
1913+ ```
1914+
1915+ 提醒, 如果你沒有清除 worktree 分支, 你是無法切換過去對應的分支, 像這邊的例子, 你會無法切換過去 main 分支.
1916+
1917+ 如果你擔心不小心刪掉你的 worktree, 可以使用 lock
1918+
1919+ ``` cmd
1920+ git worktree lock ../repo-hotfix
1921+ ```
1922+
1923+ 這樣當你真的不小心執行要刪掉你的 worktree, 會警告你要加上 ` -f -f ` 才能刪除
1924+
1925+ ``` cmd
1926+ git worktree remove -f -f ../repo-hotfix
1927+ ```
1928+
1929+ 我知道最後你一定想問, 這樣和我複製一個資料夾出來, 然後在資料夾上切換分支有什麼差別
1930+
1931+ 詳細比較可參考下表
1932+
1933+ | 特性 | ` git worktree ` | ` 複製資料夾 ` (` cp -r ` ) |
1934+ | :--- | :--- | :--- |
1935+ | ** 核心機制** | ** 連結 (Linked)** | ** 複製 (Copied)** |
1936+ | ** ` .git ` 資料庫** | ** 1 個 (共享)** | ** 2 個 (獨立且互不相干)** |
1937+ | ** Commit 同步** | ** 即時自動同步** <br >在任何一個 worktree 中 commit,另一個立刻就能看到。 | ** 完全不同步** <br >必須手動設定, 透過 ` fetch ` /` pull ` 同步。 |
1938+ | ** 硬碟空間使用** | ** 高效率** <br >只增加工作檔案的空間,龐大的 ` .git/objects ` 歷史紀錄不需複製。 | ** 極度浪費** <br >完整複製了整個 ` .git ` 資料庫,專案歷史越長,浪費空間越多。 |
1939+ | ** 操作流程** | ** 簡單優雅** <br >` git worktree add/remove ` | ** 複雜且違反直覺** <br >需要設定本地額外設定以及推到remote |
1940+ | ** 風險** | ** 低** <br >永遠只有一個事實來源 (Single Source of Truth),不會搞混歷史。 | ** 高** <br >容易產生混淆,甚至導致兩個獨立的歷史紀錄** 分岔 (diverge)** 。 |
1941+
18041942## git tag
18051943
18061944[ Youtube Tutorial - git tag 教學] ( https://youtu.be/azciLlpr3Gs )
@@ -2024,9 +2162,11 @@ git grep "hello"
20242162
20252163刪除未被追蹤的檔案,
20262164
2027- ` git clean -n `
2165+ ` git clean -n -d `
2166+
2167+ ` -n, --dry-run ` 模擬執行 Don’t actually remove anything, just show what would be done
20282168
2029- ` -n, --dry-run ` Don’t actually remove anything, just show what would be done
2169+ ` -d ` 代表 recurse, 資料夾也會刪除.
20302170
20312171這個指定是告訴你會刪除哪些資料, 不會真的刪除.
20322172
@@ -2044,14 +2184,15 @@ Untracked files:
20442184
20452185nothing added to commit but untracked files present (use "git add" to track)
20462186
2047- ❯ git clean -n
2187+ ❯ git clean -n -d
20482188Would remove test.py
20492189```
20502190
20512191如果你執行以下的指令, 就會真的刪除,
20522192
20532193` git clean -df `
20542194
2195+
20552196詳細說明可使用 ` git clean --help ` 觀看,
20562197
20572198範例如下,
@@ -2095,6 +2236,36 @@ git status
20952236
20962237建議大家自己操作一下.
20972238
2239+ ## git gc
2240+
2241+ git gc 是 Git 的垃圾收集器(Garbage Collector)
2242+
2243+ 它會清理不再需要的物件、壓縮檔案、優化儲存庫效能
2244+
2245+ 如果你希望將 ` .git ` 資料夾變小,可以考慮使用以下的指令,
2246+
2247+ ``` cmd
2248+ git gc --aggressive --prune=now
2249+ ```
2250+
2251+ ` --aggressive ` 使用更徹底但耗時的優化策略
2252+
2253+ ` --prune=now ` 立即刪除所有不可達到的物件
2254+
2255+ 執行效果,
2256+
2257+ 1 . 空間優化:大幅減少 ` .git ` 目錄的大小
2258+
2259+ 2 . 效能提升:改善 Git 操作的速度
2260+
2261+ 3 . 徹底清理:移除所有無用的物件和引用
2262+
2263+ 使用時機
2264+
2265+ • 儲存庫變得很大時
2266+
2267+ • 進行了大量的分支合併、刪除操作後
2268+
20982269## git Submodule
20992270
21002271由於這個內容稍微比較多,所以我另外寫了一篇,
0 commit comments