設定和配置
獲取和建立專案
基本快照
分支與合併
共享和更新專案
檢查和比較
打補丁
除錯
電子郵件
外部系統
伺服器管理
指南
管理
底層命令
- 2.47.1 → 2.50.1 無更改
-
2.47.0
2024-10-06
- 2.44.1 → 2.46.4 無更改
-
2.44.0
2024-02-23
- 2.35.1 → 2.43.7 無更改
-
2.35.0
2022-01-24
- 2.34.1 → 2.34.8 無更改
- 2.34.0 無更改
- 2.32.1 → 2.33.8 無更改
-
2.32.0
2021-06-06
- 2.30.1 → 2.31.8 無更改
-
2.30.0
2020-12-27
- 2.25.1 → 2.29.3 無更改
-
2.25.0
2020-01-13
- 2.24.1 → 2.24.4 無更改
-
2.24.0
2019-11-04
- 2.22.1 → 2.23.4 無更改
-
2.22.0
2019-06-07
- 2.19.1 → 2.21.4 無更改
-
2.19.0
2018-09-10
- 2.18.1 → 2.18.5 無更改
-
2.18.0
2018-06-21
- 2.16.6 → 2.17.6 無更改
-
2.15.4
2019-12-06
-
2.14.6
2019-12-06
- 2.12.5 → 2.13.7 無更改
-
2.11.4
2017-09-22
-
2.10.5
2017-09-22
-
2.9.5
2017-07-30
-
2.8.6
2017-07-30
- 2.6.7 → 2.7.6 無更改
-
2.5.6
2017-05-05
-
2.4.12
2017-05-05
- 2.3.10 無更改
-
2.2.3
2015-09-04
-
2.1.4
2014-12-17
-
2.0.5
2014-12-17
描述
git svn 是 Subversion 和 Git 之間變更集的簡單通道。它提供了 Subversion 倉庫和 Git 倉庫之間的雙向變更流。
git svn 可以跟蹤標準 Subversion 倉庫,遵循常見的“trunk/branches/tags”佈局,並使用 --stdlayout 選項。它還可以使用 -T/-t/-b 選項跟蹤任何佈局中的分支和標籤(參見下面的 init 選項,以及 clone 命令)。
一旦跟蹤了 Subversion 倉庫(使用上述任何方法),Git 倉庫可以透過 fetch 命令從 Subversion 更新,而 Subversion 可以透過 dcommit 命令從 Git 更新。
命令
- init
-
初始化一個空的 Git 倉庫,其中包含 git svn 的額外元資料目錄。Subversion URL 可以指定為命令列引數,或作為 -T/-t/-b 的完整 URL 引數。可選地,要操作的目標目錄可以指定為第二個引數。通常此命令會初始化當前目錄。
- -T<trunk-subdir>
- --trunk=<trunk-subdir>
- -t<tags-subdir>
- --tags=<tags-subdir>
- -b<branches-subdir>
- --branches=<branches-subdir>
- -s
- --stdlayout
-
這些是 init 的可選命令列選項。每個標誌都可以指向相對倉庫路徑(--tags=project/tags)或完整 URL(--tags=https://foo.org/project/tags)。如果您的 Subversion 倉庫將標籤或分支放在多個路徑下,您可以指定多個 --tags 和/或 --branches 選項。--stdlayout 選項是設定 trunk、tags、branches 為相對路徑的簡寫方式,這是 Subversion 的預設設定。如果同時給定任何其他選項,它們將優先。
- --no-metadata
-
在 [svn-remote] 配置中設定 noMetadata 選項。不建議使用此選項,在使用此選項之前請閱讀此手冊頁的 svn.noMetadata 部分。
- --use-svm-props
-
在 [svn-remote] 配置中設定 useSvmProps 選項。
- --use-svnsync-props
-
在 [svn-remote] 配置中設定 useSvnsyncProps 選項。
- --rewrite-root=<URL>
-
在 [svn-remote] 配置中設定 rewriteRoot 選項。
- --rewrite-uuid=<UUID>
-
在 [svn-remote] 配置中設定 rewriteUUID 選項。
- --username=<user>
-
對於 SVN 處理身份驗證的傳輸方式(http、https 和 plain svn),請指定使用者名稱。對於其他傳輸方式(例如
svn+ssh://
),您必須在 URL 中包含使用者名稱,例如svn+ssh://foo@svn.bar.com/project
- --prefix=<prefix>
-
這允許您指定一個字首,如果在指定 trunk/branches/tags 時,該字首將預置到遠端名稱之前。字首不會自動包含尾隨斜槓,因此如果您需要,請務必在引數中包含一個。如果指定了 --branches/-b,字首必須包含尾隨斜槓。在任何情況下都強烈建議設定一個字首(帶尾隨斜槓),因為您的 SVN 跟蹤引用將位於 “refs/remotes/$prefix/**”,這與 Git 自己的遠端跟蹤引用佈局(refs/remotes/$remote/**)相容。如果您希望跟蹤共享同一倉庫的多個專案,設定字首也很有用。預設情況下,字首設定為 origin/。
注意在 Git v2.0 之前,預設字首是 ""(無字首)。這意味著 SVN 跟蹤引用被放置在 “refs/remotes/*” 下,這與 Git 自己的遠端跟蹤引用的組織方式不相容。如果您仍然想要舊的預設設定,可以透過在命令列上傳遞 --prefix
""
來實現(如果您的 Perl 的 Getopt::Long 小於 v2.37,則--prefix=""
可能不起作用)。 - --ignore-refs=<regex>
-
當傳遞給 init 或 clone 時,此正則表示式將作為配置鍵保留。有關
--ignore-refs
的描述,請參閱 fetch。 - --ignore-paths=<regex>
-
當傳遞給 init 或 clone 時,此正則表示式將作為配置鍵保留。有關
--ignore-paths
的描述,請參閱 fetch。 - --include-paths=<regex>
-
當傳遞給 init 或 clone 時,此正則表示式將作為配置鍵保留。有關
--include-paths
的描述,請參閱 fetch。 - --no-minimize-url
-
當跟蹤多個目錄(使用 --stdlayout、--branches 或 --tags 選項)時,git svn 將嘗試連線到 Subversion 倉庫的根目錄(或最高允許級別)。如果整個專案在倉庫內移動,此預設設定可以更好地跟蹤歷史記錄,但可能會在存在讀取訪問限制的倉庫上導致問題。傳遞
--no-minimize-url
將允許 git svn 按原樣接受 URL,而無需嘗試連線到更高級別的目錄。預設情況下,當只跟蹤一個 URL/分支時,此選項是關閉的(作用不大)。
- fetch
-
從我們正在跟蹤的 Subversion 遠端倉庫中抓取未抓取的修訂版本。$GIT_DIR/config 檔案中 [svn-remote "…"] 部分的名稱可以作為可選命令列引數指定。
如果需要,這會自動更新 rev_map(有關詳細資訊,請參閱下面 FILES 部分中的 $GIT_DIR/svn/**/.rev_map.*)。
- --localtime
-
以本地時區而不是 UTC 儲存 Git 提交時間。這使得 git log(即使沒有 --date=local)顯示與
svn
log
在本地時區中顯示的相同時間。這不會干擾與您克隆的 Subversion 倉庫的互操作性,但如果您希望您的本地 Git 倉庫能夠與他人的本地 Git 倉庫互操作,則要麼不使用此選項,要麼您都應該在相同的本地時區中使用它。
- --parent
-
僅從當前 HEAD 的 SVN 父級抓取。
- --ignore-refs=<regex>
-
忽略與 Perl 正則表示式匹配的分支或標籤引用。可以使用“負向前瞻斷言”(negative look-ahead assertion)如 ^refs/remotes/origin/(?!tags/wanted-tag|wanted-branch).*$ 來只允許特定的引用。
config key: svn-remote.<name>.ignore-refs
如果設定了 ignore-refs 配置鍵,並且還給定了命令列選項,則將使用兩個正則表示式。
- --ignore-paths=<regex>
-
這允許您指定一個 Perl 正則表示式,該表示式將導致跳過從 SVN 檢出所有匹配的路徑。
--ignore-paths
選項應該匹配給定倉庫上的每次 fetch(包括由於 clone、dcommit、rebase 等引起的自動抓取)。config key: svn-remote.<name>.ignore-paths
如果設定了 ignore-paths 配置鍵,並且還給定了命令列選項,則將使用兩個正則表示式。
示例
- --include-paths=<regex>
-
這允許您指定一個 Perl 正則表示式,該表示式將導致僅包含從 SVN 檢出的匹配路徑。
--include-paths
選項應該匹配給定倉庫上的每次 fetch(包括由於 clone、dcommit、rebase 等引起的自動抓取)。--ignore-paths
優先於--include-paths
。config key: svn-remote.<name>.include-paths
- --log-window-size=<n>
-
掃描 Subversion 歷史時,每次請求抓取 <n> 條日誌條目。預設值為 100。對於非常大的 Subversion 倉庫,可能需要更大的值才能在合理的時間內完成 clone/fetch。但是過大的值可能會導致更高的記憶體使用和請求超時。
- clone
-
執行 init 和 fetch。它將根據傳遞給它的 URL 的基本名稱自動建立一個目錄;或者如果傳遞第二個引數,它將建立一個目錄並在其中工作。它接受 init 和 fetch 命令接受的所有引數;除了
--fetch-all
和--parent
。克隆倉庫後,fetch 命令將能夠更新修訂版本而不會影響工作樹;rebase 命令將能夠用最新更改更新工作樹。 - rebase
-
這會從當前 HEAD 的 SVN 父級抓取修訂版本,並根據它變基當前(未提交到 SVN 的)工作。
這類似於
svn
update
或 git pull,不同之處在於它使用 git rebase 而不是 git merge 來保留線性歷史,以便於使用 git svn 進行 dcommit。這接受 git svn fetch 和 git rebase 接受的所有選項。但是,
--fetch-all
僅從當前的 [svn-remote] 抓取,而不是所有 [svn-remote] 定義。像 git rebase 一樣;這要求工作樹是乾淨的,並且沒有未提交的更改。
如果需要,這會自動更新 rev_map(有關詳細資訊,請參閱下面 FILES 部分中的 $GIT_DIR/svn/**/.rev_map.*)。
- dcommit
-
將當前分支的每個差異直接提交到 SVN 倉庫,然後進行變基或重置(取決於 SVN 和 head 之間是否存在差異)。這將在 SVN 中為 Git 中的每個提交建立一個修訂版本。
當將可選的 Git 分支名稱(或 Git 提交物件名稱)指定為引數時,子命令將在指定的分支上工作,而不是在當前分支上工作。
優先使用 dcommit 而不是 set-tree(見下文)。
- --no-rebase
-
提交後,不進行變基或重置。
- --commit-url <URL>
-
提交到此 SVN URL(完整路徑)。這旨在允許在使用者稍後獲得提交的替代傳輸方法(例如
svn+ssh://
或https://
)訪問時,可以重用使用一種傳輸方法(例如svn://
或http://
用於匿名讀取)建立的現有 git svn 倉庫。config key: svn-remote.<name>.commiturl config key: svn.commiturl (overwrites all svn-remote.<name>.commiturl options)
請注意,commiturl 配置鍵的 SVN URL 包含 SVN 分支。如果您希望為整個 SVN 倉庫設定提交 URL,請改用 svn-remote.<name>.pushurl。
非常不建議將此選項用於任何其他目的(不要問)。
- --mergeinfo=<mergeinfo>
-
在 dcommit 期間新增給定的合併資訊(例如
--mergeinfo="/branches/foo:1-10"
)。所有 svn 伺服器版本都可以儲存此資訊(作為屬性),並且從 1.5 版本開始的 svn 客戶端可以使用它。要指定來自多個分支的合併資訊,請在分支之間使用單個空格字元(--mergeinfo="/branches/foo:1-10
/branches/bar:3,5-6,8"
)config key: svn.pushmergeinfo
此選項將導致 git-svn 在可能的情況下嘗試自動填充 SVN 倉庫中的 svn:mergeinfo 屬性。目前,這隻能在 dcommit 非快進合併時完成,其中除第一個之外的所有父級都已推送到 SVN 中。
- --interactive
-
詢問使用者是否確認補丁集應實際傳送到 SVN。對於每個補丁,可以回答“yes”(接受此補丁)、“no”(放棄此補丁)、“all”(接受所有補丁)或“quit”(退出)。
如果回答是“no”或“quit”,git svn dcommit 將立即返回,而不向 SVN 提交任何內容。
- branch
-
在 SVN 倉庫中建立分支。
- -m
- --message
-
允許指定提交訊息。
- -t
- --tag
-
透過使用 tags_subdir 而不是 git svn init 期間指定的 branches_subdir 來建立標籤。
- -d<path>
- --destination=<path>
-
如果向 init 或 clone 命令提供了多個 --branches(或 --tags)選項,則必須提供您希望在 SVN 倉庫中建立的分支(或標籤)的位置。<path> 指定用於建立分支或標籤的路徑,並且應與已配置的分支或標籤引用規範之一的左側模式匹配。您可以使用以下命令檢視這些引用規範
git config --get-all svn-remote.<name>.branches git config --get-all svn-remote.<name>.tags
其中 <name> 是透過 init 命令的 -R 選項指定的 SVN 倉庫名稱(預設情況下為 "svn")。
- --username
-
指定用於執行提交的 SVN 使用者名稱。此選項將覆蓋 username 配置屬性。
- --commit-url
-
使用指定的 URL 連線到目標 Subversion 倉庫。這在源 SVN 倉庫是隻讀的情況下很有用。此選項將覆蓋配置屬性 commiturl。
git config --get-all svn-remote.<name>.commiturl
- --parents
-
建立父資料夾。此引數等同於 svn cp 命令中的 --parents 引數,對於非標準倉庫佈局很有用。
- tag
-
在 SVN 倉庫中建立標籤。這是 branch -t 的簡寫。
- log
-
這應該使 SVN 使用者在引用 -r/--revision 號時,更容易查詢 svn 日誌訊息。
支援‘svn log’的以下功能
新功能
注意SVN 本身只以 UTC 儲存時間,沒有其他。常規 svn 客戶端將 UTC 時間轉換為本地時間(或基於 TZ= 環境變數)。此命令具有相同的行為。 任何其他引數直接傳遞給 git log
- blame
-
顯示檔案的每一行最後由哪個修訂版本和作者修改。此模式的輸出預設與‘svn blame’的輸出格式相容。與 SVN blame 命令一樣,工作樹中未提交的本地更改將被忽略;檔案在 HEAD 修訂版本中的版本將被註釋。未知引數直接傳遞給 git blame。
- find-rev
-
當給定形式為 rN 的 SVN 修訂版本號時,返回相應的 Git 提交雜湊(這可以選擇性地後跟一個 tree-ish 以指定應搜尋哪個分支)。當給定一個 tree-ish 時,返回相應的 SVN 修訂版本號。
- set-tree
-
您應該考慮使用 dcommit 而不是此命令。將指定的提交或樹物件提交到 SVN。這依賴於您匯入的抓取資料是最新的。在提交到 SVN 時,它完全不嘗試進行打補丁,它只是用樹或提交中指定的檔案覆蓋檔案。所有合併都被假定為獨立於 git svn 功能進行。
- create-ignore
-
遞迴查詢目錄上的 svn:ignore 和 svn:global-ignores 屬性,並建立匹配的 .gitignore 檔案。生成的檔案已暫存待提交,但尚未提交。使用 -r/--revision 引用特定的修訂版本。
- show-ignore
-
遞迴查詢並列出目錄上的 svn:ignore 和 svn:global-ignores 屬性。輸出適合附加到 $GIT_DIR/info/exclude 檔案。
- mkdirs
-
嘗試根據 $GIT_DIR/svn/<refname>/unhandled.log 檔案中的資訊重新建立核心 Git 無法跟蹤的空目錄。使用“git svn clone”和“git svn rebase”時會自動重新建立空目錄,因此“mkdirs”旨在用於“git checkout”或“git reset”等命令之後。(有關更多資訊,請參閱 svn-remote.<name>.automkdirs 配置檔案選項。)
- commit-diff
-
提交命令列中兩個 tree-ish 引數的差異。此命令不依賴於在
git
svn
init
過的倉庫中。此命令接受三個引數:(a) 要進行差異比較的原始樹,(b) 新樹結果,(c) 目標 Subversion 倉庫的 URL。如果您正在從一個 git svn 感知的倉庫(已用 git svninit
過的倉庫)工作,則可以省略最後一個引數 (URL)。此命令需要 -r<revision> 選項。提交訊息可以直接透過
-m
或-F
選項提供,或者當第二個 tree-ish 指示此類物件時間接從標籤或提交中獲取,或者透過呼叫編輯器請求(參見下面的--edit
選項)。 - info
-
顯示有關檔案或目錄的資訊,類似於‘svn info’提供的資訊。目前不支援 -r/--revision 引數。使用 --url 選項僅輸出 URL: 欄位的值。
- proplist
-
列出 Subversion 倉庫中關於給定檔案或目錄的屬性。使用 -r/--revision 引用特定的 Subversion 修訂版本。
- propget
-
獲取作為第一個引數提供的 Subversion 屬性,用於檔案。可以使用 -r/--revision 指定特定修訂版本。
- propset
-
將作為第一個引數提供的 Subversion 屬性設定為作為第二個引數提供的值,應用於作為第三個引數提供的檔案。
示例
git svn propset svn:keywords "FreeBSD=%H" devel/py-tipper/Makefile
這將為檔案 devel/py-tipper/Makefile 將屬性 svn:keywords 設定為 FreeBSD=%H。
- show-externals
-
顯示 Subversion 外部庫。使用 -r/--revision 指定特定修訂版本。
- gc
-
壓縮 $GIT_DIR/svn/<refname>/unhandled.log 檔案並刪除 $GIT_DIR/svn/<refname>/index 檔案。
- reset
-
撤銷 fetch 到指定修訂版本的效果。這允許您重新 fetch 一個 SVN 修訂版本。通常,SVN 修訂版本的內容不應改變,並且 reset 不應是必需的。但是,如果 SVN 許可權更改,或者您更改了 --ignore-paths 選項,則 fetch 可能會因“commit 中未找到”(檔案以前不可見)或“checksum mismatch”(錯過修改)而失敗。如果問題檔案不能永遠忽略(使用 --ignore-paths),則修復倉庫的唯一方法是使用 reset。
只有 rev_map 和 refs/remotes/git-svn 會更改(有關詳細資訊,請參閱下面 FILES 部分中的 $GIT_DIR/svn/**/.rev_map.*)。在 reset 之後執行 fetch,然後執行 git reset 或 git rebase 以將本地分支移動到新樹上。
- -r <n>
- --revision=<n>
-
指定要保留的最新修訂版本。所有後續修訂版本都將被丟棄。
- -p
- --parent
-
同時丟棄指定修訂版本,而是保留最近的父級。
- 示例
-
假設您在“master”中有本地更改,但需要重新抓取“r2”。
r1---r2---r3 remotes/git-svn \ A---B master
首先修復導致“r2”不完整的 ignore-paths 或 SVN 許可權問題。然後
git svn reset -r2 -p git svn fetch
r1---r2'--r3' remotes/git-svn \ r2---r3---A---B master
然後用 git rebase 修復“master”。不要使用 git merge,否則您的歷史記錄將與未來的 dcommit 不相容!
git rebase --onto remotes/git-svn A^ master
r1---r2'--r3' remotes/git-svn \ A'--B' master
選項
- --template=<template-directory>
-
僅與 init 命令一起使用。這些直接傳遞給 git init。
- -r <arg>
- --revision <arg>
-
與 fetch 命令一起使用。
這允許支援部分/截斷歷史的修訂範圍。支援 $NUMBER、$NUMBER1:$NUMBER2(數字範圍)、$NUMBER:HEAD 和 BASE:$NUMBER。
這允許您在執行 fetch 時建立部分映象;但通常不建議這樣做,因為歷史記錄將被跳過並丟失。
- -
- --stdin
-
僅與 set-tree 命令一起使用。
從 stdin 讀取提交列表並按相反順序提交它們。每行只讀取開頭的 sha1,因此可以使用 git rev-list --pretty=oneline 輸出。
- --rmdir
-
僅與 dcommit、set-tree 和 commit-diff 命令一起使用。
如果 SVN 樹中沒有剩餘檔案,則從 SVN 樹中刪除目錄。SVN 可以對空目錄進行版本控制,如果其中沒有剩餘檔案,則預設情況下不會刪除它們。Git 無法對空目錄進行版本控制。啟用此標誌將使提交到 SVN 的行為類似於 Git。
config key: svn.rmdir
- -e
- --edit
-
僅與 dcommit、set-tree 和 commit-diff 命令一起使用。
在提交到 SVN 之前編輯提交訊息。對於提交物件,此功能預設關閉;對於提交樹物件,此功能強制開啟。
config key: svn.edit
- -l<num>
- --find-copies-harder
-
僅與 dcommit、set-tree 和 commit-diff 命令一起使用。
它們都直接傳遞給 git diff-tree;有關更多資訊,請參閱 git-diff-tree[1]。
config key: svn.l config key: svn.findcopiesharder
- -A<filename>
- --authors-file=<filename>
-
語法與 git cvsimport 使用的檔案相容,但可以使用 <> 提供空電子郵件地址。
loginname = Joe User <user@example.com>
如果指定此選項,並且 git svn 遇到作者檔案中不存在的 SVN 提交者名稱,git svn 將中止操作。使用者將需要新增相應的條目。在修改作者檔案後重新執行先前的 git svn 命令應會繼續操作。
config key: svn.authorsfile
- --authors-prog=<filename>
-
如果指定此選項,則對於作者檔案中不存在的每個 SVN 提交者名稱,將執行給定檔案,並將提交者名稱作為第一個引數。該程式應返回“Name <email>”或“Name <>”形式的單行,該行將被視為包含在作者檔案中。
由於歷史原因,相對 filename 首先在當前目錄中搜索 init 和 clone,然後在工作樹的根目錄中搜索 fetch。如果未找到 filename,則像搜尋 $PATH 中的任何其他命令一樣搜尋它。
config key: svn.authorsProg
- -q
- --quiet
-
使 git svn 更少冗長。第二次指定可使其更少冗長。
- -m
- --merge
- -s<strategy>
- --strategy=<strategy>
- -p
- --rebase-merges
-
這些僅與 dcommit 和 rebase 命令一起使用。
當使用 dcommit 且無法使用 git reset 時(參見 dcommit),直接傳遞給 git rebase。
- -n
- --dry-run
-
這可以與 dcommit、rebase、branch 和 tag 命令一起使用。
對於 dcommit,打印出將顯示哪些差異將提交到 SVN 的 Git 引數序列。
對於 rebase,顯示與當前分支關聯的上游 SVN 倉庫相關的本地分支,以及將從中抓取 SVN 倉庫的 URL。
對於 branch 和 tag,顯示建立分支或標籤時將用於複製的 URL。
- --use-log-author
-
將 svn 提交檢索到 Git 時(作為 fetch、rebase 或 dcommit 操作的一部分),在日誌訊息中查詢第一個
From:
行或Signed-off-by
尾部,並將其用作作者字串。config key: svn.useLogAuthor
- --add-author-from
-
當從 Git 提交到 SVN 時(作為 set-tree 或 dcommit 操作的一部分),如果現有日誌訊息尚未包含
From:
或Signed-off-by
尾部,則根據 Git 提交的作者字串新增一個From:
行。如果您使用此選項,則--use-log-author
將為所有提交檢索有效的作者字串。config key: svn.addAuthorFrom
高階選項
- -i<GIT_SVN_ID>
- --id <GIT_SVN_ID>
-
這會設定 GIT_SVN_ID(而不是使用環境變數)。這允許使用者在跟蹤單個 URL 時覆蓋預設的要抓取的 refname。log 和 dcommit 命令不再需要此開關作為引數。
- -R<remote-name>
- --svn-remote <remote-name>
-
指定要使用的 [svn-remote "<remote-name>"] 部分,這允許跟蹤多個 SVN 倉庫。預設值:“svn”
- --follow-parent
-
此選項僅在我們跟蹤分支時相關(使用倉庫佈局選項之一:--trunk、--tags、--branches、--stdlayout)。對於每個跟蹤的分支,嘗試找出其修訂版本是從何處複製的,並在該分支的第一個 Git 提交中設定一個合適的父級。當跟蹤在倉庫內移動的目錄時,這尤其有用。如果停用此功能,由 git svn 建立的分支都將是線性的,並且不共享任何歷史記錄,這意味著將沒有關於分支從何處分出或合併的資訊。但是,跟蹤冗長/複雜歷史可能需要很長時間,因此停用此功能可能會加快克隆過程。此功能預設啟用,使用 --no-follow-parent 停用它。
config key: svn.followparent
僅配置檔案選項
- svn.noMetadata
- svn-remote.<name>.noMetadata
-
這會移除每個提交末尾的 git-svn-id: 行。
此選項只能用於一次性匯入,因為如果沒有元資料,git svn 將無法再次抓取。此外,如果您丟失 $GIT_DIR/svn/**/.rev_map.* 檔案,git svn 將無法重建它們。
git svn log 命令也無法在此選項下的倉庫上工作。出於(希望是)顯而易見的原因,使用此選項與 useSvmProps 選項衝突。
不建議使用此選項,因為它會使在現有文件、錯誤報告和存檔中追溯對 SVN 修訂版本號的舊引用變得困難。如果您計劃最終從 SVN 遷移到 Git 並確定要放棄 SVN 歷史,請考慮使用 git-filter-repo。filter-repo 還允許重新格式化元資料以便於閱讀,併為非“svn.authorsFile”使用者重寫作者資訊。
- svn.useSvmProps
- svn-remote.<name>.useSvmProps
-
這允許 git svn 從使用 SVN::Mirror(或 svk)建立的映象重新對映倉庫 URL 和 UUID,用於元資料。
如果 SVN 修訂版本具有屬性“svm:headrev”,則該修訂版本很可能是由 SVN::Mirror(也由 SVK 使用)建立的。該屬性包含倉庫 UUID 和修訂版本。我們希望使其看起來像是正在映象原始 URL,因此引入一個輔助函式來返回原始身份 URL 和 UUID,並在提交訊息中生成元資料時使用它。
- svn.useSvnsyncProps
- svn-remote.<name>.useSvnsyncprops
-
類似於 useSvmProps 選項;這是為 SVN 1.4.x 及更高版本附帶的 svnsync(1) 命令的使用者提供的。
- svn-remote.<name>.rewriteRoot
-
這允許使用者從替代 URL 建立倉庫。例如,管理員可以在本地伺服器上執行 git svn(透過 file:// 訪問),但希望在元資料中包含公共 http:// 或 svn:// URL 來分發倉庫,以便使用者能看到公共 URL。
- svn-remote.<name>.rewriteUUID
-
類似於 useSvmProps 選項;這是為需要手動重新對映 UUID 的使用者提供的。這在原始 UUID 無法透過 useSvmProps 或 useSvnsyncProps 獲取的情況下可能很有用。
- svn-remote.<name>.pushurl
-
類似於 Git 的
remote.
<name>.pushurl
,此鍵旨在用於 url 透過只讀傳輸指向 SVN 倉庫的情況,以提供備用讀/寫傳輸。假定這兩個鍵都指向同一個倉庫。與 commiturl 不同,pushurl 是一個基本路徑。如果可以使用 commiturl 或 pushurl,則 commiturl 優先。 - svn.brokenSymlinkWorkaround
-
這會停用可能代價高昂的檢查,以解決由損壞的客戶端檢查到 SVN 中的損壞符號連結。如果您跟蹤的 SVN 倉庫有許多不是符號連結的空 blob,請將此選項設定為“false”。此選項可以在 git svn 執行時更改,並在下次抓取修訂版本時生效。如果未設定,git svn 假定此選項為“true”。
- svn.pathnameencoding
-
這指示 git svn 將路徑名重新編碼為給定編碼。Windows 使用者和在非 UTF-8 區域設定中工作的使用者可以使用它,以避免帶有非 ASCII 字元的檔名損壞。有效編碼是 Perl 的 Encode 模組支援的編碼。
- svn-remote.<name>.automkdirs
-
通常,“git svn clone”和“git svn rebase”命令會嘗試重新建立 Subversion 倉庫中的空目錄。如果此選項設定為“false”,則只有在明確執行“git svn mkdirs”命令時才會建立空目錄。如果未設定,git svn 假定此選項為“true”。
由於 noMetadata、rewriteRoot、rewriteUUID、useSvnsyncProps 和 useSvmProps 選項都會影響 git svn 生成和使用的元資料;它們必須在匯入任何歷史記錄之前在配置檔案中設定,並且一旦設定,這些設定絕不應更改。
此外,每個 svn-remote 部分只能使用這些選項中的一個,因為它們會影響 git-svn-id: 元資料行,但 rewriteRoot 和 rewriteUUID 可以一起使用。
基本示例
跟蹤 Subversion 管理的專案的主幹併為其貢獻(忽略標籤和分支)
# Clone a repo (like git clone): git svn clone http://svn.example.com/project/trunk # Enter the newly cloned directory: cd trunk # You should be on master branch, double-check with 'git branch' git branch # Do some work and commit locally to Git: git commit ... # Something is committed to SVN, rebase your local changes against the # latest changes in SVN: git svn rebase # Now commit your changes (that were committed previously using Git) to SVN, # as well as automatically updating your working HEAD: git svn dcommit # Append svn:ignore and svn:global-ignores settings to the default Git exclude file: git svn show-ignore >> .git/info/exclude
跟蹤並貢獻整個 Subversion 管理的專案(包含主幹、標籤和分支)
# Clone a repo with standard SVN directory layout (like git clone): git svn clone http://svn.example.com/project --stdlayout --prefix svn/ # Or, if the repo uses a non-standard directory layout: git svn clone http://svn.example.com/project -T tr -b branch -t tag --prefix svn/ # View all branches and tags you have cloned: git branch -r # Create a new branch in SVN git svn branch waldo # Reset your master to trunk (or any other branch, replacing 'trunk' # with the appropriate name): git reset --hard svn/trunk # You may only dcommit to one branch/tag/trunk at a time. The usage # of dcommit/rebase/show-ignore should be the same as above.
最初的 git svn clone 可能非常耗時(特別是對於大型 Subversion 倉庫)。如果多個人(或一臺機器上的多個人)希望使用 git svn 與同一個 Subversion 倉庫互動,您可以將最初的 git svn clone 到伺服器上的一個倉庫,然後讓每個人都用 git clone 克隆該倉庫。
# Do the initial import on a server ssh server "cd /pub && git svn clone http://svn.example.com/project [options...]" # Clone locally - make sure the refs/remotes/ space matches the server mkdir project cd project git init git remote add origin server:/pub/project git config --replace-all remote.origin.fetch '+refs/remotes/*:refs/remotes/*' git fetch # Prevent fetch/pull from remote Git server in the future, # we only want to use git svn for future updates git config --remove-section remote.origin # Create a local branch from one of the branches just fetched git checkout -b master FETCH_HEAD # Initialize 'git svn' locally (be sure to use the same URL and # --stdlayout/-T/-b/-t/--prefix options as were used on server) git svn init http://svn.example.com/project [options...] # Pull the latest changes from Subversion git svn rebase
REBASE 與 PULL/MERGE
優先使用 git svn rebase 或 git rebase,而不是 git pull 或 git merge 來將未整合提交與 git svn 分支同步。這樣做將使未整合提交的歷史相對於上游 SVN 倉庫保持線性,並允許使用首選的 git svn dcommit 子命令將未整合提交推回 SVN。
最初,git svn 建議開發者從 git svn 分支拉取或合併。這是因為作者偏愛 git
svn
set-tree
B
來提交單個頭,而不是 git
svn
set-tree
A..B
表示法來提交多個提交。將 git pull 或 git merge 與 git
svn
set-tree
A..B
結合使用,將在提交到 SVN 時導致非線性歷史被扁平化,這可能導致合併提交意外地反轉 SVN 中的先前提交。
合併跟蹤
雖然 git svn 可以跟蹤採用標準佈局的倉庫的複製歷史(包括分支和標籤),但它尚無法將 Git 內部發生的合併歷史表示回上游的 SVN 使用者。因此,建議使用者在 Git 內部儘可能保持歷史線性,以方便與 SVN 相容(參見下面的 CAVEATS 部分)。
SVN 分支的處理
如果 git svn 配置為抓取分支(並且 --follow-branches 生效),它有時會為一個 SVN 分支建立多個 Git 分支,其中額外的分支名稱形式為 branchname@nnn(其中 nnn 是 SVN 修訂版本號)。如果 git svn 無法為 SVN 分支中的第一個提交找到父提交,以將該分支連線到其他分支的歷史記錄,則會建立這些額外的分支。
通常,SVN 分支中的第一個提交由複製操作組成。git svn 將讀取此提交以獲取建立該分支的 SVN 修訂版本。然後它將嘗試查詢與此 SVN 修訂版本對應的 Git 提交,並將其用作分支的父級。但是,可能沒有合適的 Git 提交作為父級。發生這種情況的原因包括,如果 SVN 分支是 git svn 未抓取到的修訂版本的副本(例如,因為它是一箇舊修訂版本,已用 --revision
跳過),或者如果在 SVN 中複製了一個 git svn 未跟蹤的目錄(例如,一個根本未跟蹤的分支,或一個已跟蹤分支的子目錄)。在這些情況下,git svn 仍將建立一個 Git 分支,但它不會使用現有 Git 提交作為分支的父級,而是會讀取複製分支的目錄的 SVN 歷史記錄並建立適當的 Git 提交。這由訊息“Initializing parent: <branchname>”指示。
此外,它將建立一個名為 <branchname>@<SVN-Revision> 的特殊分支,其中 <SVN-Revision> 是複製該分支的 SVN 修訂版本號。此分支將指向該分支新建立的父提交。如果在 SVN 中該分支被刪除並稍後從不同版本重新建立,則將有多個帶有 @ 的此類分支。
請注意,這可能意味著單個 SVN 修訂版本會建立多個 Git 提交。
一個例子:在一個具有標準 trunk/tags/branches 佈局的 SVN 倉庫中,目錄 trunk/sub 在 r.100 中建立。在 r.200 中,透過將其複製到 branches/ 來建立 trunk/sub 分支。然後 git svn clone -s 將建立一個分支 sub。它還將為 r.100 到 r.199 建立新的 Git 提交,並將其用作分支 sub 的歷史記錄。因此,從 r.100 到 r.199 的每個修訂版本將有兩個 Git 提交(一個包含 trunk/,一個包含 trunk/sub/)。最後,它將建立一個分支 sub@200,指向分支 sub 的新父提交(即 r.200 和 trunk/sub/ 的提交)。
注意事項
為了簡化和與 Subversion 互操作,建議所有 git svn 使用者直接從 SVN 伺服器克隆、抓取和 dcommit,並避免 Git 倉庫和分支之間的所有 git clone/pull/merge/push 操作。在 Git 分支和使用者之間交換程式碼的推薦方法是 git format-patch 和 git am,或者僅僅是 dcommit 到 SVN 倉庫。
不建議在您計劃 dcommit 的分支上執行 git merge 或 git pull,因為 Subversion 使用者看不到您所做的任何合併。此外,如果您從作為 SVN 分支映象的 Git 分支合併或拉取,dcommit 可能會提交到錯誤的分支。
如果您進行合併,請注意以下規則:git svn dcommit 將嘗試在名為
git log --grep=^git-svn-id: --first-parent -1
因此,您必須確保您要 dcommit 的分支的最新提交是合併的第一個父級。否則將導致混亂,特別是如果第一個父級是同一 SVN 分支上的舊提交。
git clone 不克隆 refs/remotes/ 層次結構下的分支或任何 git svn 元資料或配置。因此,使用 git svn 建立和管理的倉庫應該使用 rsync 進行克隆,如果需要克隆的話。
由於 dcommit 內部使用 rebase,因此在 dcommit 之前您 git push 到的任何 Git 分支都將需要強制覆蓋遠端倉庫上現有引用。這通常被認為是壞習慣,有關詳細資訊,請參閱 git-push[1] 文件。
不要對您已經 dcommit 的更改使用 git-commit[1] 的 --amend 選項。修改您已經推送到遠端倉庫供其他使用者使用的提交被認為是壞習慣,而 SVN 的 dcommit 與此類似。
克隆 SVN 倉庫時,如果沒有使用任何描述倉庫佈局的選項(--trunk、--tags、--branches、--stdlayout),git svn clone 將建立一個具有完全線性歷史的 Git 倉庫,其中分支和標籤在工作副本中顯示為單獨的目錄。雖然這是獲取完整倉庫副本最簡單的方法,但對於具有許多分支的專案,它將導致工作副本比僅主幹大許多倍。因此,對於使用標準目錄結構(trunk/branches/tags)的專案,建議使用 --stdlayout
選項進行克隆。如果專案使用非標準結構,並且/或者不需要分支和標籤,最簡單的方法是隻克隆一個目錄(通常是 trunk),而不提供任何倉庫佈局選項。如果需要包含分支和標籤的完整歷史記錄,則必須使用 --trunk
/ --branches
/ --tags
選項。
當使用多個 --branches 或 --tags 時,git svn 不會自動處理名稱衝突(例如,如果來自不同路徑的兩個分支具有相同的名稱,或者如果分支和標籤具有相同的名稱)。在這些情況下,請使用 init 設定您的 Git 倉庫,然後在第一次 fetch 之前,編輯 $GIT_DIR/config 檔案,以便分支和標籤與不同的名稱空間關聯。例如
branches = stable/*:refs/remotes/svn/stable/* branches = debug/*:refs/remotes/svn/debug/*
配置
git svn 將 [svn-remote] 配置資訊儲存在倉庫的 $GIT_DIR/config 檔案中。它類似於核心 Git 的 [remote] 部分,只是 fetch 鍵不接受 glob 引數;而是由 branches 和 tags 鍵處理。由於某些 SVN 倉庫配置異常,包含多個專案,因此允許以下 glob 擴充套件
[svn-remote "project-a"] url = http://server.org/svn fetch = trunk/project-a:refs/remotes/project-a/trunk branches = branches/*/project-a:refs/remotes/project-a/branches/* branches = branches/release_*:refs/remotes/project-a/branches/release_* branches = branches/re*se:refs/remotes/project-a/branches/* tags = tags/*/project-a:refs/remotes/project-a/tags/*
請記住,本地引用(:
右側)的 *
(星號)萬用字元必須是最右側的路徑元件;但遠端萬用字元可以在任何位置,只要它是一個獨立的路徑元件(由 /
或行尾包圍)。此型別的配置不會由 init 自動建立,應使用文字編輯器或 git config 手動輸入。
另請注意,每個單詞只允許一個星號。例如
branches = branches/re*se:refs/remotes/project-a/branches/*
將匹配分支 release、rese、re123se,但是
branches = branches/re*s*e:refs/remotes/project-a/branches/*
將產生錯誤。
也可以透過使用大括號內逗號分隔的名稱列表來抓取分支或標籤的子集。例如
[svn-remote "huge-project"] url = http://server.org/svn fetch = trunk/src:refs/remotes/trunk branches = branches/{red,green}/src:refs/remotes/project-a/branches/* tags = tags/{1.0,2.0}/src:refs/remotes/project-a/tags/*
支援多個 fetch、branches 和 tags 鍵
[svn-remote "messy-repo"] url = http://server.org/svn fetch = trunk/project-a:refs/remotes/project-a/trunk fetch = branches/demos/june-project-a-demo:refs/remotes/project-a/demos/june-demo branches = branches/server/*:refs/remotes/project-a/branches/* branches = branches/demos/2011/*:refs/remotes/project-a/2011-demos/* tags = tags/server/*:refs/remotes/project-a/tags/*
在此類配置中建立分支需要使用 -d 或 --destination 標誌來消除位置歧義
$ git svn branch -d branches/server release-2-3-0
請注意,git-svn 會跟蹤分支或標籤出現的最高修訂版本。如果在抓取後更改了分支或標籤的子集,則必須手動編輯 $GIT_DIR/svn/.metadata 以刪除(或重置)branches-maxRev 和/或 tags-maxRev。
BUG
我們忽略所有 SVN 屬性,除了 svn:executable。任何未處理的屬性都會記錄到 $GIT_DIR/svn/<refname>/unhandled.log。
Git 不檢測重新命名和複製的目錄,因此在提交到 SVN 時也不會跟蹤它們。我不打算為此新增支援,因為它非常困難且耗時,無法涵蓋所有可能的邊緣情況(Git 也無法做到)。如果重新命名和複製的檔案足夠相似以供 Git 檢測,則完全支援提交它們。
在 SVN 中,可以(但不建議)提交更改到標籤(因為標籤只是目錄副本,因此技術上與分支相同)。克隆 SVN 倉庫時,git svn 無法知道將來是否會發生此類標籤提交。因此,它保守地將所有 SVN 標籤作為分支匯入,並在標籤名稱前加上 tags/ 字首。