设置由 --preserve-empty-dirs 创建的占位符文件的名称。 默认:".gitignore"
这将从当前 HEAD 的 SVN 父版本中获取修订版本,并将当前(未提交至 SVN)工作与之相对应。
除了用
git rebase
而不是
git merge
保留线性历史记录以便于用
git svn
提交外,它的工作原理与
svn update
或
git pull
类似。
它接受所有
git svn fetch
和
git rebase
接受的选项。 不过,
--fetch-all
只从当前 [svn-remote] 获取,而不是所有 [svn-remote] 定义。
和
git rebase
一样,它要求工作区是干净的,没有未提交的更改。
如果需要,这将自动更新 rev_map(详情请参见下文 FILES 部分中的
$GIT_DIR/svn/**/.rev_map.*
)。
同时丢弃指定的修订版本,保留最近的父版本。
假设 "master" 中有本地更改,但需要重新获取 "r2"(都是分支名)。
r1---r2---r3 remotes/git-svn
A---B master
修复导致 "r2 "不完整的忽略路径或 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
与
fetch
(获取 ) 命令一起使用。
这样就可以支持部分/阉割历史的修订范围。 支持 $NUMBER、$NUMBER1:$NUMBER2(数字范围)、$NUMBER:HEAD 和 BASE:$NUMBER。
这样可以在运行 fetch (获取)时建立部分镜像,但一般不建议这样做,因为历史记录会被跳过并丢失。
只有在跟踪分支的情况下(使用仓库布局选项之一 --trunk、--tags、--branches、--stdlayout),该选项才有意义。对于每个被跟踪的分支,我们会尝试找出它的修订版本是从哪里复制的,并在该分支的第一次 Git 提交中设置一个合适的父分支。 当我们跟踪的目录在版本库中被移动过时,这一点尤其有用。 如果禁用此功能,
git svn
创建的分支将全部是线性的,不会共享任何历史记录,这意味着不会有任何关于分支被分支或合并的信息。 不过,追踪冗长/复杂的历史可能需要很长时间,所以禁用该功能可能会加快克隆过程。该功能默认为启用,使用 --no-follow-parent 可以禁用它。
config key: svn.followparent
这样就不会在每次提交的最后出现
git-svn-id:
行。
这个选项只能用于一次性导入,因为如果没有元数据,
git svn
将无法再次获取。此外,如果丢失了
$GIT_DIR/svn/**/.rev_map.*
文件,
git svn
将无法重建它们。
git svn log
命令在使用此选项的仓库中也不起作用。 由于(希望)显而易见的原因,使用此选项与
useSvmProps
选项冲突.
通常,"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 可以一起使用。
# 用标准 SVN 目录布局克隆一个仓库(与 git clone 类似):
git svn clone http://svn.example.com/project --stdlayout --prefix svn/
# 或者,如果仓库使用非标准目录布局:
git svn clone http://svn.example.com/project -T tr -b branch -t tag --prefix svn/
# 查看您克隆的所有分支和标签:
git branch -r
# 在 SVN 中创建一个新分支
git svn branch waldo
# 重置您的主分支为 trunk(或任何其他分支,用适当的名称替换 'trunk'
# 替换为合适的名称):
git reset --hard svn/trunk
# 一次只能提交到一个分支/标签/主干。 使用
# dcommit/rebase/show-ignore 的用法应与上述相同。
最初的
git svn clone
可能相当耗时(尤其是对于大型 Subversion 仓库)。如果多人(或一人拥有多台机器)想用
git svn
与同一个 Subversion 仓库交互,可以先用
git svn clone
克隆服务器上的仓库,然后让每个人用
git clone
克隆该仓库:
# 在服务器上进行初始导入
ssh server "cd /pub && git svn clone http://svn.example.com/project [options...]"
# 克隆到本地 - 确保 refs/remotes/ 空间与服务器一致
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
# 防止将来从远程 Git 服务器获取/拉取、
# 我们只想在将来的更新中使用 git svn
git config --remove-section remote.origin
# 从刚刚获取的分支中创建一个本地分支
git checkout -b master FETCH_HEAD
# 在本地初始化 "git svn"(确保使用相同的 URL 和
--stdlayout/-T/-b/-t/-t--prefix 选项)。
git svn init http://svn.example.com/project [options...]
# 从 Subversion 拉取最新修改
git svn rebase
优先使用
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
被配置为获取分支(且 --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:<分支名>"信息来表示。
此外,它还会创建一个名为
<分支名>@<SVN-版本>
的特殊分支,其中 <SVN-版本> 是该分支复制自的 SVN 版本号。 该分支将指向该分支新创建的父提交。 如果该分支在 SVN 中被删除,后来又从不同版本重新创建,则会出现多个带
@
的分支。
请注意,这可能意味着一个 SVN 修订版会创建多个 Git 提交。
举个例子:在一个采用标准 trunk/tags/branches 布局的 SVN 代码库中,r.100 中创建了 trunk/sub 目录。 在 r.200 中,trunk/sub 被复制到 branches/ 中,从而被分支。
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 服务器 clone、fetch 和 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
会尝试提交在 SVN 的顶部提交
git log --grep=^git-svn-id: --first-parent -1
因此,您 “必须” 确保您要提交到的分支的最新提交是合并的
first
父提交。 否则就会出现混乱,尤其是当第一父提交是同一 SVN 分支上的旧提交时。
git clone
不会克隆 refs/remotes/ 层次结构下的分支,也不会克隆任何
git svn
元数据或配置。 因此,如果要克隆,使用
git svn
创建和管理的仓库应该使用
rsync
来克隆。
请注意,git-svn 会记录分支或标签出现过的最高修订版本。如果分支或标签的子集在获取后发生了变化,则必须手动编辑 $GIT_DIR/svn/.metadata,以根据情况移除(或重置)分支-最高修订和/或标签-最高修订。