設定和配置
獲取和建立專案
基本快照
分支與合併
共享和更新專案
檢查和比較
打補丁
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
- 2.48.1 → 2.50.1 無更改
-
2.48.0
2025-01-10
- 2.43.2 → 2.47.3 無變更
-
2.43.1
2024-02-09
- 2.42.2 → 2.43.0 無變更
-
2.42.1
2023-11-02
-
2.42.0
2023-08-21
- 2.39.1 → 2.41.3 無變更
-
2.39.0
2022-12-12
- 2.36.1 → 2.38.5 無更改
-
2.36.0
2022-04-18
- 2.35.1 → 2.35.8 無更改
-
2.35.0
2022-01-24
- 2.33.1 → 2.34.8 無變化
-
2.33.0
2021-08-16
- 2.31.1 → 2.32.7 無更改
-
2.31.0
2021-03-15
- 2.30.1 → 2.30.9 無更改
-
2.30.0
2020-12-27
- 2.29.1 → 2.29.3 無更改
-
2.29.0
2020-10-19
- 2.28.1 無更改
-
2.28.0
2020-07-27
- 2.22.1 → 2.27.1 無變更
-
2.22.0
2019-06-07
- 2.20.1 → 2.21.4 無更改
-
2.20.0
2018-12-09
- 2.19.3 → 2.19.6 無更改
-
2.19.2
2018-11-21
- 2.19.1 無更改
-
2.19.0
2018-09-10
- 2.18.1 → 2.18.5 無更改
-
2.18.0
2018-06-21
- 2.17.1 → 2.17.6 無更改
-
2.17.0
2018-04-02
-
2.16.6
2019-12-06
- 2.14.6 → 2.15.4 無變更
-
2.13.7
2018-05-22
-
2.12.5
2017-09-22
- 2.11.4 無更改
-
2.10.5
2017-09-22
-
2.9.5
2017-07-30
- 2.8.6 無更改
-
2.7.6
2017-07-30
-
2.6.7
2017-05-05
-
2.5.6
2017-05-05
概要
git worktree add [-f] [--detach] [--checkout] [--lock [--reason <string>]] [--orphan] [(-b | -B) <new-branch>] <path> [<commit-ish>] git worktree list [-v | --porcelain [-z]] git worktree lock [--reason <string>] <worktree> git worktree move <worktree> <new-path> git worktree prune [-n] [-v] [--expire <expire>] git worktree remove [-f] <worktree> git worktree repair [<path>…] git worktree unlock <worktree>
描述
管理附加到同一倉庫的多個工作區。
Git 倉庫支援多個工作區,允許您同時檢出多個分支。透過 git
worktree
add
命令,可以將新的工作區與倉庫關聯起來,並附帶額外的元資料,以區分同一倉庫中的不同工作區。工作區連同其元資料被稱為“工作區”。
這個新的工作區被稱為“連結工作區”(linked worktree),與 git-init[1] 或 git-clone[1] 準備的“主工作區”(main worktree)相對。一個倉庫有一個主工作區(如果它不是裸倉庫),以及零個或多個連結工作區。當您完成使用連結工作區後,請使用 git
worktree
remove
命令將其刪除。
最簡單的形式是,git
worktree
add
<path> 會自動建立一個新分支,其名稱為 <path> 的最後一個元件,如果您打算處理一個新主題,這會很方便。例如,git
worktree
add
../hotfix
會建立新分支 hotfix
並將其檢出到路徑 ../hotfix
。如果要在新的工作區中處理現有分支,請使用 git
worktree
add
<path> <branch>。另一方面,如果您只是計劃進行一些實驗性更改或測試,而不想幹擾現有開發,那麼建立一個不與任何分支關聯的*一次性*工作區通常會很方便。例如,git
worktree
add
-d
<path> 會建立一個新的工作區,其 HEAD
處於分離狀態,指向與當前分支相同的提交。
如果一個工作區在沒有使用 git
worktree
remove
的情況下被刪除,那麼其相關的管理檔案(位於倉庫中,參見下文“詳情”)最終會被自動移除(參見 git-config[1] 中的 gc.worktreePruneExpire
),或者您可以在主工作區或任何連結工作區中執行 git
worktree
prune
來清理任何過時的管理檔案。
如果連結工作區的工作目錄儲存在便攜裝置或網路共享上,並且不總是掛載的,您可以透過執行 git
worktree
lock
命令來防止其管理檔案被修剪,您可以選擇指定 --reason
來解釋鎖定該工作區的原因。
命令
- add <path> [<commit-ish>]
-
在 <path> 建立一個工作區並檢出 <commit-ish> 到其中。新的工作區連結到當前倉庫,共享除每個工作區特有的檔案(如
HEAD
、index
等)之外的所有內容。為方便起見,<commit-ish> 可以是裸的“-
”,這等同於@{-1}
。如果 <commit-ish> 是一個分支名稱(稱之為 <branch>)且未找到,並且沒有使用
-b
、-B
或--detach
,但恰好在一個遠端倉庫(稱之為 <remote>)中存在一個同名跟蹤分支,則將其視為等同於$ git worktree add --track -b <branch> <path> <remote>/<branch>
如果分支存在於多個遠端倉庫中,並且其中一個由
checkout.defaultRemote
配置變數指定,我們將使用該遠端倉庫進行消歧,即使 <branch> 在所有遠端倉庫中並非唯一。例如,將其設定為checkout.defaultRemote=origin
,以便在 <branch> 模稜兩可但存在於origin
遠端倉庫時,總是從那裡檢出遠端分支。另請參閱 git-config[1] 中的checkout.defaultRemote
。如果省略 <commit-ish> 並且沒有使用
-b
、-B
或--detach
,那麼為方便起見,新的工作區將與一個分支(稱之為 <branch>)關聯,該分支以$
(basename
<path>) 命名。如果 <branch> 不存在,則會自動建立一個基於HEAD
的新分支,如同給定了-b
<branch>。如果 <branch> 確實存在,並且沒有在其他地方被檢出,它將在新的工作區中被檢出,否則命令將拒絕建立該工作區(除非使用了--force
)。如果省略 <commit-ish>,且沒有使用
--detach
或--orphan
,並且沒有有效的本地分支(如果指定了--guess-remote
則也沒有遠端分支),那麼為方便起見,新的工作區將與一個新的未出生(unborn)分支 <branch> 關聯(如果既沒有使用-b
也沒有使用-B
,則以$
(basename
<path>) 命名),如同向命令傳遞了--orphan
。如果倉庫有遠端且使用了--guess-remote
,但不存在任何遠端或本地分支,則命令將失敗併發出警告,提醒使用者首先從遠端倉庫抓取(fetch)(或透過使用-f/--force
覆蓋)。 - list
-
列出每個工作區的詳細資訊。主工作區首先列出,然後是每個連結工作區。輸出詳細資訊包括工作區是否為裸倉庫、當前檢出的版本、當前檢出的分支(如果沒有則是“分離的 HEAD”)、如果工作區被鎖定則顯示“locked”、如果工作區可以透過
prune
命令修剪則顯示“prunable”。 - lock
-
如果一個工作區位於便攜裝置或網路共享上且並非總是掛載的,則將其鎖定以防止其管理檔案被自動修剪。這也能防止它被移動或刪除。您可以選擇使用
--reason
來指定鎖定的原因。 - move
-
將工作區移動到新位置。請注意,主工作區或包含子模組的連結工作區不能使用此命令移動。(但是,如果您手動移動了主工作區,
git
worktree
repair
命令可以重新建立與連結工作區的連線。) - prune
-
修剪
$GIT_DIR/worktrees
中的工作區資訊。 - remove
-
移除一個工作區。只有乾淨的工作區(沒有未跟蹤的檔案且跟蹤檔案沒有修改)才能被移除。不乾淨的工作區或包含子模組的工作區可以使用
--force
移除。主工作區不能被移除。 - repair [<path>…]
-
如果工作區管理檔案因外部因素而損壞或過時,則儘可能修復它們。
例如,如果主工作區(或裸倉庫)被移動,連結工作區將無法找到它。在主工作區中執行
repair
將重新建立從連結工作區到主工作區的連線。同樣,如果連結工作區的工作目錄在沒有使用
git
worktree
move
的情況下被移動,主工作區(或裸倉庫)將無法找到它。在最近移動的工作區內執行repair
將重新建立連線。如果移動了多個連結工作區,從任何工作區執行repair
並以每個工作區的新 <path> 作為引數,將重新建立與所有指定路徑的連線。如果主工作區和連結工作區都已被手動移動或複製,那麼在主工作區中執行
repair
並指定每個連結工作區的新 <path>,將重新建立雙向的所有連線。 - unlock
-
解鎖一個工作區,允許其被修剪、移動或刪除。
選項
- -f
- --force
-
預設情況下,當 <commit-ish> 是一個分支名稱且已被另一個工作區檢出,或者 <path> 已被分配給某個工作區但其目錄缺失(例如,如果 <path> 被手動刪除)時,
add
會拒絕建立新的工作區。此選項會覆蓋這些安全保護措施。要新增一個缺失但被鎖定的工作區路徑,請指定兩次--force
。move
拒絕移動鎖定的工作區,除非指定兩次--force
。如果目標路徑已被分配給其他工作區但其目錄缺失(例如,如果 <new-path> 被手動刪除),則--force
允許繼續移動;如果目標路徑被鎖定,則使用兩次--force
。remove
拒絕移除不乾淨的工作區,除非使用--force
。要移除鎖定的工作區,請指定兩次--force
。 - -b <new-branch>
- -B <new-branch>
-
使用
add
命令,建立一個名為 <new-branch> 的新分支,從 <commit-ish> 開始,並將 <new-branch> 檢出到新的工作區中。如果省略 <commit-ish>,則預設為HEAD
。預設情況下,如果新分支已存在,-b
會拒絕建立。-B
會覆蓋此安全措施,將 <new-branch> 重置為 <commit-ish>。 - -d
- --detach
-
使用
add
命令,分離新工作區中的HEAD
。參見 git-checkout[1] 中的“分離的 HEAD”(DETACHED HEAD)。 - --[no-]checkout
-
預設情況下,
add
會檢出 <commit-ish>,但是,可以使用--no-checkout
來抑制檢出,以便進行自定義,例如配置稀疏檢出(sparse-checkout)。參見 git-read-tree[1] 中的“稀疏檢出”(Sparse checkout)。 - --[no-]guess-remote
-
使用
worktree
add
<path>,且不帶 <commit-ish> 時,如果恰好有一個遠端跟蹤分支的名稱與 <path> 的基本名稱匹配,則新分支將基於該遠端跟蹤分支建立,並將其標記為新分支的“上游”,而不是從HEAD
建立新分支。這也可以透過使用
worktree.guessRemote
配置選項設定為預設行為。 - --[no-]relative-paths
-
使用相對路徑或絕對路徑(預設)連結工作區。此選項會覆蓋
worktree.useRelativePaths
配置選項,詳見 git-config[1]。使用
repair
時,如果存在絕對/相對路徑不匹配的情況,即使連結是正確的,連結檔案也會被更新。 - --[no-]track
-
建立新分支時,如果 <commit-ish> 是一個分支,則將其標記為新分支的“上游”。如果 <commit-ish> 是一個遠端跟蹤分支,則這是預設行為。詳見 git-branch[1] 中的
--track
。 - --lock
-
建立後保持工作區鎖定。這等同於在
git
worktree
add
之後執行git
worktree
lock
,但沒有競爭條件。 - -n
- --dry-run
-
使用
prune
時,不移除任何內容;只報告它將移除什麼。 - --orphan
-
使用
add
時,使新的工作區和索引為空,並將該工作區與一個名為 <new-branch> 的新的未出生分支關聯起來。 - --porcelain
-
使用
list
時,以易於指令碼解析的格式輸出。這種格式在不同 Git 版本之間以及無論使用者配置如何都將保持穩定。建議將其與-z
結合使用。詳見下文。 - -z
-
當
list
命令指定--porcelain
時,每行以 NUL 字元而不是換行符終止。這使得當工作區路徑包含換行符時,可以解析輸出。 - -q
- --quiet
-
使用
add
時,抑制反饋訊息。 - -v
- --verbose
-
使用
prune
時,報告所有移除操作。使用
list
時,輸出關於工作區的額外資訊(詳見下文)。 - --expire <time>
-
使用
prune
時,只使舊於 <time> 的未使用的工作區過期。使用
list
時,如果缺失的工作區舊於 <time>,則將其標註為可修剪(prunable)。 - --reason <string>
-
使用
lock
或add
--lock
時,解釋工作區被鎖定的原因。 - <工作區>
-
工作區可以透過路徑識別,可以是相對路徑或絕對路徑。
如果工作區路徑中的最後一個路徑元件在所有工作區中是唯一的,則可以使用它來識別工作區。例如,如果您只有兩個工作區,分別在
/abc/def/ghi
和/abc/def/ggg
,那麼ghi
或def/ghi
就足以指向前一個工作區。
引用
當使用多個工作區時,一些引用(refs)在所有工作區之間共享,但另一些則特定於單個工作區。一個例子是 HEAD
,它在每個工作區中都不同。本節介紹共享規則以及如何從一個工作區訪問另一個工作區的引用。
通常,所有偽引用(pseudo refs)都是每個工作區特有的,所有以 refs/
開頭的引用都是共享的。偽引用是像 HEAD
這樣直接位於 $GIT_DIR
下而不是 $GIT_DIR/refs
內部的引用。然而也有例外:refs/bisect
、refs/worktree
和 refs/rewritten
內部的引用不共享。
每個工作區特有的引用仍然可以透過兩個特殊路徑從另一個工作區訪問:main-worktree
和 worktrees
。前者提供對主工作區特有引用的訪問,後者則提供對所有連結工作區的訪問。
例如,main-worktree/HEAD
或 main-worktree/refs/bisect/good
解析為與主工作區的 HEAD
和 refs/bisect/good
相同的值。類似地,worktrees/foo/HEAD
或 worktrees/bar/refs/bisect/bad
等同於 $GIT_COMMON_DIR/worktrees/foo/HEAD
和 $GIT_COMMON_DIR/worktrees/bar/refs/bisect/bad
。
要訪問引用,最好不要直接檢視 $GIT_DIR
內部。而是使用諸如 git-rev-parse[1] 或 git-update-ref[1] 等命令,它們將正確處理引用。
配置檔案
預設情況下,倉庫 config
檔案在所有工作區之間共享。如果 core.bare
或 core.worktree
配置變數存在於公共配置檔案中且 extensions.worktreeConfig
已停用,則它們將僅應用於主工作區。
為了擁有工作區特定的配置,您可以啟用 worktreeConfig
擴充套件,例如:
$ git config extensions.worktreeConfig true
在此模式下,特定配置將保留在 git
rev-parse
--git-path
config.worktree
指向的路徑中。您可以使用 git
config
--worktree
在此檔案中新增或更新配置。舊版 Git 將拒絕訪問使用此擴充套件的倉庫。
請注意,在此檔案中,core.bare
和 core.worktree
的例外情況已不存在。如果它們存在於 $GIT_DIR/config
中,您必須將它們移動到主工作區的 config.worktree
中。您也可以藉此機會審查並移動您不想共享到所有工作區的其他配置。
-
core.worktree
不應被共享。 -
如果值為
core.bare=true
,則不應共享core.bare
。 -
core.sparseCheckout
不應被共享,除非您確定所有工作區都始終使用稀疏檢出(sparse checkout)。
詳見 git-config[1] 中 extensions.worktreeConfig
的文件。
詳情
每個連結工作區在倉庫的 $GIT_DIR/worktrees
目錄下都有一個私有子目錄。私有子目錄的名稱通常是連結工作區路徑的基本名稱,可能附加一個數字以使其唯一。例如,當 $GIT_DIR=/path/main/.git
時,命令 git
worktree
add
/path/other/test-next
next
會在 /path/other/test-next
建立連結工作區,並同時建立一個 $GIT_DIR/worktrees/test-next
目錄(如果 test-next
已被佔用,則為 $GIT_DIR/worktrees/test-next1
)。
在連結工作區內部,$GIT_DIR
被設定為指向此私有目錄(例如示例中的 /path/main/.git/worktrees/test-next
),而 $GIT_COMMON_DIR
被設定為指回主工作區的 $GIT_DIR
(例如 /path/main/.git
)。這些設定是在連結工作區頂層目錄下的 .git
檔案中進行的。
透過 git
rev-parse
--git-path
進行的路徑解析會根據路徑使用 $GIT_DIR
或 $GIT_COMMON_DIR
。例如,在連結工作區中,git
rev-parse
--git-path
HEAD
返回 /path/main/.git/worktrees/test-next/HEAD
(而不是 /path/other/test-next/.git/HEAD
或 /path/main/.git/HEAD
),而 git
rev-parse
--git-path
refs/heads/master
使用 $GIT_COMMON_DIR
並返回 /path/main/.git/refs/heads/master
,因為除了 refs/bisect
、refs/worktree
和 refs/rewritten
之外,引用在所有工作區之間共享。
更多資訊請參見 gitrepository-layout[5]。經驗法則是,當您需要直接訪問 $GIT_DIR
內部的某些內容時,不要對路徑是否屬於 $GIT_DIR
或 $GIT_COMMON_DIR
做任何假設。請使用 git
rev-parse
--git-path
來獲取最終路徑。
如果您手動移動一個連結工作區,您需要更新其入口目錄中的 gitdir
檔案。例如,如果一個連結工作區被移動到 /newpath/test-next
,並且其 .git
檔案指向 /path/main/.git/worktrees/test-next
,那麼請更新 /path/main/.git/worktrees/test-next/gitdir
以引用 /newpath/test-next
。更好的做法是,執行 git
worktree
repair
來自動重新建立連線。
為防止 $GIT_DIR/worktrees
中的條目被修剪(這在某些情況下很有用,例如當條目所屬的工作區儲存在便攜裝置上時),請使用 git
worktree
lock
命令,該命令會在該條目目錄下新增一個名為 locked
的檔案。該檔案包含純文字格式的原因。例如,如果一個連結工作區的 .git
檔案指向 /path/main/.git/worktrees/test-next
,那麼名為 /path/main/.git/worktrees/test-next/locked
的檔案將阻止 test-next
條目被修剪。詳見 gitrepository-layout[5]。
當 extensions.worktreeConfig
被啟用時,配置檔案 .git/worktrees/
<id>/config.worktree
會在讀取 .git/config
之後讀取。
列表輸出格式
worktree
list
命令有兩種輸出格式。預設格式在一行中以列的形式顯示詳細資訊。例如
$ git worktree list /path/to/bare-source (bare) /path/to/linked-worktree abcd1234 [master] /path/to/other-linked-worktree 1234abc (detached HEAD)
該命令還會根據每個工作區的狀態顯示註釋。這些註釋是:
-
如果工作區被鎖定,則顯示
locked
。 -
如果工作區可以透過
git
worktree
prune
修剪,則顯示prunable
。
$ git worktree list /path/to/linked-worktree abcd1234 [master] /path/to/locked-worktree acbd5678 (brancha) locked /path/to/prunable-worktree 5678abc (detached HEAD) prunable
對於這些註釋,可能還會提供原因,可以在詳細模式下檢視。註釋會移到下一行,縮排後跟著附加資訊。
$ git worktree list --verbose /path/to/linked-worktree abcd1234 [master] /path/to/locked-worktree-no-reason abcd5678 (detached HEAD) locked /path/to/locked-worktree-with-reason 1234abcd (brancha) locked: worktree path is mounted on a portable device /path/to/prunable-worktree 5678abc1 (detached HEAD) prunable: gitdir file points to non-existent location
請注意,如果有附加資訊,註釋會移到下一行,否則它會留在工作區本身的同一行。
瓷器格式
瓷器格式中,每個屬性佔據一行。如果給定 -z
,則行以 NUL 字元而不是換行符終止。屬性以標籤和值列出,由一個空格分隔。布林屬性(如 bare
和 detached
)僅列出標籤,並且僅當值為真時才存在。某些屬性(如 locked
)可以只列出標籤,也可以帶上值,這取決於是否有原因可用。工作區的第一個屬性始終是 worktree
,一個空行表示記錄的結束。例如
$ git worktree list --porcelain worktree /path/to/bare-source bare worktree /path/to/linked-worktree HEAD abcd1234abcd1234abcd1234abcd1234abcd1234 branch refs/heads/master worktree /path/to/other-linked-worktree HEAD 1234abc1234abc1234abc1234abc1234abc1234a detached worktree /path/to/linked-worktree-locked-no-reason HEAD 5678abc5678abc5678abc5678abc5678abc5678c branch refs/heads/locked-no-reason locked worktree /path/to/linked-worktree-locked-with-reason HEAD 3456def3456def3456def3456def3456def3456b branch refs/heads/locked-with-reason locked reason why is locked worktree /path/to/linked-worktree-prunable HEAD 1233def1234def1234def1234def1234def1234b detached prunable gitdir file points to non-existent location
除非使用 -z
,否則鎖定原因中的任何“不尋常”字元(如換行符)都會被轉義,並且整個原因會像配置變數 core.quotePath
所解釋的那樣被引用起來(參見 git-config[1])。例如
$ git worktree list --porcelain ... locked "reason\nwhy is locked" ...
示例
您正在進行重構,這時您的老闆進來,要求您立即修復一些東西。您通常可能會使用 git-stash[1] 暫時儲存您的更改,但是,您的工作區處於如此混亂的狀態(有新增、移動和刪除的檔案,以及散落的其他零碎內容),以至於您不想冒險打亂任何東西。相反,您可以建立一個臨時的連結工作區來完成緊急修復,完成後將其刪除,然後繼續您之前的重構會話。
$ git worktree add -b emergency-fix ../temp master $ pushd ../temp # ... hack hack hack ... $ git commit -a -m 'emergency fix for boss' $ popd $ git worktree remove ../temp