設定與配置
取得與建立專案
基本快照
分支與合併
分享與更新專案
檢查與比較
修補
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
- 2.46.1 → 2.47.0 沒有變更
-
2.46.0
07/29/24
- 2.34.1 → 2.45.2 沒有變更
-
2.34.0
11/15/21
- 2.29.1 → 2.33.8 沒有變更
-
2.29.0
10/19/20
- 2.27.1 → 2.28.1 沒有變更
-
2.27.0
06/01/20
配置
-
user.name
中應該填寫什麼? -
您應該填寫您的個人姓名,通常是使用名字和姓氏的形式。例如,Git 的現任維護者使用「Junio C Hamano」。這將會是您所做的每個 commit 中儲存的姓名部分。
此配置不會影響對遠端服務進行身份驗證;為此,請參閱 git-config[1] 中的
credential.username
。
-
http.postBuffer
實際上做什麼? -
此選項會變更 Git 在透過 HTTP 或 HTTPS 將資料推送至遠端時使用的緩衝區大小。如果資料大於此大小,libcurl(負責 Git 的 HTTP 支援)將會使用分塊傳輸編碼,因為事先不知道推送資料的大小。
除非您知道遠端伺服器或中間的代理伺服器不支援 HTTP/1.1(引入了分塊傳輸編碼),或已知分塊資料有問題,否則將此值保留為預設大小即可。這通常(錯誤地)被建議作為通用推送問題的解決方案,但由於幾乎每個伺服器和代理伺服器都至少支援 HTTP/1.1,因此提高此值通常無法解決大多數推送問題。今天,在網際網路上,不正確支援 HTTP/1.1 和分塊傳輸編碼的伺服器或代理伺服器將沒有那麼有用,因為它會中斷大量流量。
請注意,增加此值會增加 Git 透過 HTTP 或 HTTPS 進行的每次相關推送所使用的記憶體,因為無論是否全部使用,都會配置整個緩衝區。因此,最好將其保留為預設值,除非您確定需要不同的值。
- 我該如何設定不同的編輯器?
-
如果您沒有特別為 Git 指定編輯器,它預設會使用您使用
VISUAL
或EDITOR
環境變數設定的編輯器,如果兩者都沒有指定,則使用系統預設值(通常是vi
)。由於有些人覺得vi
很難使用或偏好不同的編輯器,因此可能需要變更所使用的編輯器。如果您想為大多數需要編輯器的程式設定通用編輯器,您可以編輯 shell 配置(例如,
~/.bashrc
或~/.zshenv
),使其包含一行將EDITOR
或VISUAL
環境變數設定為適當的值。例如,如果您偏好編輯器nano
,則可以寫入以下內容export VISUAL=nano
如果您想特別為 Git 設定編輯器,您可以設定
core.editor
配置值或GIT_EDITOR
環境變數。您可以參閱 git-var[1] 以取得有關諮詢這些選項的順序的詳細資訊。請注意,在所有情況下,編輯器值都會傳遞給 shell,因此任何包含空格的引數都應適當引號。此外,如果您的編輯器通常在調用時會與終端分離,您應該使用一個不會這樣做的引數來指定它,否則 Git 將看不到任何變更。在 Windows 上解決這兩個問題的配置範例是配置
"C:\Program Files\Vim\gvim.exe" --nofork
,它會將包含空格的檔名加上引號,並指定--nofork
選項以避免將程式置於背景。
憑證
- 我該如何在使用 HTTP 推送時指定我的憑證?
-
最簡單的方法是透過
credential.helper
配置使用憑證輔助工具。大多數系統都提供一個標準選項,以便與系統憑證管理員整合。例如,Git for Windows 提供wincred
憑證管理員,macOS 具有osxkeychain
憑證管理員,而具有標準桌面環境的 Unix 系統可以使用libsecret
憑證管理員。所有這些都將憑證儲存在加密的儲存區中,以確保您的密碼或權杖安全。此外,您可以使用
store
憑證管理員(儲存在您主目錄中的檔案中)或cache
憑證管理員(不會永久儲存您的憑證,但會防止您在特定時間內被提示輸入憑證)。您也可以在出現提示時直接輸入密碼。雖然可以將密碼(必須經過百分比編碼)放在 URL 中,但這並不是很安全,並且可能導致憑證意外洩露,因此不建議使用。
- 我該如何使用 HTTP 與同一個託管供應商的多個帳戶?
-
通常,區分這些帳戶的最簡單方法是在 URL 中使用使用者名稱。例如,如果您在
git.example.org
上擁有帳戶author
和committer
,則可以使用 URL https://author@git.example.org/org1/project1.git 和 https://committer@git.example.org/org2/project2.git。這樣,當您使用憑證輔助工具時,它會自動嘗試尋找您帳戶的正確憑證。如果您已經設定了遠端,您可以使用類似git remote set-url origin https://author@git.example.org/org1/project1.git
的指令來變更 URL(有關詳細資訊,請參閱 git-remote[1])。
- 我該如何使用 SSH 與同一個託管供應商的多個帳戶?
-
對於大多數支援 SSH 的託管供應商,單一金鑰對可唯一識別使用者。因此,若要使用多個帳戶,必須為每個帳戶建立金鑰對。如果您使用的是相當新的 OpenSSH 版本,您可以使用類似
ssh-keygen -t ed25519 -f ~/.ssh/id_committer
的指令建立新的金鑰對。然後,您可以向託管供應商註冊公鑰(在本例中,為~/.ssh/id_committer.pub
;請注意.pub
)。大多數託管供應商使用單一 SSH 帳戶進行推送;也就是說,所有使用者都會推送至
git
帳戶(例如,git@git.example.org
)。如果您的供應商是這種情況,您可以設定 SSH 中的多個別名,以便清楚地知道要使用哪個金鑰對。例如,您可以在~/.ssh/config
中寫入類似以下的內容,並替換正確的私鑰檔# This is the account for author on git.example.org. Host example_author HostName git.example.org User git # This is the key pair registered for author with git.example.org. IdentityFile ~/.ssh/id_author IdentitiesOnly yes # This is the account for committer on git.example.org. Host example_committer HostName git.example.org User git # This is the key pair registered for committer with git.example.org. IdentityFile ~/.ssh/id_committer IdentitiesOnly yes
然後,您可以調整推送 URL 以使用
git@example_author
或git@example_committer
,而不是git@example.org
(例如,git remote set-url git@example_author:org1/project1.git
)。
傳輸
- 我該如何在多個系統之間同步工作樹?
-
首先,決定您是否要執行此操作。當您使用典型的
git push
和git fetch
命令推送或提取您的工作時,Git 的效果最佳,並且不是設計為跨系統共享工作樹。這具有潛在風險,並且在某些情況下可能會導致儲存庫損壞或資料遺失。通常,這樣做會導致
git status
需要重新讀取工作樹中的每個檔案。此外,Git 的安全模型不允許跨不受信任的使用者共享工作樹,因此,只有當工作樹將僅由所有機器上的單一使用者使用時,同步工作樹才是安全的。請勿使用雲端同步服務來同步 Git 儲存庫的任何部分,因為這可能會導致損壞,例如遺失物件、變更或新增的檔案、損壞的 refs 以及各種其他問題。這些服務傾向於持續地逐個檔案同步,而且不了解 Git 儲存庫的結構。如果它們在儲存庫更新的中途進行同步,情況會特別糟糕,因為這很可能會導致不完整或部分更新,進而造成資料遺失。
可能會發生的損壞類型的一個例子是 refs 狀態的衝突,導致兩邊在同一個分支上擁有對方沒有的不同提交。這可能會導致重要的物件變成未被參照,並可能被
git gc
修剪,造成資料遺失。因此,最好使用正常的 push 和 pull 機制,將你的工作推送到另一個系統或中央伺服器。然而,這並非總是能保留重要的資料,例如暫存 (stashes),所以有些人偏好在多個系統間共享工作目錄。
如果你這樣做,建議的方法是在儲存庫的根目錄上使用
rsync -a --delete-after
(最好使用加密連線,例如ssh
)。執行此操作時,你應該確保幾件事:-
如果你有額外的工作樹 (worktrees) 或獨立的 Git 目錄,它們必須與主要工作樹和儲存庫同時同步。
-
你能夠接受目標目錄成為來源目錄的精確副本,刪除任何已存在的資料。
-
儲存庫 (包括所有工作樹和 Git 目錄) 在傳輸期間處於靜止狀態 (也就是說,沒有進行任何類型的操作,包括背景操作,例如
git gc
和編輯器調用的操作)。請注意,即使有這些建議,以這種方式同步仍存在一些風險,因為它繞過了 Git 對儲存庫的正常完整性檢查,因此建議進行備份。你可能還希望在同步後執行
git fsck
來驗證目標系統上資料的完整性。
-
常見問題
- 我該如何忽略對已追蹤檔案的變更?
-
Git 沒有提供這樣做的方法。原因是如果 Git 需要覆寫這個檔案,例如在 checkout 期間,它不知道對該檔案的變更是否是重要的、應該被保留的,還是不相關且可以安全銷毀的。因此,它必須採取安全的路線,並且始終保留它們。
嘗試使用
git update-index
的某些功能 (即 assume-unchanged 和 skip-worktree 位元) 很有誘惑力,但這些功能不能正確地達到此目的,不應這樣使用。如果你的目標是修改組態檔案,通常會有一個已簽入儲存庫的檔案,作為範本或預設值,然後可以將其複製並適當地修改。這個第二個修改過的檔案通常會被忽略,以防止意外提交它。
- 我要求 Git 忽略各種檔案,但它們仍然被追蹤
-
gitignore
檔案確保某些未被 Git 追蹤的檔案保持未追蹤狀態。然而,有時特定的檔案可能在將它們加入.gitignore
之前就被追蹤了,因此它們仍然保持被追蹤狀態。要取消追蹤並忽略檔案/模式,請使用git rm --cached <檔案/模式>
,並在.gitignore
中加入符合 <檔案> 的模式。請參閱 gitignore[5] 以取得詳細資訊。
- 我該如何知道我想要執行 fetch 還是 pull?
-
fetch 會儲存來自遠端儲存庫的最新變更的副本,而不會修改工作樹或目前分支。然後,你可以隨意檢查、合併、基於上游變更重新定基 (rebase),或忽略它們。pull 包含 fetch,然後立即進行合併或重新定基。請參閱 git-pull[1]。
- 我可以在 Git 中使用 Proxy 嗎?
-
可以,Git 支援使用 Proxy。Git 遵循 Unix 上常用的標準
http_proxy
、https_proxy
和no_proxy
環境變數,也可以使用http.proxy
和類似的 HTTPS 選項進行設定 (請參閱 git-config[1])。http.proxy
和相關選項可以根據每個 URL 模式進行自訂。此外,理論上 Git 可以在網路上存在的透明 Proxy 環境下正常運作。對於 SSH,Git 可以使用 OpenSSH 的
ProxyCommand
來支援 Proxy。常用的工具包括netcat
和socat
。然而,它們必須設定為在標準輸入上看到 EOF 時不退出,這通常意味著netcat
需要-q
,而socat
需要帶有類似-t 10
的逾時。這是必要的,因為 Git SSH 伺服器知道不再會有請求的方式是在標準輸入上出現 EOF,但是當這種情況發生時,伺服器可能尚未處理完最後的請求,因此在該點斷開連線會中斷該請求。一個在
~/.ssh/config
中具有 HTTP Proxy 的範例組態項目可能如下所示:Host git.example.org User git ProxyCommand socat -t 10 - PROXY:proxy.example.org:%h:%p,proxyport=8080
請注意,在所有情況下,為了使 Git 正常運作,Proxy 必須完全透明。Proxy 不能以任何方式修改、竄改或緩衝連線,否則 Git 幾乎肯定會無法運作。請注意,許多 Proxy,包括許多 TLS 中間盒、Windows 防毒和防火牆程式 (Windows Defender 和 Windows 防火牆除外) 以及過濾 Proxy 都無法符合此標準,因此最終會破壞 Git。由於有許多問題報告及其不良的安全性歷史,我們建議不要使用這些類型的軟體和裝置。
合併與重新定基
- 當使用 Squash 合併來合併長期分支時,可能會發生哪些問題?
-
一般來說,當使用 Squash 合併來多次合併兩個分支時,可能會發生各種問題。這些問題可能包括在
git log
輸出、GUI 中,或在使用...
表示法來表示範圍時看到額外的提交,以及可能需要一再重新解決衝突的情況。當 Git 在兩個分支之間進行正常合併時,它會考慮三個點:兩個分支和第三個提交,稱為合併基底,通常是提交的共同祖先。合併的結果是合併基底與每個 head 之間的變更總和。當你使用一般合併提交來合併兩個分支時,這會產生一個新的提交,該提交將會在它們再次合併時最終成為合併基底,因為現在有一個新的共同祖先。Git 不必考慮在合併基底之前發生的變更,因此你不必重新解決你之前解決的任何衝突。
當你執行 Squash 合併時,不會建立合併提交;相反地,一側的變更會作為一般提交應用於另一側。這表示這些分支的合併基底不會改變,因此當 Git 執行下一次合併時,它會考慮上次考慮的所有變更加上新的變更。這表示可能需要重新解決任何衝突。同樣地,在
git diff
、git log
或 GUI 中使用...
表示法的任何東西都會顯示自原始合併基底以來的全部變更。因此,如果你想要重複合併兩個長期分支,最好始終使用一般合併提交。
- 如果我在兩個分支上做了變更,但在其中一個分支上還原了它,為什麼這些分支的合併會包含該變更?
-
預設情況下,當 Git 進行合併時,它會使用一種稱為
ort
的策略,該策略會執行精巧的三向合併。在這種情況下,當 Git 執行合併時,它會考慮三個點:兩個 head 和第三個點,稱為合併基底,通常是這些提交的共同祖先。Git 完全不考慮歷史記錄或這些分支上發生的個別提交。因此,如果兩側都有變更,而其中一側還原了該變更,則結果是包含該變更。這是因為程式碼在一側被變更,而另一側沒有淨變更,在這種情況下,Git 會採用該變更。
如果這對你來說是個問題,你可以改為進行重新定基,將具有還原的分支重新定基到另一個分支上。在這種情況下,重新定基會還原變更,因為重新定基會應用每個個別提交,包括還原。請注意,重新定基會重寫歷史記錄,因此除非你確定自己可以接受,否則應避免重新定基已發佈的分支。請參閱 git-rebase[1] 中的 NOTES 區段以取得更多詳細資訊。
鉤子 (Hooks)
- 我該如何使用鉤子來防止使用者進行某些變更?
-
唯一能安全進行這些變更的地方是在遠端儲存庫(即 Git 伺服器)上,通常是在
pre-receive
鉤子或持續整合 (CI) 系統中。這些是能有效執行策略的位置。通常會嘗試使用
pre-commit
鉤子(或針對提交訊息使用commit-msg
鉤子)來檢查這些事情,如果您是單獨開發並希望工具能幫助您,這很棒。然而,在開發人員機器上使用鉤子作為政策控制並非有效,因為使用者可以使用--no-verify
略過這些鉤子而不被注意到(還有其他各種方法)。Git 假設使用者可以控制他們的本機儲存庫,並且不會試圖阻止這種情況或告發使用者。此外,一些進階使用者發現
pre-commit
鉤子會阻礙使用臨時提交來暫存進行中工作或建立修復提交的工作流程,因此最好還是將這些檢查推送到伺服器端。
跨平台問題
- 我在 Windows 上,我的文字檔案被偵測為二進位檔案。
-
當您將文字檔案儲存為 UTF-8 時,Git 的運作效果最佳。Windows 上的許多程式都支援 UTF-8,但有些不支援,只使用小端 UTF-16 格式,Git 會將其偵測為二進位。如果您無法在程式中使用 UTF-8,您可以指定工作樹編碼,以指示應使用哪種編碼簽出您的檔案,同時仍然將這些檔案以 UTF-8 格式儲存在儲存庫中。這可讓像 git-diff[1] 之類的工具按預期工作,同時仍允許您的工具正常運作。
要執行此操作,您可以使用帶有
working-tree-encoding
屬性的 gitattributes[5] 模式。例如,以下模式會將所有 C 檔案設定為使用 UTF-16LE-BOM,這是 Windows 上常用的編碼*.c working-tree-encoding=UTF-16LE-BOM
您需要執行
git add --renormalize
才能讓此設定生效。請注意,如果您是在跨平台使用的專案上進行這些變更,您可能需要將其設定在每個使用者的組態檔中,或是在$GIT_DIR/info/attributes
中的檔案中,因為在儲存庫的.gitattributes
檔案中進行設定將會套用到該儲存庫的所有使用者。請參閱以下條目,以取得有關正規化換行符號的資訊,並參閱 gitattributes[5] 以取得有關屬性檔案的更多資訊。
- 我在 Windows 上,git diff 顯示我的檔案結尾有
^M
。 -
預設情況下,Git 期望檔案以 Unix 換行符號儲存。因此,Windows 換行符號的一部分歸位字元 (
^M
) 會顯示出來,因為它被視為尾隨空白。Git 預設只會顯示新行的尾隨空白,而不是現有的空白。您可以將檔案以 Unix 換行符號儲存在儲存庫中,並將其自動轉換為您平台的換行符號。要執行此操作,請將組態選項
core.eol
設定為native
,並參閱 關於建議儲存設定的問題,以取得有關如何將檔案設定為文字或二進位的資訊。如果您不希望從換行符號中移除歸位字元,您也可以使用
core.whitespace
設定來控制此行為。
- 為什麼我有一個檔案總是處於已修改狀態?
-
在內部,Git 始終將檔案名稱儲存為位元組序列,並且不執行任何編碼或大小寫折疊。但是,Windows 和 macOS 預設都會對檔案名稱執行大小寫折疊。因此,可能會出現多個檔案或目錄的名稱僅在大小寫上有所不同。Git 可以很好地處理這種情況,但檔案系統只能儲存其中一個檔案,因此當 Git 讀取另一個檔案以查看其內容時,會發現它已修改。
最好刪除其中一個檔案,這樣您就只有一個檔案。您可以使用以下命令來執行此操作(假設有兩個檔案
AFile.txt
和afile.txt
),在其他方面乾淨的工作樹上執行$ git rm --cached AFile.txt $ git commit -m 'Remove files conflicting in case' $ git checkout .
這樣可以避免觸摸磁碟,但會移除其他檔案。您的專案可能會傾向採用命名慣例,例如全部使用小寫名稱,以避免再次發生此問題;可以使用
pre-receive
鉤子或作為持續整合 (CI) 系統的一部分來檢查此類慣例。如果您的系統上使用塗抹或清除篩選器,但先前提交檔案時沒有執行塗抹或清除篩選器,則也可能在任何平台上發生永久修改的檔案。要解決此問題,請在其他方面乾淨的工作樹上執行以下操作
$ git add --renormalize .
- 在 Git 中儲存檔案的建議方法是什麼?
-
雖然 Git 可以儲存和處理任何類型的任何檔案,但有些設定的效果比其他設定更好。一般來說,我們建議將文字檔案儲存為不帶位元組順序標記 (BOM) 的 UTF-8,並使用 LF (Unix 樣式) 結尾。我們還建議在提交訊息中使用 UTF-8(同樣不帶 BOM)。這些設定在跨平台以及與
git diff
和git merge
等工具配合使用時效果最佳。此外,如果您可以在基於文字或非基於文字的儲存格式之間進行選擇,我們建議以文字格式儲存檔案,並在必要時將其轉換為其他格式。例如,每行一個記錄的基於文字的 SQL 轉儲比實際的資料庫檔案更適合進行差異比較和合併。同樣,像 Markdown 和 AsciiDoc 這樣的基於文字的格式比像 Microsoft Word 和 PDF 這樣的二進位格式更有效。
同樣,通常不建議在儲存庫中儲存二進位相依性(例如,共用程式庫或 JAR 檔案)或建置產品。相依性和建置產品最好儲存在工件或套件伺服器上,而儲存庫中僅儲存參考、URL 和雜湊值。
我們還建議設定 gitattributes[5] 檔案來明確標記哪些檔案是文字檔案,哪些是二進位檔案。如果您希望 Git 猜測,您可以設定屬性
text=auto
。對於文字檔案,Git 通常會確保在儲存庫中使用 LF 結尾。
core.autocrlf
和core.eol
組態變數會指定在簽出任何文字檔案時應遵循哪種換行符號慣例。您也可以使用eol
屬性(例如,eol=crlf
)來覆寫哪些檔案使用哪些換行符號處理。例如,一般來說,shell 檔案必須具有 LF 結尾,而批次檔案必須具有 CRLF 結尾,因此在某些專案中,以下設定可能適用
# By default, guess. * text=auto # Mark all C files as text. *.c text # Ensure all shell files have LF endings and all batch files have CRLF # endings in the working tree and both have LF in the repo. *.sh text eol=lf *.bat text eol=crlf # Mark all JPEG files as binary. *.jpg binary
這些設定可協助工具選取正確的輸出格式,例如修補程式,並使檔案以適合該平台的換行符號簽出。
GIT
git[1] 套件的一部分