# git-fetch
> 原文: [https://git-scm.com/docs/git-fetch](https://git-scm.com/docs/git-fetch)
## 名稱
git-fetch - 從另一個存儲庫下載對象和引用
## 概要
```
git fetch [<options>] [<repository> [<refspec>…?]]
git fetch [<options>] <group>
git fetch --multiple [<options>] [(<repository> | <group>)…?]
git fetch --all [<options>]
```
## 描述
從一個或多個其他存儲庫中獲取分支和/或標記(統稱為“refs”),以及完成其歷史記錄所需的對象。遠程跟蹤分支已更新(有關控制此行為的方法,請參閱下面< refspec>的說明)。
默認情況下,還會獲取指向要獲取的歷史記錄的任何標記;效果是獲取指向您感興趣的分支的標記。可以使用--tags或--no-tags選項或配置遠程來更改此默認行為。< name> .tagOpt。通過使用明確獲取標記的refspec,您可以獲取不指向您感興趣的分支的標記。
_git fetch_ 可以從單個命名的存儲庫或URL獲取,或者如果< group>則從一個存儲庫獲取。給出并且有一個遙控器。< group>配置文件中的條目。 (參見 [git-config [1]](https://git-scm.com/docs/git-config) )。
如果未指定遠程,則默認情況下將使用`origin`遠程,除非為當前分支配置了上游分支。
獲取的引用名稱及其指向的對象名稱將寫入`.git/FETCH_HEAD`。腳本或其他git命令可以使用此信息,例如 [git-pull [1]](https://git-scm.com/docs/git-pull) 。
## OPTIONS
```
--all
```
獲取所有遙控器。
```
-a
```
```
--append
```
將獲取的引用的引用名稱和對象名稱附加到`.git/FETCH_HEAD`的現有內容。如果沒有此選項,`.git/FETCH_HEAD`中的舊數據將被覆蓋。
```
--depth=<depth>
```
從每個遠程分支歷史記錄的提示限制提取到指定的提交數。如果使用`--depth=<depth>`選項(參見 [git-clone [1]](https://git-scm.com/docs/git-clone) )獲取`git clone`創建的_淺_存儲庫,請將歷史記錄加深或縮短到指定的提交數。不提取深化提交的標記。
```
--deepen=<depth>
```
與--depth類似,不同之處在于它指定了當前淺邊界而不是每個遠程分支歷史記錄的提交數。
```
--shallow-since=<date>
```
深化或縮短淺存儲庫的歷史記錄,以包括< date>之后的所有可訪問提交。
```
--shallow-exclude=<revision>
```
深化或縮短淺存儲庫的歷史記錄,以排除從指定的遠程分支或標記可到達的提交。可以多次指定此選項。
```
--unshallow
```
如果源存儲庫已完成,請將淺存儲庫轉換為完整存儲庫,從而消除淺存儲庫所施加的所有限制。
如果源存儲庫很淺,則盡可能多地獲取,以便當前存儲庫與源存儲庫具有相同的歷史記錄。
```
--update-shallow
```
默認情況下,從淺存儲庫中獲取時,`git fetch`拒絕需要更新.git / shallow的引用。此選項更新.git / shallow并接受此類引用。
```
--negotiation-tip=<commit|glob>
```
默認情況下,Git將向服務器報告可從所有本地引用訪問的提交,以查找公共提交以嘗試減少要接收的包文件的大小。如果指定,Git將僅報告從給定提示可到達的提交。當用戶知道哪個本地ref可能與正在獲取的上游引用有共同提交時,這對于加速提取是有用的。
可以多次指定此選項;如果是這樣,Git將報告從任何給定提交可到達的提交。
此選項的參數可以是ref的名稱,ref或者提交的(可能縮寫的)SHA-1上的glob。指定glob等效于多次指定此選項,每個匹配的ref名稱一個。
另請參見 [git-config [1]](https://git-scm.com/docs/git-config) 中記錄的`fetch.negotiationAlgorithm`配置變量。
```
--dry-run
```
顯示將要完成的任務,而不進行任何更改。
```
-f
```
```
--force
```
當 _git fetch_ 與`<src>:<dst>` refspec一起使用時,它可能會拒絕更新本地分支,如下面`<refspec>`部分所述。此選項會覆蓋該檢查。
```
-k
```
```
--keep
```
保持下載的包。
```
--multiple
```
允許多個< repository>和< group>要指定的參數。不能指定< refspec> s。
```
-p
```
```
--prune
```
在獲取之前,刪除遠程不再存在的任何遠程跟蹤引用。如果僅由于默認標記自動跟蹤或由于--tags選項而提取標記,則不對其進行修剪。但是,如果由于顯式refspec(在命令行或遠程配置中,例如,如果使用--mirror選項克隆遠程),則會提取標記,那么它們也會受到修剪。提供`--prune-tags`是提供標簽refspec的簡寫。
有關詳細信息,請參閱下面的PRUNING部分。
```
-P
```
```
--prune-tags
```
在獲取之前,如果啟用了`--prune`,則刪除遙控器上不再存在的任何本地標簽。應該更仔細地使用此選項,與`--prune`不同,它將刪除已創建的任何本地引用(本地標記)。此選項是提供顯式標記refspec和`--prune`的簡寫,請參閱其文檔中有關該標記的討論。
有關詳細信息,請參閱下面的PRUNING部分。
```
-n
```
```
--no-tags
```
默認情況下,指向從遠程存儲庫下載的對象的標記將被提取并存儲在本地。此選項會禁用此自動標記。可以使用遠程。< name> .tagOpt設置指定遠程的默認行為。見 [git-config [1]](https://git-scm.com/docs/git-config) 。
```
--refmap=<refspec>
```
在獲取命令行中列出的引用時,使用指定的refspec(可以多次給出)將refs映射到遠程跟蹤分支,而不是遠程存儲庫的`remote.*.fetch`配置變量的值。有關詳細信息,請參閱“已配置的遠程跟蹤分支”部分。
```
-t
```
```
--tags
```
從遠程獲取所有標記(即,將遠程標記`refs/tags/*`提取到具有相同名稱的本地標記),以及否則將獲取的任何其他標記。即使使用了--prune,單獨使用此選項也不會對標記進行修剪(盡管如果它們也是顯式refspec的目標,則無論如何都可以修剪標記;請參閱`--prune`)。
```
--recurse-submodules[=yes|on-demand|no]
```
此選項控制是否以及在何種條件下應該提取已填充的子模塊的新提交。當設置為 _no_ 時,它可以用作布爾選項來完全禁用遞歸,或者當設置為 _yes_ 時無條件地遞歸到所有填充的子模塊,這是使用此選項時的默認值沒有任何價值。當超級項目檢索到更新子模塊對尚未在本地子模塊克隆中的提交的引用的提交時,使用_按需_僅遞歸到填充的子模塊。
```
-j
```
```
--jobs=<n>
```
用于獲取子模塊的并行子節點數。每個都將從不同的子模塊中獲取,這樣獲取許多子模塊的速度會更快。默認情況下,將一次提取一個子模塊。
```
--no-recurse-submodules
```
禁用遞歸獲取子模塊(這與使用`--recurse-submodules=no`選項具有相同的效果)。
```
--submodule-prefix=<path>
```
前置<路徑>在信息性消息中打印的路徑,例如“獲取子模塊foo”。在子模塊上遞歸時,此選項在內部使用。
```
--recurse-submodules-default=[yes|on-demand]
```
此選項在內部用于臨時為--recurse-submodules選項提供非負默認值。所有其他配置fetch子模塊遞歸的方法(例如 [gitmodules [5]](https://git-scm.com/docs/gitmodules) 和 [git-config [1]](https://git-scm.com/docs/git-config) 中的設置)都會覆蓋此選項,指定 - [no-] recurse-submodules直接。
```
-u
```
```
--update-head-ok
```
默認情況下 _git fetch_ 拒絕更新與當前分支對應的頭部。此標志禁用檢查。這純粹是為 _git pull_ 內部使用與 _git fetch_ 進行通信,除非你實現自己的瓷器,否則你不應該使用它。
```
--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>`時,它們都按照命令行中列出的順序發送到另一側。
```
-4
```
```
--ipv4
```
僅使用IPv4地址,忽略IPv6地址。
```
-6
```
```
--ipv6
```
僅使用IPv6地址,忽略IPv4地址。
```
<repository>
```
“遠程”存儲庫,它是獲取或拉取操作的源。該參數可以是URL(參見下面的 [GIT URL](#URLS) 部分)或遙控器的名稱(參見下面的 [REMOTES](#REMOTES) 部分)。
```
<group>
```
一個名稱,指的是存儲庫列表作為遙控器的值。< group>在配置文件中。 (參見 [git-config [1]](https://git-scm.com/docs/git-config) )。
```
<refspec>
```
指定要獲取的引用和要更新的本地引用。如果命令行中沒有< refspec> s,則從`remote.<repository>.fetch`變量中讀取要獲取的引用(參見下面的[配置的遠程跟蹤分支](#CRTB))。
< refspec>的格式參數是可選加`+`,后跟源< src>,后跟冒號`:`,后跟目標ref< dst>。當< dst>時,可以省略冒號。是空的。 < SRC>通常是ref,但它也可以是完全拼寫的十六進制對象名稱。
`tag <tag>`表示與`refs/tags/<tag>:refs/tags/<tag>`相同;它請求獲取給定標記的所有內容。
匹配< src>的遠程引用取出,如果< dst>不是空字符串,嘗試更新與其匹配的本地引用。
在沒有`--force`的情況下是否允許更新取決于它被提取到的ref命名空間,被提取的對象的類型,以及更新是否被認為是快進。通常,相同的規則適用于推送時的提取,請參閱 [git-push [1]](https://git-scm.com/docs/git-push) 的`<refspec>...`部分。 _git fetch_ 特有的那些規則的例外情況如下所述。
直到Git版本2.20,并且與使用 [git-push [1]](https://git-scm.com/docs/git-push) 推送時不同,對`refs/tags/*`的任何更新都將在refspec(或`--force`)中沒有`+`的情況下被接受。在獲取時,我們會混淆地將遠程的所有標記更新視為強制提取。從Git版本2.20開始,獲取更新`refs/tags/*`的方式與推送時相同。即如果沒有refspec(或`--force`)中的`+`,任何更新都將被拒絕。
與使用 [git-push [1]](https://git-scm.com/docs/git-push) 進行推送時不同,[refdpec(或`--force`)中的`+`將接受`refs/{tags,heads}/*`以外的任何更新,無論是否交換,例如一個blob的樹對象,或另一個提交的提交,它沒有先前的提交作為祖先等。
與使用 [git-push [1]](https://git-scm.com/docs/git-push) 進行推送不同,沒有任何配置可以修改這些規則,也沒有類似于`pre-receive`掛鉤的`pre-fetch`掛鉤。
與使用 [git-push [1]](https://git-scm.com/docs/git-push) 推送一樣,可以通過向refspec添加可選的前導`+`(或使用`--force`來覆蓋上面描述的關于不允許作為更新的所有規則。 ]命令行選項)。唯一的例外是沒有任何強制將使`refs/heads/*`命名空間接受非提交對象。
| 注意 | 當你想要獲取的遠程分支被認為是經常倒帶和重新定位時,預計它的新提示將不會是其上一個提示的后代(如上次提取時存儲在遠程跟蹤分支中)。您可能希望使用`+`符號來指示此類分支將需要非快進更新。無法確定或聲明具有此行為的存儲庫中的分支可用;拉動用戶只需知道這是分支的預期使用模式。 |
## GIT網址
通常,URL包含有關傳輸協議,遠程服務器的地址以及存儲庫路徑的信息。根據傳輸協議,可能缺少某些信息。
Git支持ssh,git,http和https協議(此外,ftp和ftps可用于獲取,但這是低效的并且已棄用;請勿使用它)。
本機傳輸(即git:// URL)不進行身份驗證,應在不安全的網絡上謹慎使用。
可以使用以下語法:
* SSH:// [用戶@] host.xz [:端口] /path/to/repo.git/
* GIT中://host.xz [:端口] /path/to/repo.git/
* HTTP [S]://host.xz [:端口] /path/to/repo.git/
* FTP [S]://host.xz [:端口] /path/to/repo.git/
另一種類似scp的語法也可以與ssh協議一起使用:
* [用戶@] host.xz:路徑/到/ repo.git /
只有在第一個冒號之前沒有斜杠時才會識別此語法。這有助于區分包含冒號的本地路徑。例如,本地路徑`foo:bar`可以指定為絕對路徑或`./foo:bar`,以避免被誤解為ssh url。
ssh和git協議還支持?用戶名擴展:
* SSH:// [用戶@] host.xz [:端口] /?[用戶] /path/to/repo.git/
* GIT中://host.xz [:端口] /?[用戶] /path/to/repo.git/
* [用戶@] host.xz:/?[用戶] /path/to/repo.git/
對于本地也受Git支持的本地存儲庫,可以使用以下語法:
* /path/to/repo.git/
* 文件:///path/to/repo.git/
這兩種語法大多是等價的,除了克隆時,前者暗示--local選項。有關詳細信息,請參閱 [git-clone [1]](https://git-scm.com/docs/git-clone) 。
當Git不知道如何處理某種傳輸協議時,它會嘗試使用 _remote-< transport>_ 遠程助手,如果存在的話。要顯式請求遠程幫助程序,可以使用以下語法:
* <運輸> ::<地址>
其中<地址>可以是路徑,服務器和路徑,或者由被調用的特定遠程助手識別的任意類似URL的字符串。有關詳細信息,請參閱 [gitremote-helpers [1]](https://git-scm.com/docs/gitremote-helpers) 。
如果存在大量具有相似名稱的遠程存儲庫,并且您希望為它們使用不同的格式(以便將您使用的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”這樣的URL或類似“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”這樣的網址將被重寫為“ssh://example.org/path/to/repo.git”以進行推送,但是pull仍會使用原始網址。
## 遙控
可以使用以下某個名稱而不是URL作為`<repository>`參數:
* Git配置文件中的一個遙控器:`$GIT_DIR/config`,
* `$GIT_DIR/remotes`目錄中的文件,或
* `$GIT_DIR/branches`目錄中的文件。
所有這些也允許你從命令行省略refspec,因為它們每個都包含一個git將默認使用的refspec。
### 在配置文件中命名為remote
您可以選擇使用 [git-remote [1]](https://git-scm.com/docs/git-remote) , [git-config [1]](https://git-scm.com/docs/git-config) 提供之前配置的遙控器的名稱,甚至可以手動編輯`$GIT_DIR/config`文件。此遠程的URL將用于訪問存儲庫。如果未在命令行上提供refspec,則默認情況下將使用此遠程的refspec。配置文件中的條目如下所示:
```
[remote "<name>"]
url = <url>
pushurl = <pushurl>
push = <refspec>
fetch = <refspec>
```
`<pushurl>`僅用于推送。它是可選的,默認為`<url>`。
### `$GIT_DIR/remotes`中的命名文件
您可以選擇在`$GIT_DIR/remotes`中提供文件名。此文件中的URL將用于訪問存儲庫。如果未在命令行上提供refspec,則此文件中的refspec將用作默認值。該文件應具有以下格式:
```
URL: one of the above URL format
Push: <refspec>
Pull: <refspec>
```
_git push_ 使用`Push:`行, _git pull_ 和 _git fetch_ 使用`Pull:`系。可以為其他分支映射指定多個`Push:`和`Pull:`行。
### `$GIT_DIR/branches`中的命名文件
您可以選擇在`$GIT_DIR/branches`中提供文件名。此文件中的URL將用于訪問存儲庫。該文件應具有以下格式:
```
<url>#<head>
```
`<url>`是必需的; `#<head>`是可選的。
根據操作,如果您沒有在命令行上提供一個refitpec,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 origin`或`git fetch`,`remote.<repository>.fetch`值用作refspecs-它們指定要獲取的refs和要更新的本地refs。上面的示例將獲取`origin`中存在的所有分支(即,與值的左側匹配的任何ref,`refs/heads/*`)并更新`refs/remotes/origin/*`層次結構中的相應遠程跟蹤分支。
* 當使用顯式分支和/或標記運行`git fetch`以在命令行上獲取時,例如, `git fetch origin master`,在命令行上給出的< refspec>確定要取出的內容(例如示例中的`master`,這是`master:`的簡寫,這反過來意味著“獲取 _] master_ 分支但是我沒有明確說出要從命令行“更新它的遠程跟蹤分支”,并且示例命令將只獲取_主_分支。 `remote.<repository>.fetch`值確定更新哪個遠程跟蹤分支(如果有)。當以這種方式使用時,`remote.<repository>.fetch`值對決定_獲取_的內容沒有任何影響(即,當命令行列出refspecs時,這些值不用作refspecs);它們僅用于決定_其中_通過充當映射來存儲所獲取的引用。
后一次使用`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]](https://git-scm.com/docs/git-config) 。
事情變得棘手和具體。修剪功能實際上并不關心分支,而是將修剪本地<→遠程引用作為遠程refspec的函數(參見上面的`<refspec>`和[配置遠程跟蹤分支](#CRTB)] )。
因此,如果遙控器的refspec包括例如`refs/tags/*:refs/tags/*`,或您手動運行,例如`git fetch --prune <name> "refs/tags/*:refs/tags/*"`它不會是被刪除的過時遠程跟蹤分支,而是遠程上不存在的任何本地標記。
這可能不是您所期望的,即您想要修剪遠程`<name>`,但也要從中明確地獲取標記,因此當您從中獲取時,您將刪除所有本地標記,其中大多數可能不是來自`<name>` ]遙遠的第一名。
因此在使用像`refs/tags/*:refs/tags/*`這樣的refspec或任何其他可能將多個遙控器的引用映射到同一本地命名空間的refspec時要小心。
由于在遙控器上保持最新的分支和標簽是一個常見的用例,`--prune-tags`選項可以與`--prune`一起提供,以修剪遙控器上不存在的本地標簽,并強制 - 更新那些不同的標簽。也可以使用配置中的`fetch.pruneTags`或`remote.<name>.pruneTags`啟用標簽修剪。見 [git-config [1]](https://git-scm.com/docs/git-config) 。
`--prune-tags`選項相當于在遙控器的refspecs中聲明了`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而不是命名遠程時也有效。這些將在原點上找不到所有修剪標簽:
```
$ 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/*'
```
## OUTPUT
“git fetch”的輸出取決于所使用的傳輸方法;本節介紹通過Git協議(本地或通過ssh)和Smart HTTP協議獲取時的輸出。
獲取的狀態以表格形式輸出,每行代表單個ref的狀態。每一行的形式如下:
```
<flag> <summary> <from> -> <to> [<reason>]
```
僅當使用--verbose選項時,才會顯示最新引用的狀態。
在使用配置變量fetch.output指定的緊湊輸出模式中,如果在另一個字符串中找到整個`<from>`或`<to>`,則在另一個字符串中將其替換為`*`。例如,`master -> origin/master`變為`master -> origin/*`。
```
flag
```
一個表示ref狀態的字符:
```
(space)
```
成功獲得快進;
```
+
```
成功的強制更新;
```
-
```
成功修剪參考;
```
t
```
成功更新標簽;
```
*
```
成功獲取新參考;
```
!
```
對于被拒絕或未能更新的引用;和
```
=
```
對于一個最新的ref,不需要提取。
```
summary
```
對于成功獲取的ref,摘要以適合用作`git log`的參數的形式顯示ref的舊值和新值(在大多數情況下這是`<old>..<new>`,而強制非快速的`<old>...<new>` - 轉發更新)。
```
from
```
從中獲取遠程引用的名稱,減去其`refs/<type>/`前綴。在刪除的情況下,遠程ref的名稱是“(none)”。
```
to
```
要更新的本地引用的名稱減去其`refs/<type>/`前綴。
```
reason
```
一個人類可讀的解釋。在成功獲取refs的情況下,不需要解釋。對于失敗的ref,描述了失敗的原因。
## 例子
* 更新遠程跟蹤分支:
```
$ git fetch origin
```
上述命令從遠程refs / heads / namespace復制所有分支,并將它們存儲到本地refs / remotes / origin / namespace,除非分支。< name> .fetch選項用于指定非默認refspec。
* 明確使用refspecs:
```
$ git fetch origin +pu:pu maint:tmp
```
這通過從遠程存儲庫中的分支(分別)`pu`和`maint`獲取來更新(或根據需要創建)本地存儲庫中的分支`pu`和`tmp`。
`pu`分支即使不快進也會更新,因為它帶有加號前綴; `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]](https://git-scm.com/docs/git-log) 的分支。最終將通過git的內置內務處理刪除獲取的對象(參見 [git-gc [1]](https://git-scm.com/docs/git-gc) )。
## 安全
提取和推送協議的目的不是為了防止一方竊取不打算共享的其他存儲庫中的數據。如果您需要保護私有數據免受惡意對等方的攻擊,那么最佳選擇是將其存儲在另一個存儲庫中。這適用于客戶端和服務器。特別是,服務器上的命名空間對讀訪問控制無效;您應該只將命名空間的讀訪問權授予您信任的客戶端,并具有對整個存儲庫的讀訪問權限。
已知的攻擊向量如下:
1. 受害者發送“有”行,宣傳其擁有的對象的ID,這些對象并未明確地用于共享,但如果對等方也擁有它們,則可用于優化轉移。攻擊者選擇一個對象ID X來竊取并向X發送一個ref,但不需要發送X的內容,因為受害者已經擁有它。現在,受害者認為攻擊者擁有X,并且稍后會將X的內容發送回攻擊者。 (這種攻擊對于客戶端在服務器上執行是最直接的,通過在客戶端有權訪問的命名空間中創建ref,然后獲取它。服務器在客戶端上執行它的最可能方式是“將“X”合并到一個公共分支中,并希望用戶在此分支上執行其他工作,并將其推送回服務器,而不會注意到合并。)
2. 與#1一樣,攻擊者選擇一個對象ID X來竊取。受害者發送攻擊者已經擁有的對象Y,并且攻擊者錯誤地聲稱擁有X而不是Y,因此受害者將Y作為針對X的增量發送。該增量顯示X的區域與攻擊者的Y類似。
## BUGS
使用--recurse-submodules只能在已檢出的子模塊中獲取新的提交。例如,上游在超級項目的剛剛提取的提交中添加了一個新的子模塊,子模塊本身無法獲取,因此無法在以后檢查該子模塊而無需再次進行提取。預計將在未來的Git版本中修復。
## 也可以看看
[git-pull [1]](https://git-scm.com/docs/git-pull)
## GIT
部分 [git [1]](https://git-scm.com/docs/git) 套件
- git
- git-config
- git-help
- git-init
- git-clone
- git-add
- git-status
- git-diff
- git-commit
- git-reset
- git-rm
- git-mv
- git-branch
- git-checkout
- git-merge
- git-mergetool
- git-log
- git-stash
- git-tag
- git-worktree
- git-fetch
- git-pull
- git-push
- git-remote
- git-submodule
- git-show
- git-log
- git-shortlog
- git-describe
- git-apply
- git-cherry-pick
- git-rebase
- git-revert
- git-bisect
- git-blame
- git-grep
- gitattributes
- giteveryday
- gitglossary
- githooks
- gitignore
- gitmodules
- gitrevisions
- gittutorial
- gitworkflows
- git-am
- git-format-patch
- git-send-email
- git-request-pull
- git-svn
- git-fast-import
- git-clean
- git-gc
- git-fsck
- git-reflog
- git-filter-branch
- git-instaweb
- git-archive
- git-bundle
- git-daemon
- git-update-server-info
- git-cat-file
- git-check-ignore
- git-checkout-index
- git-commit-tree
- git-count-objects
- git-diff-index
- git-for-each-ref
- git-hash-object
- git-ls-files
- git-merge-base
- git-read-tree
- git-rev-list
- git-rev-parse
- git-show-ref
- git-symbolic-ref
- git-update-index
- git-update-ref
- git-verify-pack
- git-write-tree