設定和配置
獲取和建立專案
基本快照
分支與合併
共享和更新專案
檢查和比較
打補丁
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
- 2.50.1 無更改
-
2.50.0
2025-06-16
- 2.47.2 → 2.49.1 無變更
-
2.47.1
2024-11-25
- 2.44.1 → 2.47.0 無變更
-
2.44.0
2024-02-23
- 2.43.2 → 2.43.7 無變更
-
2.43.1
2024-02-09
-
2.43.0
2023-11-20
- 2.41.1 → 2.42.4 無更改
-
2.41.0
2023-06-01
- 2.40.1 → 2.40.4 無更改
-
2.40.0
2023-03-12
- 2.39.4 → 2.39.5 無更改
-
2.39.3
2023-04-17
- 2.38.1 → 2.39.2 無更改
-
2.38.0
2022-10-02
- 2.35.1 → 2.37.7 無更改
-
2.35.0
2022-01-24
- 2.34.1 → 2.34.8 無更改
-
2.34.0
2021-11-15
- 2.30.1 → 2.33.8 無變更
-
2.30.0
2020-12-27
- 2.29.1 → 2.29.3 無更改
-
2.29.0
2020-10-19
- 2.27.1 → 2.28.1 無變更
-
2.27.0
2020-06-01
- 2.25.1 → 2.26.3 無更改
-
2.25.0
2020-01-13
- 2.23.1 → 2.24.4 無更改
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 無更改
-
2.22.0
2019-06-07
- 2.21.1 → 2.21.4 無更改
-
2.21.0
2019-02-24
- 2.19.3 → 2.20.5 無更改
-
2.19.2
2018-11-21
- 2.19.1 無更改
-
2.19.0
2018-09-10
- 2.17.0 → 2.18.5 無更改
-
2.16.6
2019-12-06
- 2.15.4 無更改
-
2.14.6
2019-12-06
-
2.13.7
2018-05-22
- 2.11.4 → 2.12.5 無變更
-
2.10.5
2017-09-22
-
2.9.5
2017-07-30
- 2.8.6 無更改
-
2.7.6
2017-07-30
- 2.6.7 無更改
-
2.5.6
2017-05-05
-
2.4.12
2017-05-05
- 2.1.4 → 2.3.10 無更改
-
2.0.5
2014-12-17
概要
git
checkout
[-q
] [-f
] [-m
] [<branch>]git
checkout
[-q
] [-f
] [-m
]--detach
[<branch>]git
checkout
[-q
] [-f
] [-m
] [--detach
] <commit>git
checkout
[-q
] [-f
] [-m
] [[-b
|-B
|--orphan
] <new-branch>] [<start-point>]git
checkout
[-f
] <tree-ish> [--
] <pathspec>…git
checkout
[-f
] <tree-ish>--pathspec-from-file=
<file> [--pathspec-file-nul
]git
checkout
[-f
|--ours
|--theirs
|-m
|--conflict=
<style>] [--
] <pathspec>…git
checkout
[-f
|--ours
|--theirs
|-m
|--conflict=
<style>]--pathspec-from-file=
<file> [--pathspec-file-nul
]git
checkout
(-p
|--patch
) [<tree-ish>] [--
] [<pathspec>…]
描述
更新工作區中的檔案,使其與索引或指定樹中的版本匹配。如果未指定路徑,git
checkout
還會更新 HEAD
以將指定分支設定為當前分支。
git
checkout
[<branch>]-
為準備在 <branch> 上工作,透過更新索引和工作區中的檔案,並將
HEAD
指向該分支來切換到它。工作區中檔案的本地修改會保留,以便它們可以提交到 <branch>。如果未找到 <branch>,但恰好存在一個同名且在唯一一個遠端倉庫(稱之為 <remote>)中的跟蹤分支,並且未指定
--no-guess
,則等同於執行:$ git checkout -b <branch> --track <remote>/<branch>
你可以省略 <branch>,在這種情況下,該命令會退化為“檢出當前分支”,這實際上是一個花哨的空操作,但會產生相當昂貴的副作用,即僅顯示當前分支的跟蹤資訊(如果存在)。
git
checkout
(-b
|-B
) <new-branch> [<start-point>]-
指定
-b
會建立一個新分支,如同呼叫 git-branch[1] 然後再將其檢出一樣。在這種情況下,你可以使用--track
或--no-track
選項,它們將傳遞給git
branch
。為方便起見,不帶-b
的--track
意味著建立分支;詳見下方--track
選項的描述。如果給定
-B
,如果 <new-branch> 不存在則建立,否則重置它。這等同於執行以下事務性操作:$ git branch -f <branch> [<start-point>] $ git checkout <branch>
也就是說,除非“git checkout”成功,否則分支不會被重置/建立(例如,當分支在另一個工作樹中使用時,不僅當前分支保持不變,分支也不會重置到起始點)。
git
checkout
--detach
[<branch>]git
checkout
[--detach
] <commit>-
透過將
HEAD
分離到 <commit> 上(參見“分離 HEAD”章節),並更新索引和工作區中的檔案,準備在 <commit> 之上工作。工作區中檔案的本地修改會保留,因此最終的工作區將是提交中記錄的狀態加上本地修改。當 <commit> 引數是分支名稱時,可以使用
--detach
選項將HEAD
分離到該分支的末端(git
checkout
<branch> 會檢出該分支而不會分離HEAD
)。省略 <branch> 會將
HEAD
分離到當前分支的末端。 git
checkout
[-f
|--ours
|--theirs
|-m
|--conflict=
<style>] [<tree-ish>] [--
] <pathspec>...git
checkout
[-f
|--ours
|--theirs
|-m
|--conflict=
<style>] [<tree-ish>]--pathspec-from-file=
<file> [--pathspec-file-nul
]-
覆蓋與路徑匹配的檔案內容。如果未指定 <tree-ish>(通常是一個提交),則用索引中的內容覆蓋工作區。如果指定了 <tree-ish>,則用 <tree-ish> 中的內容覆蓋索引和工作區。
索引可能包含由於之前失敗的合併而產生的未合併條目。預設情況下,如果你嘗試從索引中檢出此類條目,檢出操作將失敗,並且不會檢出任何內容。使用
-f
將忽略這些未合併的條目。可以使用--ours
或--theirs
從索引中檢出合併的特定一方的內容。使用-m
,可以丟棄對工作區檔案所做的更改,以重新建立原始的衝突合併結果。 git
checkout
(-p
|--patch
) [<tree-ish>] [--
] [<pathspec>...]-
這與之前的模式類似,但允許你使用互動式介面顯示“diff”輸出,並選擇結果中要使用的程式碼塊(hunks)。有關
--patch
選項的描述,請參見下文。
選項
-q
--quiet
-
安靜模式,抑制反饋訊息。
--progress
--no-progress
-
預設情況下,當連線到終端時,進度狀態會在標準錯誤流上報告,除非指定了
--quiet
。即使未連線到終端,此標誌也會啟用進度報告,無論是否指定--quiet
。 -f
--force
-
切換分支時,即使索引或工作區與
HEAD
不同,或者存在未跟蹤的檔案阻礙,也要繼續進行。這用於丟棄本地修改以及任何阻礙的未跟蹤檔案或目錄。從索引中檢出路徑時,遇到未合併的條目時不失敗;相反,未合併的條目將被忽略。
--ours
--theirs
-
從索引中檢出路徑時,對於未合併的路徑,檢出階段 #2 (
ours
) 或 #3 (theirs
)。請注意,在執行
git
rebase
和git
pull
--rebase
時,ours
和theirs
可能會互換;--ours
提供更改被 rebase 到其上的分支的版本,而--theirs
提供包含你正在 rebase 的工作的分支的版本。這是因為
rebase
在一個工作流中使用,該工作流將遠端倉庫的歷史視為共享的規範歷史,並將你在正在 rebase 的分支上所做的工作視為要整合的第三方工作,並且你在 rebase 期間暫時承擔著規範歷史維護者的角色。作為規範歷史的維護者,你需要將來自遠端倉庫的歷史視為ours
(即“我們共享的規範歷史”),而將你在旁支上所做的工作視為theirs
(即“一位貢獻者在其上所做的工作”)。 -b
<new-branch>-
建立一個名為 <new-branch> 的新分支,從 <start-point> 開始,並檢出生成的分支;有關詳細資訊,請參見 git-branch[1]。
-B
<new-branch>-
建立分支 <new-branch>,從 <start-point> 開始;如果它已經存在,則將其重置到 <start-point>。然後檢出生成的分支。這等同於執行帶有
-f
的git
branch
,然後檢出該分支;有關詳細資訊,請參見 git-branch[1]。 -t
--track
[=
(direct
|inherit
)]-
建立新分支時,設定“upstream”配置。有關詳細資訊,請參見 git-branch[1] 中的
--track
。如果沒有給出
-b
選項,新分支的名稱將從遠端跟蹤分支派生,方法是檢視為相應遠端配置的引用規範的本地部分,然後剝離直到“*”的初始部分。這將告訴我們在從origin/hack
(或remotes/origin/hack
,甚至refs/remotes/origin/hack
)分支時,使用hack
作為本地分支名稱。如果給定的名稱沒有斜槓,或者上述猜測導致名稱為空,則猜測中止。在這種情況下,你可以使用-b
顯式指定名稱。 --no-track
-
不設定“upstream”配置,即使
branch.autoSetupMerge
配置變數為 true。 --guess
--no-guess
-
如果未找到 <branch>,但恰好存在一個同名且在唯一一個遠端倉庫(稱之為 <remote>)中的跟蹤分支,則等同於執行:
$ git checkout -b <branch> --track <remote>/<branch>
如果該分支存在於多個遠端倉庫中,並且其中一個遠端倉庫透過
checkout.defaultRemote
配置變數指定,我們將使用該遠端倉庫進行消歧,即使 <branch> 在所有遠端倉庫中不是唯一的。例如,將其設定為checkout.defaultRemote=origin
,以便在 <branch> 存在歧義但存在於 origin 遠端倉庫時,始終從那裡檢出遠端分支。另請參見 git-config[1] 中的checkout.defaultRemote
。--guess
是預設行為。使用--no-guess
可以停用它。預設行為可以透過
checkout.guess
配置變數進行設定。 -l
-
建立新分支的引用日誌;有關詳細資訊,請參見 git-branch[1]。
-d
--detach
-
不是檢出一個分支來在其上工作,而是檢出一個提交用於檢查和可丟棄的實驗。這是當 <commit> 不是分支名稱時,
git
checkout
<commit> 的預設行為。有關詳細資訊,請參見下方的“分離 HEAD”章節。 --orphan
<new-branch>-
建立一個名為 <new-branch> 的新“孤兒”分支,從 <start-point> 開始並切換到它。在此新分支上進行的第一次提交將沒有父級,它將成為一個與所有其他分支和提交完全斷開的新歷史的根。
索引和工作區會進行調整,就像你之前運行了
git
checkout
<start-point> 一樣。這允許你透過輕鬆執行git
commit
-a
來建立根提交,從而開始一個記錄與 <start-point> 類似路徑集的新歷史。當你想要釋出一個提交的樹結構而不暴露其完整歷史時,這會很有用。你可能希望這樣做,以釋出一個專案(其當前樹結構是“乾淨”的)的開源分支,但其完整歷史包含專有或受其他限制的程式碼片段。
如果你想開始一個記錄與 <start-point> 完全不同的路徑集的新歷史,那麼在建立孤兒分支後,你應該立即從工作區的頂層執行
git
rm
-rf
.
來清空索引和工作區。之後,你就可以準備你的新檔案,透過從其他地方複製、解壓 tarball 等方式重新填充工作區。 --ignore-skip-worktree-bits
-
在稀疏檢出模式下,
git
checkout
--
<path>... 將只更新與 <paths> 和$GIT_DIR/info/sparse-checkout
中的稀疏模式匹配的條目。此選項會忽略稀疏模式,並重新新增 <path>... 中的任何檔案。 -m
--merge
-
切換分支時,如果你的一個或多個檔案有本地修改,並且這些修改在當前分支與你要切換的分支之間存在差異,命令會拒絕切換分支,以便在上下文中保留你的修改。然而,使用此選項,將執行當前分支、你的工作區內容和新分支之間的三方合併,然後你將位於新分支上。
當發生合併衝突時,衝突路徑的索引條目會保持未合併狀態,你需要解決衝突並使用
git
add
(如果合併應導致路徑刪除,則使用git
rm
)標記已解決的路徑。從索引中檢出路徑時,此選項讓你可以在指定路徑中重新建立衝突合併。從樹物件(tree-ish)中檢出路徑時,不能使用此選項。
使用
--merge
切換分支時,暫存的更改可能會丟失。 --conflict=
<style>-
與上面的
--merge
選項相同,但改變了衝突程式碼塊的呈現方式,覆蓋了merge.conflictStyle
配置變數。可能的值有merge
(預設)、diff3
和zdiff3
。 -p
--patch
-
互動式地選擇 <tree-ish>(如果未指定,則為索引)與工作區之間差異中的程式碼塊(hunks)。然後將選定的程式碼塊反向應用於工作區(如果指定了 <tree-ish>,則也應用於索引)。
這意味著你可以使用
git
checkout
-p
從當前工作區中選擇性地丟棄編輯。有關如何操作--patch
模式的詳細資訊,請參見 git-add[1] 的“互動模式”章節。請注意,此選項預設使用無覆蓋模式(另請參見
--overlay
),並且目前不支援覆蓋模式。 --ignore-other-worktrees
-
git
checkout
在所需分支已被檢出或被另一個工作樹佔用時會拒絕操作。此選項使其無論如何都會檢出該分支。換句話說,該分支可以被多個工作樹使用。 --overwrite-ignore
--no-overwrite-ignore
-
切換分支時,靜默覆蓋被忽略的檔案。這是預設行為。使用
--no-overwrite-ignore
在新分支包含被忽略檔案時中止操作。 --recurse-submodules
--no-recurse-submodules
-
使用
--recurse-submodules
將根據超級專案中記錄的提交更新所有活動子模組的內容。如果子模組中的本地修改將被覆蓋,檢出將失敗,除非使用-f
。如果沒有使用任何(或--no-recurse-submodules
)選項,子模組工作樹將不會更新。就像 git-submodule[1] 一樣,這會分離子模組的HEAD
。 --overlay
--no-overlay
-
在預設的覆蓋模式下,
git
checkout
永遠不會從索引或工作區中刪除檔案。當指定--no-overlay
時,出現在索引和工作區中但不在 <tree-ish> 中的檔案將被刪除,以使其與 <tree-ish> 精確匹配。 --pathspec-from-file=
<file>-
路徑規範透過 <file> 傳遞,而不是透過命令列引數。如果 <file> 精確為
-
,則使用標準輸入。路徑規範元素由 LF 或 CR/LF 分隔。路徑規範元素可以按照配置變數core.quotePath
的說明進行引用(參見 git-config[1])。另請參見--pathspec-file-nul
和全域性--literal-pathspecs
。 --pathspec-file-nul
-
僅在與
--pathspec-from-file
一起使用時有意義。路徑規範元素由 NUL 字元分隔,所有其他字元都被視為字面值(包括換行符和引號)。 - <分支>
-
要檢出的分支;如果它指向一個分支(即,一個加上“refs/heads/”字首後是有效引用的名稱),那麼將檢出該分支。否則,如果它指向一個有效的提交,你的
HEAD
將變為“分離”狀態,你將不再位於任何分支上(詳見下文)。你可以使用
@{-N}
語法來引用使用“git checkout”操作檢出的倒數第 N 個分支/提交。你也可以指定-
,它等同於@{-1}
。作為特例,如果 <rev-a> 和 <rev-b> 只有一個合併基準,你可以使用 <rev-a>
...
<rev-b> 作為它們的合併基準的快捷方式。你可以最多省略 <rev-a> 和 <rev-b> 中的一個,在這種情況下它預設為HEAD
。 - <新分支>
-
新分支的名稱。
- <起始點>
-
新分支的起始提交名稱;有關詳細資訊,請參見 git-branch[1]。預設為
HEAD
。作為特例,如果 <rev-a> 和 <rev-b> 只有一個合併基準,你可以使用 <rev-a>
...
<rev-b> 作為它們的合併基準的快捷方式。你可以最多省略 <rev-a> 和 <rev-b> 中的一個,在這種情況下它預設為HEAD
。 - <樹物件>
-
要從中檢出的樹(當給定路徑時)。如果未指定,將使用索引。
作為特例,如果 <rev-a> 和 <rev-b> 只有一個合併基準,你可以使用 <rev-a>
...
<rev-b> 作為它們的合併基準的快捷方式。你可以最多省略 <rev-a> 和 <rev-b> 中的一個,在這種情況下它預設為HEAD
。 --
-
不再將任何後續引數解釋為選項。
- <路徑規範>...
-
限制受操作影響的路徑。
有關更多詳細資訊,請參閱 gitglossary[7] 中的 pathspec 條目。
分離 HEAD
HEAD
通常指向一個命名分支(例如 master
)。同時,每個分支都指向一個特定的提交。讓我們看看一個包含三個提交的倉庫,其中一個已打標籤,並且 master
分支已被檢出:
HEAD (refers to branch 'master') | v a---b---c branch 'master' (refers to commit 'c') ^ | tag 'v2.0' (refers to commit 'b')
在這種狀態下建立提交時,分支會更新以指向新提交。具體來說,git
commit
會建立一個新提交 d
,其父級是提交 c
,然後更新 master
分支以指向新提交 d
。HEAD
仍然指向 master
分支,因此現在間接指向提交 d
。
$ edit; git add; git commit HEAD (refers to branch 'master') | v a---b---c---d branch 'master' (refers to commit 'd') ^ | tag 'v2.0' (refers to commit 'b')
有時,檢出不在任何命名分支頂端的提交,甚至建立一個未被命名分支引用的新提交,都是有用的。讓我們看看當我們檢出提交 b
時會發生什麼(這裡我們展示了兩種可能的方法):
$ git checkout v2.0 # or $ git checkout master^^ HEAD (refers to commit 'b') | v a---b---c---d branch 'master' (refers to commit 'd') ^ | tag 'v2.0' (refers to commit 'b')
請注意,無論我們使用哪個檢出命令,HEAD
現在都直接指向提交 b
。這被稱為處於分離 HEAD
狀態。它簡單地意味著 HEAD
指向一個特定的提交,而不是指向一個命名分支。讓我們看看當我們建立一個提交時會發生什麼:
$ edit; git add; git commit HEAD (refers to commit 'e') | v e / a---b---c---d branch 'master' (refers to commit 'd') ^ | tag 'v2.0' (refers to commit 'b')
現在有一個新提交 e
,但它只被 HEAD
引用。我們當然可以在這種狀態下再新增一個提交:
$ edit; git add; git commit HEAD (refers to commit 'f') | v e---f / a---b---c---d branch 'master' (refers to commit 'd') ^ | tag 'v2.0' (refers to commit 'b')
事實上,我們可以執行所有正常的 Git 操作。但是,讓我們看看當我們檢出 master
時會發生什麼:
$ git checkout master HEAD (refers to branch 'master') e---f | / v a---b---c---d branch 'master' (refers to commit 'd') ^ | tag 'v2.0' (refers to commit 'b')
重要的是要意識到,此時沒有任何東西引用提交 f
。最終,提交 f
(以及延伸的提交 e
)將被常規的 Git 垃圾回收過程刪除,除非在此之前我們建立了一個引用。如果我們還沒有從提交 f
移開,以下任何操作都將建立一個引用指向它:
$ git checkout -b foo # or "git switch -c foo" (1) $ git branch foo (2) $ git tag foo (3)
-
建立了一個新分支
foo
,它指向提交f
,然後更新HEAD
以指向分支foo
。換句話說,執行此命令後,我們將不再處於分離HEAD
狀態。 -
類似地,建立了一個指向提交
f
的新分支foo
,但保留了分離的HEAD
。 -
建立了一個指向提交
f
的新標籤foo
,保留了分離的HEAD
。
如果我們已經離開了提交 f
,那麼我們必須首先恢復它的物件名稱(通常透過使用 git reflog),然後我們才能建立指向它的引用。例如,要檢視 HEAD
引用過的最後兩個提交,我們可以使用以下任一命令:
$ git reflog -2 HEAD # or $ git log -g -2 HEAD
引數消歧
當只給定一個引數且不是 --
(例如 git
checkout
abc
),並且該引數既是一個有效的 <樹物件>(例如,分支 abc
存在)又是一個有效的 <路徑規範>(例如,名為“abc”的檔案或目錄存在)時,Git 通常會要求你進行消歧。然而,由於檢出分支是一個非常常見的操作,在這種情況下,git
checkout
abc
將“abc”視為一個 <樹物件>。如果你想從索引中檢出這些路徑,請使用 git
checkout
--
<路徑規範>。
示例
1. 路徑
以下序列將檢出 master
分支,將 Makefile
恢復到兩個修訂版本之前,不小心刪除了 hello.c
,然後從索引中將其恢復。
$ git checkout master (1) $ git checkout master~2 Makefile (2) $ rm -f hello.c $ git checkout hello.c (3)
-
切換分支
-
從另一個提交中取出檔案
-
從索引中恢復
hello.c
如果你想從索引中檢出 所有 C 語言原始檔,你可以這樣說:
$ git checkout -- '*.c'
請注意 *.c
周圍的引號。檔案 hello.c
也將被檢出,即使它不再在工作區中,因為檔案萬用字元用於匹配索引中的條目(而不是由 shell 在工作區中匹配)。
如果你有一個不幸地命名為 hello.c
的分支,這一步將被誤認為是切換到該分支的指令。你應該改為這樣寫:
$ git checkout -- hello.c
2. 合併
在錯誤的分支上工作後,切換到正確的分支將使用以下方式完成:
$ git checkout mytopic
然而,你的“錯誤”分支和正確的分支 mytopic
在你本地修改的檔案上可能存在差異,在這種情況下,上述檢出操作將像這樣失敗:
$ git checkout mytopic error: You have local changes to 'frotz'; not switching branches.
你可以向命令新增 -m
標誌,它會嘗試進行三方合併:
$ git checkout -m mytopic Auto-merging frotz
在此三方合併之後,本地修改 不會 註冊到你的索引檔案中,因此 git
diff
會顯示自新分支尖端以來你所做的更改。
配置
本節中以下所有內容均從 git-config[1] 文件中選擇性地包含。內容與彼處相同:
checkout.defaultRemote
-
當你執行
git
checkout
<something> 或git
switch
<something> 並且只有一個遠端倉庫時,它可能會隱式地回退到檢出和跟蹤例如origin/
<something>。一旦你有多個包含 <something> 引用的遠端倉庫,這將停止工作。此設定允許指定一個首選遠端倉庫的名稱,該遠端倉庫在消歧時應始終優先。典型的用例是將其設定為origin
。目前,當
git
checkout
<something> 或git
switch
<something> 將檢出另一個遠端倉庫上的 <something> 分支時,此設定被 git-switch[1] 和 git-checkout[1] 使用;當git
worktree
add
引用遠端分支時,此設定被 git-worktree[1] 使用。將來,此設定可能會用於其他類似檢出命令或功能。 checkout.guess
-
提供
git
checkout
和git
switch
中--guess
或--no-guess
選項的預設值。參見 git-switch[1] 和 git-checkout[1]。 checkout.workers
-
更新工作區時使用的並行工作程序數。預設值為一,即順序執行。如果設定為小於一的值,Git 將使用與可用邏輯核心數相同的工作程序數。此設定和
checkout.thresholdForParallelism
影響所有執行檢出操作的命令。例如 checkout、clone、reset、sparse-checkout 等。注意並行檢出通常對於位於 SSD 或透過 NFS 的倉庫提供更好的效能。對於位於旋轉磁碟和/或核心數量較少的機器上的倉庫,預設的順序檢出通常表現更好。倉庫的大小和壓縮級別也可能影響並行版本的效能。 checkout.thresholdForParallelism
-
當並行檢出少量檔案時,子程序生成和程序間通訊的開銷可能超過並行化帶來的收益。此設定允許你定義應嘗試並行檢出的最小檔案數量。預設值為 100。