Skip to content

Commit ade1f4e

Browse files
committed
git worktree
1 parent a4eaaed commit ade1f4e

File tree

1 file changed

+145
-4
lines changed

1 file changed

+145
-4
lines changed

README.md

Lines changed: 145 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,16 +1726,30 @@ git stash
17261726
假如你想要更清楚自己這次的 stash 原因是什麼,或是這是正在開發什麼功能
17271727
可以使用以下指令
17281728

1729-
範例
1729+
範例, 預設只會加入已經追蹤的, 也就是要先執行 `git add .`
17301730

17311731
```cmd
1732+
# 舊語法
17321733
git stash save "我是註解"
17331734
```
17341735

17351736
```cmd
1737+
# 新語法
1738+
git stash -m "我是註解"
1739+
```
1740+
1741+
如果你想把沒追蹤的也加入進去, 使用以下語法, 這樣就不用執行 `git add .`
1742+
1743+
```cmd
1744+
# 舊語法
17361745
git 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
18011815
git stash drop stash@{0}
18021816
```
18031817

1818+
## git worktree 指令
1819+
1820+
* [Youtube Tutorial - 別再用 git stash 了!受 Claude 啟發的 Git Worktree,實現真正的平行開發(等待新增)](xx)
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 ../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`
20282166

2029-
`-n, --dry-run` Don’t actually remove anything, just show what would be done
2167+
`-n, --dry-run` 模擬執行 Don’t actually remove anything, just show what would be done
2168+
2169+
`-d` 代表 recurse, 資料夾也會刪除.
20302170

20312171
這個指定是告訴你會刪除哪些資料, 不會真的刪除.
20322172

@@ -2044,14 +2184,15 @@ Untracked files:
20442184
20452185
nothing added to commit but untracked files present (use "git add" to track)
20462186
2047-
❯ git clean -n
2187+
❯ git clean -n -d
20482188
Would remove test.py
20492189
```
20502190

20512191
如果你執行以下的指令, 就會真的刪除,
20522192

20532193
`git clean -df`
20542194

2195+
20552196
詳細說明可使用 `git clean --help` 觀看,
20562197

20572198
範例如下,

0 commit comments

Comments
 (0)