簡體中文 ▾ 主題 ▾ 最新版本 ▾ git-fetch 最後更新於 2.48.0

名稱

git-fetch - 從另一個倉庫下載物件和引用

概要

git fetch [<options>] [<repository> [<refspec>…​]]
git fetch [<options>] <group>
git fetch --multiple [<options>] [(<repository> | <group>)…​]
git fetch --all [<options>]

描述

從一個或多個其他倉庫抓取分支和/或標籤(統稱為“引用”),以及完成其歷史所需的其他物件。遠端跟蹤分支將被更新(請參閱下文 <refspec> 的描述以瞭解如何控制此行為)。

預設情況下,任何指向所抓取歷史的標籤也會被抓取;其效果是抓取指向您感興趣的分支的標籤。此預設行為可以透過使用 --tags--no-tags 選項或配置 remote.<name>.tagOpt 來更改。透過使用顯式抓取標籤的 refspec,您也可以抓取不指向您感興趣的分支的標籤。

git fetch 可以從單個命名倉庫或 URL 抓取,也可以同時從多個倉庫抓取,如果給定 <group> 並且配置檔案中有 remotes.<group> 條目。(請參閱 git-config[1])。

未指定遠端倉庫時,預設使用 origin 遠端倉庫,除非當前分支已配置上游分支。

抓取到的引用名稱及其指向的物件名稱將寫入 .git/FETCH_HEAD。此資訊可用於指令碼或其他 Git 命令,例如 git-pull[1]

選項

--[no-]all

抓取所有遠端倉庫,除了那些設定了 remote.<name>.skipFetchAll 配置變數的倉庫。這會覆蓋配置變數 fetch.all

-a
--append

將抓取到的引用的名稱和物件名稱追加到 .git/FETCH_HEAD 的現有內容中。不使用此選項,.git/FETCH_HEAD 中的舊資料將被覆蓋。

--atomic

使用原子事務更新本地引用。要麼所有引用都更新,要麼出錯時,不更新任何引用。

--depth=<depth>

將抓取限制為每個遠端分支歷史尖端指定數量的提交。如果抓取到使用 git clone--depth=<depth> 選項建立的淺克隆倉庫(參見 git-clone[1]),則將歷史記錄加深或縮短到指定數量的提交。加深提交的標籤不會被抓取。

--deepen=<depth>

類似於 --depth,但它指定的是從當前淺克隆邊界開始的提交數量,而不是從每個遠端分支歷史的尖端開始。

--shallow-since=<date>

深化或縮短淺克隆倉庫的歷史記錄,以包含 <date> 之後所有可達的提交。

--shallow-exclude=<ref>

深化或縮短淺克隆倉庫的歷史記錄,以排除從指定遠端分支或標籤可達的提交。此選項可以多次指定。

--unshallow

如果源倉庫是完整的,則將淺克隆倉庫轉換為完整倉庫,移除淺克隆倉庫施加的所有限制。

如果源倉庫是淺克隆倉庫,則儘可能多地抓取,以便當前倉庫與源倉庫具有相同的歷史記錄。

--update-shallow

預設情況下,當從淺克隆倉庫抓取時,git fetch 會拒絕需要更新 .git/shallow 的引用。此選項會更新 .git/shallow 並接受此類引用。

--negotiation-tip=<commit|glob>

預設情況下,Git 會向伺服器報告所有本地引用可達的提交,以查詢共同提交,從而嘗試減少要接收的包檔案大小。如果指定此選項,Git 將僅報告給定尖端可達的提交。當用戶知道哪個本地引用可能與正在抓取的上游引用有共同提交時,這有助於加快抓取速度。

此選項可以多次指定;如果這樣,Git 將報告從任何給定提交可達的提交。

此選項的引數可以是引用名稱的 glob 模式、一個引用,或提交的(可能是縮寫的)SHA-1。指定 glob 模式等同於多次指定此選項,每次對應一個匹配的引用名稱。

另請參閱 git-config[1] 中記錄的 fetch.negotiationAlgorithmpush.negotiate 配置變數,以及下方的 --negotiate-only 選項。

--negotiate-only

不從伺服器抓取任何內容,而是列印與伺服器共同擁有的、由提供的 --negotiation-tip=* 引數指定的祖先。

這與 --recurse-submodules=[yes|on-demand] 不相容。在內部,此選項用於實現 push.negotiate 選項,請參閱 git-config[1]

--dry-run

顯示將要執行的操作,但不進行任何更改。

--porcelain

以易於指令碼解析的格式將輸出列印到標準輸出。詳情請參閱 git-fetch[1] 中的 OUTPUT 部分。

這與 --recurse-submodules=[yes|on-demand] 不相容,並優先於 fetch.output 配置選項。

--[no-]write-fetch-head

將抓取的遠端引用列表直接寫入 $GIT_DIR 下的 FETCH_HEAD 檔案。這是預設行為。從命令列傳遞 --no-write-fetch-head 會告訴 Git 不寫入此檔案。在 --dry-run 選項下,該檔案永遠不會寫入。

-f
--force

git fetch<src>:<dst> `refspec` 一起使用時,它可能會拒絕更新本地分支,如下面 <refspec> 部分所討論的。此選項會覆蓋該檢查。

-k
--keep

保留下載的包。

--multiple

允許指定多個 <repository><group> 引數。不能指定 <refspec>

--[no-]auto-maintenance
--[no-]auto-gc

在最後執行 git maintenance run --auto 以在需要時執行自動倉庫維護。(--[no-]auto-gc 是同義詞。)此功能預設啟用。

--[no-]write-commit-graph

抓取後寫入提交圖。這會覆蓋配置設定 fetch.writeCommitGraph

--prefetch

修改配置的 refspec,將所有引用放置到 refs/prefetch/ 名稱空間中。請參閱 git-maintenance[1] 中的 prefetch 任務。

-p
--prune

在抓取之前,刪除遠端倉庫中不再存在的任何遠端跟蹤引用。如果標籤僅因預設的標籤自動跟蹤或 --tags 選項而被抓取,則它們不受修剪。但是,如果標籤是由於顯式 refspec(無論是命令列上還是遠端配置中,例如如果遠端倉庫是用 --mirror 選項克隆的)而被抓取,那麼它們也受修剪。提供 --prune-tags 是提供標籤 refspec 的簡寫。

詳情請參閱下面的 PRUNING 部分。

-P
--prune-tags

在抓取之前,如果啟用了 --prune,則刪除遠端倉庫中不再存在的任何本地標籤。此選項應更謹慎使用,與 --prune 不同,它將刪除所有已建立的本地引用(本地標籤)。此選項是與 --prune 一起提供顯式標籤 refspec 的簡寫,請參閱其文件中的相關討論。

詳情請參閱下面的 PRUNING 部分。

-n
--no-tags

預設情況下,指向從遠端倉庫下載的物件的標籤會被抓取並本地儲存。此選項停用此自動標籤跟蹤。遠端倉庫的預設行為可以透過 remote.<name>.tagOpt 設定指定。請參閱 git-config[1]

--refetch

此選項不是與伺服器協商以避免傳輸本地已存在的提交和相關物件,而是像全新克隆一樣抓取所有物件。當過濾器定義更改時,使用此選項可以重新應用配置中的部分克隆過濾器或使用 --filter=。自動抓取後維護將執行物件資料庫包合併以刪除任何重複物件。

--refmap=<refspec>

當抓取命令列上列出的引用時,使用指定的 refspec(可以多次給定)將引用對映到遠端跟蹤分支,而不是使用遠端倉庫的 remote.*.fetch 配置變數的值。向 --refmap 選項提供一個空的 <refspec> 會使 Git 忽略已配置的 refspec,並完全依賴作為命令列引數提供的 refspec。詳情請參閱“已配置的遠端跟蹤分支”部分。

-t
--tags

除了其他將被抓取的內容之外,從遠端倉庫抓取所有標籤(即,將遠端標籤 refs/tags/* 抓取到本地同名標籤中)。單獨使用此選項不會使標籤受到修剪,即使使用了 --prune 也是如此(儘管如果標籤也是顯式 refspec 的目標,則無論如何都可能修剪標籤;請參閱 --prune)。

--recurse-submodules[=(yes|on-demand|no)]

此選項控制是否以及在何種條件下也應抓取子模組的新提交。當遞迴遍歷子模組時,git fetch 總是嘗試抓取“已更改”的子模組,即,一個子模組包含被新抓取的超專案提交引用但在本地子模組克隆中缺失的提交。只要子模組在本地存在(例如在 $GIT_DIR/modules/ 中)(參見 gitsubmodules[7]),就可以抓取已更改的子模組;如果上游添加了新的子模組,則該子模組在透過例如 git submodule update 克隆之前無法抓取。

當設定為 on-demand 時,只抓取已更改的子模組。當設定為 yes 時,抓取所有已填充的子模組,並且抓取未填充但已更改的子模組。當設定為 no 時,永不抓取子模組。

未指定時,如果設定了 fetch.recurseSubmodules,則使用其值(參見 git-config[1]),如果未設定則預設為 on-demand。當此選項不帶任何值使用時,預設為 yes

-j
--jobs=<n>

用於所有形式抓取的並行子程序數量。

如果指定了 --multiple 選項,則不同的遠端倉庫將並行抓取。如果抓取多個子模組,它們將並行抓取。要獨立控制它們,請使用配置設定 fetch.parallelsubmodule.fetchJobs(參見 git-config[1])。

通常,並行遞迴和多遠端抓取會更快。預設情況下,抓取是按順序執行的,而不是並行。

--no-recurse-submodules

停用子模組的遞迴抓取(這與使用 --recurse-submodules=no 選項效果相同)。

--set-upstream

如果遠端倉庫成功抓取,則新增上游(跟蹤)引用,供無引數的 git-pull[1] 和其他命令使用。更多資訊,請參閱 git-config[1] 中的 branch.<name>.mergebranch.<name>.remote

--submodule-prefix=<path>

在“正在抓取子模組 foo”等資訊性訊息中列印的路徑前加上 <path>。此選項在遞迴遍歷子模組時內部使用。

--recurse-submodules-default=[yes|on-demand]

此選項在內部用於臨時為 --recurse-submodules 選項提供一個非負的預設值。所有其他配置抓取子模組遞迴的方法(例如 gitmodules[5]git-config[1] 中的設定)都會覆蓋此選項,直接指定 --[no-]recurse-submodules 也是如此。

-u
--update-head-ok

預設情況下 git fetch 拒絕更新與當前分支對應的 HEAD。此標誌停用該檢查。這純粹是 git pullgit fetch 通訊的內部使用,除非您正在實現自己的 Porcelain 命令,否則不應使用它。

--upload-pack <upload-pack>

當給定此選項,並且要從中抓取的倉庫由 git fetch-pack 處理時,--exec=<upload-pack> 將傳遞給命令,以指定在另一端執行的命令的非預設路徑。

-q
--quiet

--quiet 傳遞給 git-fetch-pack 並靜默所有其他內部使用的 Git 命令。進度不會報告到標準錯誤流。

-v
--verbose

啟用詳細輸出。

--progress

預設情況下,當標準錯誤流連線到終端時,會報告進度狀態,除非指定了 -q。此標誌強制報告進度狀態,即使標準錯誤流未定向到終端。

-o <option>
--server-option=<option>

使用協議版本 2 進行通訊時,將給定字串傳輸到伺服器。給定字串不得包含 NUL 或 LF 字元。伺服器對伺服器選項(包括未知選項)的處理是伺服器特定的。當給定多個 --server-option=<option> 時,它們將按照命令列中列出的順序全部發送到另一端。當命令列沒有給定 --server-option=<option> 時,將使用配置變數 remote.<name>.serverOption 的值。

--show-forced-updates

預設情況下,Git 會在抓取期間檢查分支是否被強制更新。這可以透過 fetch.showForcedUpdates 停用,但 --show-forced-updates 選項保證會進行此檢查。請參閱 git-config[1]

--no-show-forced-updates

預設情況下,Git 會在抓取期間檢查分支是否被強制更新。傳遞 --no-show-forced-updates 或將 fetch.showForcedUpdates 設定為 false 以出於效能原因跳過此檢查。如果在 git-pull 期間使用,--ff-only 選項在嘗試快進更新之前仍會檢查強制更新。請參閱 git-config[1]

-4
--ipv4

僅使用 IPv4 地址,忽略 IPv6 地址。

-6
--ipv6

僅使用 IPv6 地址,忽略 IPv4 地址。

<repository>

“遠端”倉庫,它是抓取或拉取操作的來源。此引數可以是 URL(請參閱下面的 GIT URLS 部分)或遠端倉庫的名稱(請參閱下面的 REMOTES 部分)。

<group>

在配置檔案中,指代作為 remotes.<group> 值的倉庫列表的名稱。(請參閱 git-config[1])。

<refspec>

指定要抓取的引用以及要更新的本地引用。當命令列上沒有 <refspec> 時,要抓取的引用將從 remote.<repository>.fetch 變數中讀取(請參閱下面的 已配置的遠端跟蹤分支)。

<refspec> 引數的格式是可選的加號 +,後跟源 <src>,後跟冒號 :,再後跟目標 <dst>。當 <dst> 為空時可以省略冒號。<src> 通常是一個引用,或者帶有單個 * 的 glob 模式,用於匹配一組引用,但它也可以是一個完整的十六進位制物件名稱。

一個 <refspec> 可以在其 <src> 中包含 * 以表示簡單的模式匹配。這樣的 refspec 功能類似於匹配任何符合該模式的引用的 glob 模式。一個模式 <refspec> 必須在 <src><dst> 中都只有一個 *。它將透過將 * 替換為源中匹配的內容來將引用對映到目標。

如果一個 refspec 以 ^ 為字首,它將被解釋為負 refspec。這樣的 refspec 不指定要抓取哪些引用或要更新哪些本地引用,而是指定要排除的引用。如果一個引用至少匹配一個正 refspec 並且不匹配任何負 refspec,則認為它匹配。負 refspec 對於限制模式 refspec 的範圍很有用,使其不包含特定引用。負 refspec 本身可以是模式 refspec。但是,它們只能包含 <src> 並且不指定 <dst>。也不支援完整的十六進位制物件名稱。

tag <tag>refs/tags/<tag>:refs/tags/<tag> 的含義相同;它請求抓取直到給定標籤的所有內容。

匹配 <src> 的遠端引用被抓取,如果 <dst> 不是空字串,則嘗試更新匹配它的本地引用。

不使用 --force 是否允許該更新取決於它被抓取到的引用名稱空間、被抓取的物件型別,以及該更新是否被視為快進。通常,抓取時適用與推送時相同的規則,有關這些規則,請參閱 git-push[1]<refspec>... 部分。下面註明了 git fetch 特有的規則例外。

在 Git 2.20 版本之前,與使用 git-push[1] 推送不同,對 refs/tags/* 的任何更新都將在 refspec 中不帶 +(或 --force)的情況下被接受。抓取時,我們隨意地將遠端倉庫的所有標籤更新視為強制抓取。從 Git 2.20 版本開始,抓取以更新 refs/tags/* 的工作方式與推送時相同。即,任何更新都將在 refspec 中不帶 +(或 --force)的情況下被拒絕。

與使用 git-push[1] 推送不同,refs/{tags,heads}/* 之外的任何更新都將在 refspec 中不帶 +(或 --force)的情況下被接受,無論是將樹物件替換為 blob,還是將提交替換為另一個不將前一個提交作為祖先的提交等。

與使用 git-push[1] 推送不同,沒有配置會修改這些規則,也沒有類似於 pre-receive 鉤子的 pre-fetch 鉤子。

與使用 git-push[1] 推送一樣,上述所有關於不允許更新的規則都可以透過在 refspec 前新增可選的引導 +(或使用 --force 命令列選項)來覆蓋。唯一的例外是,無論如何強制,refs/heads/* 名稱空間都不會接受非提交物件。

注意
當已知您要抓取的遠端分支會定期回滾和變基時,其新尖端預計不會是其先前尖端(上次抓取時儲存在您的遠端跟蹤分支中)的後代。您會希望使用 + 符號來指示此類分支需要非快進更新。無法確定或宣告一個倉庫中的分支將具有此行為;拉取使用者只需知道這是該分支的預期使用模式。
--stdin

除了作為引數提供的 refspec 外,還從標準輸入中逐行讀取 refspec。“tag <name>”格式不受支援。

GIT URLS

通常,URL 包含有關傳輸協議、遠端伺服器地址和倉庫路徑的資訊。根據傳輸協議,其中一些資訊可能不存在。

Git 支援 ssh、git、http 和 https 協議(此外,ftp 和 ftps 也可用於獲取,但這效率低下且已棄用;請勿使用它們)。

原生傳輸(即 git:// URL)不進行身份驗證,在不安全的網路上應謹慎使用。

可以使用以下語法:

  • ssh://[<user>@]<host>[:<port>]/<path-to-git-repo>

  • git://<host>[:<port>]/<path-to-git-repo>

  • http[s]://<host>[:<port>]/<path-to-git-repo>

  • ftp[s]://<host>[:<port>]/<path-to-git-repo>

ssh 協議還可以使用另一種類似 scp 的語法:

  • [<user>@]<host>:/<path-to-git-repo>

只有在第一個冒號前沒有斜槓時才識別此語法。這有助於區分包含冒號的本地路徑。例如,本地路徑 foo:bar 可以指定為絕對路徑或 ./foo:bar,以避免被錯誤地解釋為 SSH URL。

ssh 和 git 協議還支援 ~<username> 擴充套件

  • ssh://[<user>@]<host>[:<port>]/~<user>/<path-to-git-repo>

  • git://<host>[:<port>]/~<user>/<path-to-git-repo>

  • [<user>@]<host>:~<user>/<path-to-git-repo>

對於 Git 本身也支援的本地倉庫,可以使用以下語法

  • /path/to/repo.git/

  • file:///path/to/repo.git/

這兩種語法大部分是等效的,除了在克隆時,前者意味著 --local 選項。有關詳細資訊,請參閱 git-clone[1]

git clonegit fetchgit pull(但 git push 不支援)也會接受合適的捆綁檔案。請參閱 git-bundle[1]

當 Git 不知道如何處理某個傳輸協議時,它會嘗試使用 remote-<transport> 遠端輔助程式(如果存在)。要顯式請求遠端輔助程式,可以使用以下語法:

  • <transport>::<address>

其中 <address> 可以是路徑、伺服器和路徑,或者是特定遠端輔助工具可識別的任意類 URL 字串。有關詳細資訊,請參閱 gitremote-helpers[7]

如果存在大量名稱相似的遠端倉庫,並且您想為它們使用不同的格式(以便您使用的 URL 將被重寫為可用的 URL),您可以建立以下形式的配置節:

	[url "<actual-url-base>"]
		insteadOf = <other-url-base>

例如,有了這個:

	[url "git://git.host.xz/"]
		insteadOf = host.xz:/path/to/
		insteadOf = work:

“work:repo.git”或“host.xz:/path/to/repo.git”這樣的 URL 在任何接受 URL 的上下文中都將被重寫為“git://git.host.xz/repo.git”。

如果只想重寫推送的 URL,可以建立以下形式的配置節:

	[url "<actual-url-base>"]
		pushInsteadOf = <other-url-base>

例如,有了這個:

	[url "ssh://example.org/"]
		pushInsteadOf = git://example.org/

像“git://example.org/path/to/repo.git”這樣的 URL 將被重寫為“ssh://example.org/path/to/repo.git”用於推送,但拉取仍將使用原始 URL。

遠端倉庫

以下之一的名稱可以作為 <repository> 引數來代替 URL 使用:

  • Git 配置檔案中的遠端倉庫:$GIT_DIR/config

  • $GIT_DIR/remotes 目錄中的檔案,或

  • $GIT_DIR/branches 目錄中的檔案。

所有這些也允許你省略命令列中的引用規範,因為它們各自包含一個 Git 將預設使用的引用規範。

配置檔案中的命名遠端倉庫

您可以選擇提供之前使用 git-remote[1]git-config[1] 配置過的遠端倉庫名稱,甚至可以透過手動編輯 $GIT_DIR/config 檔案來配置。此遠端倉庫的 URL 將用於訪問倉庫。當您未在命令列提供 refspec 時,此遠端倉庫的 refspec 將預設使用。配置檔案中的條目將顯示如下:

	[remote "<name>"]
		url = <URL>
		pushurl = <pushurl>
		push = <refspec>
		fetch = <refspec>

<pushurl> 僅用於推送。它是可選的,預設為 <URL>。推送到遠端倉庫會影響所有已定義的 pushurl,如果未定義 pushurl 則影響所有已定義的 url。但是,如果定義了多個 url,抓取只會從第一個定義的 url 抓取。

$GIT_DIR/remotes 中的命名檔案

您可以選擇提供 $GIT_DIR/remotes 中的檔名。此檔案中的 URL 將用於訪問倉庫。當您未在命令列提供 refspec 時,此檔案中的 refspec 將預設使用。此檔案應具有以下格式:

	URL: one of the above URL formats
	Push: <refspec>
	Pull: <refspec>

Push: 行由 git push 使用,Pull: 行由 git pullgit fetch 使用。可以指定多個 Push:Pull: 行以進行額外的分支對映。

$GIT_DIR/branches 中的命名檔案

你可以選擇提供 $GIT_DIR/branches 中的檔名稱。此檔案中的 URL 將用於訪問倉庫。此檔案應具有以下格式:

	<URL>#<head>

<URL> 是必需的;#<head> 是可選的。

根據操作,如果您未在命令列提供 refspec,Git 將使用以下 refspec 之一。<branch>$GIT_DIR/branches 中此檔案的名稱,<head> 預設為 master

git fetch 使用

	refs/heads/<head>:refs/heads/<branch>

git push 使用

	HEAD:refs/heads/<head>

已配置的遠端跟蹤分支

您經常透過定期反覆從同一個遠端倉庫抓取來與它互動。為了跟蹤此類遠端倉庫的進度,git fetch 允許您配置 remote.<repository>.fetch 配置變數。

通常此類變數可能如下所示:

[remote "origin"]
	fetch = +refs/heads/*:refs/remotes/origin/*

此配置有兩種使用方式:

  • 當不帶命令列引數指定要抓取的分支和/或標籤執行 git fetch 時(例如 git fetch origingit fetch),remote.<repository>.fetch 的值將用作 refspec——它們指定要抓取哪些引用以及要更新哪些本地引用。上面的示例將抓取 origin 中存在的所有分支(即匹配該值左側 refs/heads/* 的任何引用),並更新 refs/remotes/origin/* 層次結構中相應的遠端跟蹤分支。

  • 當在命令列上執行 git fetch 並顯式指定要抓取的分支和/或標籤時(例如 git fetch origin master),命令列上給定的 <refspec> 決定要抓取什麼(例如示例中的 master,它是 master: 的簡寫,後者又意味著“抓取 master 分支,但我沒有在命令列上明確說明要用它更新哪個遠端跟蹤分支”),並且示例命令將抓取 master 分支。remote.<repository>.fetch 的值決定哪個遠端跟蹤分支(如果有)被更新。以這種方式使用時,remote.<repository>.fetch 的值在決定抓取什麼時沒有任何作用(即,當命令列列出 refspec 時,這些值不作為 refspec 使用);它們僅透過充當對映來決定抓取到的引用儲存在哪裡。

remote.<repository>.fetch 值的後一種用法可以透過在命令列上提供 --refmap=<refspec> 引數來覆蓋。

修剪

Git 預設傾向於保留資料,除非明確丟棄;這延伸到保留對遠端倉庫上已刪除分支的本地引用。

如果任其累積,這些陳舊的引用可能會導致在分支變動頻繁的大型繁忙倉庫中效能下降,並且例如使 git branch -a --contains <commit> 等命令的輸出變得不必要的冗長,還會影響任何處理所有已知引用的操作。

這些遠端跟蹤引用可以一次性刪除,使用以下任一命令:

# While fetching
$ git fetch --prune <name>

# Only prune, don't fetch
$ git remote prune <name>

要在您的正常工作流程中修剪引用而無需記住執行它,請在配置中全域性設定 fetch.prune,或為每個遠端倉庫設定 remote.<name>.prune。請參閱 git-config[1]

這裡事情變得棘手且更具體。修剪功能實際上不關心分支,而是根據遠端倉庫的 refspec 來修剪本地 ←→ 遠端引用(請參閱上面的 <refspec>已配置的遠端跟蹤分支)。

因此,如果遠端倉庫的 refspec 包含例如 refs/tags/*:refs/tags/*,或者您手動執行例如 git fetch --prune <name> "refs/tags/*:refs/tags/*",那麼被刪除的將不是陳舊的遠端跟蹤分支,而是遠端倉庫上不存在的任何本地標籤。

這可能不是您所期望的,即您想修剪遠端倉庫 <name>,但又顯式地從它抓取標籤,因此當您從它抓取時,您會刪除所有本地標籤,其中大部分可能最初並非來自遠端倉庫 <name>

因此,當與 refs/tags/*:refs/tags/* 或任何其他可能將多個遠端倉庫的引用對映到同一本地名稱空間的 refspec 一起使用時,請務必小心。

由於保持與遠端倉庫的分支和標籤同步是一個常見用例,因此可以 साथ --prune 選項與 --prune-tags 選項一起提供,以修剪遠端倉庫上不存在的本地標籤,並強制更新不同的標籤。標籤修剪也可以透過配置中的 fetch.pruneTagsremote.<name>.pruneTags 啟用。請參閱 git-config[1]

--prune-tags 選項等同於在遠端倉庫的 refspec 中宣告 refs/tags/*:refs/tags/*。這可能導致一些看似奇怪的互動:

# These both fetch tags
$ git fetch --no-tags origin 'refs/tags/*:refs/tags/*'
$ git fetch --no-tags --prune-tags origin

之所以不帶 --prune 或其配置版本提供時不會報錯,是為了配置版本的靈活性,並保持命令列標誌與配置版本功能之間的 1:1 對映。

例如,在 ~/.gitconfig 中配置 fetch.pruneTags=true,以便在每次執行 git fetch --prune 時都修剪標籤,而不會使每次不帶 --prune 執行 git fetch 都產生錯誤,這是合理的。

使用 --prune-tags 修剪標籤在抓取 URL 而不是命名遠端倉庫時也有效。這些都將修剪在 origin 上未找到的標籤:

$ git fetch origin --prune --prune-tags
$ git fetch origin --prune 'refs/tags/*:refs/tags/*'
$ git fetch <url-of-origin> --prune --prune-tags
$ git fetch <url-of-origin> --prune 'refs/tags/*:refs/tags/*'

輸出

git fetch”的輸出取決於所使用的傳輸方法;本節描述透過 Git 協議(本地或透過 ssh)和智慧 HTTP 協議抓取時的輸出。

抓取狀態以表格形式輸出,每行代表一個引用的狀態。每行的格式為:

 <flag> <summary> <from> -> <to> [<reason>]

當使用 --porcelain 時,輸出格式旨在供機器解析。與人類可讀的輸出格式相比,它因此列印到標準輸出而不是標準錯誤。每行的格式為:

<flag> <old-object-id> <new-object-id> <local-reference>

只有在使用 --verbose 選項時,才會顯示最新引用的狀態。

在緊湊輸出模式下(由配置變數 fetch.output 指定),如果 entire <from>entire <to> 中的任一個在另一個字串中找到,它將用 * 替換另一個字串中的該部分。例如,master -> origin/master 變為 master -> origin/*

flag

一個字元,指示引用的狀態:

(空格)

表示成功抓取的快進;

+

表示成功的強制更新;

-

表示成功修剪的引用;

t

表示成功的標籤更新;

*

表示成功抓取的新引用;

!

表示被拒絕或未能更新的引用;以及

=

表示已是最新且無需抓取的引用。

summary

對於成功抓取的引用,摘要以適合作為 git log 引數的形式顯示引用的舊值和新值(在大多數情況下是 <old>..<new>,對於強制的非快進更新則是 <old>...<new>)。

from

正在抓取的遠端引用的名稱,不包括其 refs/<type>/ 字首。在刪除的情況下,遠端引用的名稱是“(none)”。

to

正在更新的本地引用的名稱,不包括其 refs/<type>/ 字首。

reason

人類可讀的解釋。對於成功抓取的引用,無需解釋。對於失敗的引用,會描述失敗原因。

示例

  • 更新遠端跟蹤分支

    $ git fetch origin

    上述命令將遠端 refs/heads/ 名稱空間中的所有分支複製並存儲到本地 refs/remotes/origin/ 名稱空間中,除非使用 remote.<repository>.fetch 選項指定了非預設 refspec。

  • 顯式使用 refspec

    $ git fetch origin +seen:seen maint:tmp

    這透過分別從遠端倉庫的 seenmaint 分支抓取,來更新(或在必要時建立)本地倉庫中的 seentmp 分支。

    seen 分支即使不是快進也會被更新,因為它帶有加號字首;tmp 則不會。

  • 檢視遠端分支,無需在本地倉庫中配置遠端倉庫

    $ git fetch git://git.kernel.org/pub/scm/git/git.git maint
    $ git log FETCH_HEAD

    第一個命令從 git://git.kernel.org/pub/scm/git/git.git 倉庫抓取 maint 分支,第二個命令使用 FETCH_HEAD 透過 git-log[1] 檢查該分支。抓取到的物件最終將由 Git 的內建維護程式移除(參見 git-gc[1])。

安全性

抓取和推送協議並非旨在防止一方從另一方倉庫竊取不打算共享的資料。如果您有需要保護免受惡意對等方侵害的私有資料,最佳選擇是將其儲存在另一個倉庫中。這適用於客戶端和伺服器。特別是,伺服器上的名稱空間對於讀取訪問控制無效;您應該只向信任其擁有整個倉庫讀取訪問許可權的客戶端授予對名稱空間的讀取訪問許可權。

已知的攻擊向量如下:

  1. 受害者傳送“have”行,宣傳其擁有的、不明確打算共享但如果對等方也有則可用於最佳化傳輸的物件 ID。攻擊者選擇要竊取的目標物件 ID X 並向 X 傳送一個引用,但不需要傳送 X 的內容,因為受害者已經擁有它。現在受害者認為攻擊者擁有 X,並且隨後將 X 的內容發回給攻擊者。(這種攻擊對於客戶端在伺服器上執行最直接,透過在客戶端有權訪問的名稱空間中建立指向 X 的引用,然後抓取它。伺服器在客戶端上執行的最可能方式是“合併”X 到公共分支,並希望使用者在此分支上進行額外工作並將其推送回伺服器而沒有注意到合併。)

  2. 與 #1 類似,攻擊者選擇要竊取的目標物件 ID X。受害者傳送攻擊者已有的物件 Y,攻擊者虛假聲稱擁有 X 而沒有 Y,因此受害者將 Y 作為相對於 X 的增量傳送。此增量向攻擊者揭示了 X 中與 Y 相似的區域。

配置

本節中以下所有內容均從 git-config[1] 文件中選擇性地包含。內容與彼處相同:

fetch.recurseSubmodules

此選項控制 git fetch(以及 git pull 中的底層抓取)是否會遞迴抓取到已填充的子模組中。此選項可以設定為布林值或 on-demand。將其設定為布林值會更改抓取和拉取的行為:設定為 true 時無條件遞迴到子模組中,設定為 false 時完全不遞迴。當設定為 on-demand 時,抓取和拉取將只會在其超專案檢索到更新子模組引用的提交時遞迴到已填充的子模組中。預設為 on-demand,如果設定了 submodule.recurse,則預設為 submodule.recurse 的值。

fetch.fsckObjects

如果設定為 truegit-fetch-pack 將檢查所有抓取到的物件。有關檢查內容,請參閱 transfer.fsckObjects。預設為 false。如果未設定,則使用 transfer.fsckObjects 的值。

fetch.fsck.<msg-id>

作用類似於 fsck.<msg-id>,但由 git-fetch-pack[1] 而非 git-fsck[1] 使用。詳情請參閱 fsck.<msg-id> 文件。

fetch.fsck.skipList

作用類似於 fsck.skipList,但由 git-fetch-pack[1] 而非 git-fsck[1] 使用。詳情請參閱 fsck.skipList 文件。

fetch.unpackLimit

如果透過 Git 原生傳輸抓取的物件數量低於此限制,則這些物件將被解包為鬆散物件檔案。但是,如果接收到的物件數量等於或超過此限制,則接收到的包將作為包儲存,並在新增任何缺失的增量基礎後。從推送儲存包可以使推送操作更快完成,特別是在慢速檔案系統上。如果未設定,則使用 transfer.unpackLimit 的值。

fetch.prune

如果為 true,抓取將自動錶現為在命令列上給出了 --prune 選項。另請參閱 remote.<name>.prunegit-fetch[1] 的 PRUNING 部分。

fetch.pruneTags

如果為 true,如果尚未設定,抓取將自動錶現為在修剪時提供了 refs/tags/*:refs/tags/* refspec。這允許同時設定此選項和 fetch.prune,以維護與上游引用的 1:1 對映。另請參閱 remote.<name>.pruneTagsgit-fetch[1] 的 PRUNING 部分。

fetch.all

如果為 true,抓取將嘗試更新所有可用的遠端倉庫。此行為可以透過傳遞 --no-all 或顯式指定一個或多個要從中抓取的遠端倉庫來覆蓋。預設為 false

fetch.output

控制引用更新狀態的列印方式。有效值為 fullcompact。預設值為 full。詳情請參閱 git-fetch[1] 的 OUTPUT 部分。

fetch.negotiationAlgorithm

控制在協商伺服器要傳送的包檔案內容時,如何傳送關於本地倉庫中提交的資訊。設定為 "consecutive" 以使用一種演算法,該演算法遍歷連續的提交併檢查每個提交。設定為 "skipping" 以使用一種演算法,該演算法跳過提交以努力更快地收斂,但這可能導致包檔案大於必要的大小;或者設定為 "noop" 以完全不傳送任何資訊,這幾乎肯定會導致包檔案大於必要的大小,但會跳過協商步驟。設定為 "default" 以覆蓋之前所做的設定並使用預設行為。預設通常是 "consecutive",但如果 feature.experimentaltrue,則預設為 "skipping"。未知值將導致 git fetch 出錯。

另請參閱 git-fetch[1]--negotiate-only--negotiation-tip 選項。

fetch.showForcedUpdates

設定為 false 以在 git-fetch[1]git-pull[1] 命令中啟用 --no-show-forced-updates。預設為 true

fetch.parallel

指定同時並行執行的最大抓取運算元(子模組,或當 git-fetch[1]--multiple 選項生效時的遠端倉庫)。

值為 0 將給出一些合理的預設值。如果未設定,則預設為 1。

對於子模組,此設定可以使用 submodule.fetchJobs 配置設定來覆蓋。

fetch.writeCommitGraph

設定為 true,以便在每次從遠端下載包檔案的 git fetch 命令後寫入提交圖。使用 --split 選項,大多數執行將在現有提交圖檔案之上建立一個非常小的提交圖檔案。偶爾,這些檔案會合並,寫入可能需要更長時間。擁有更新的提交圖檔案有助於許多 Git 命令的效能,包括 git merge-basegit push -fgit log --graph。預設為 false

fetch.bundleURI

此值儲存一個 URI,用於在從原始 Git 伺服器執行增量抓取之前,從捆綁 URI 下載 Git 物件資料。這類似於 git-clone[1]--bundle-uri 選項的行為。如果提供的捆綁 URI 包含為增量抓取組織的捆綁列表,git clone --bundle-uri 將設定 fetch.bundleURI 值。

如果您修改此值且您的倉庫有 fetch.bundleCreationToken 值,則在從新的捆綁 URI 抓取之前,請刪除該 fetch.bundleCreationToken 值。

fetch.bundleCreationToken

當使用 fetch.bundleURI 從使用“creationToken”啟發式方法的捆綁列表中增量抓取時,此配置值儲存已下載捆綁的最大 creationToken 值。此值用於防止將來下載捆綁,如果釋出的 creationToken 不嚴格大於此值。

creationToken 值由提供特定捆綁 URI 的提供者選擇。如果您修改 fetch.bundleURI 的 URI,則請務必在抓取之前刪除 fetch.bundleCreationToken 的值。

BUG

使用 --recurse-submodules 只能抓取本地存在的子模組(例如在 $GIT_DIR/modules/ 中)中的新提交。如果上游添加了一個新的子模組,該子模組在透過 git submodule update 克隆之前無法被抓取。這預計將在未來的 Git 版本中修復。

另請參閱

GIT

Git[1] 套件的一部分

scroll-to-top