git-svn

原文: https://git-scm.com/docs/git-svn

名称

git-svn - Subversion存储库和Git之间的双向操作

概要

  1. git svn <command> [<options>] [<arguments>]

描述

git svn 是Subversion和Git之间变更集的简单管道。它提供Subversion和Git存储库之间的双向变化流。

git svn 可以使用—stdlayout选项跟踪常见的“trunk / branches / tags”布局的标准Subversion存储库。它还可以使用-T / -t / -b选项跟随任何布局中的分支和标签(请参阅下面的 init 选项,以及 clone 命令)。

一旦跟踪Subversion存储库(使用上述任何方法),就可以通过 fetch 命令从Subversion更新Git存储库,并通过 dcommit 命令从Git更新Subversion。

COMMANDS

  1. init

使用 git svn 的其他元数据目录初始化一个空的Git存储库。 Subversion URL可以指定为命令行参数,也可以指定为-T / -t / -b的完整URL参数。可选地,可以将要操作的目标目录指定为第二个参数。通常,此命令初始化当前目录。

  1. -T<trunk_subdir>
  1. --trunk=<trunk_subdir>
  1. -t<tags_subdir>
  1. --tags=<tags_subdir>
  1. -b<branches_subdir>
  1. --branches=<branches_subdir>
  1. -s
  1. --stdlayout

这些是init的可选命令行选项。这些标志中的每一个都可以指向相对存储库路径(—tags = project / tags)或完整URL(—tags = https://foo.org/project/tags)。如果您的Subversion存储库在多个路径下放置标记或分支,您可以指定多个—tags和/或—branches选项。选项—stdlayout是将trunk,tags,branches设置为相对路径的简便方法,这是Subversion的默认设置。如果同时给出任何其他选项,则它们优先。

  1. --no-metadata

在[svn-remote]配置中设置 noMetadata 选项。建议不要使用此选项,请在使用此选项之前阅读本联机帮助页的 svn.noMetadata 部分。

  1. --use-svm-props

在[svn-remote]配置中设置 useSvmProps 选项。

  1. --use-svnsync-props

在[svn-remote]配置中设置 useSvnsyncProps 选项。

  1. --rewrite-root=<URL>

在[svn-remote]配置中设置 rewriteRoot 选项。

  1. --rewrite-uuid=<UUID>

在[svn-remote]配置中设置 rewriteUUID 选项。

  1. --username=<user>

对于SVN处理(http,https和plain svn)身份验证的传输,请指定用户名。对于其他传输(例如svn+ssh://),您必须在URL中包含用户名,例如svn+ssh://foo@svn.bar.com/project

  1. --prefix=<prefix>

如果指定了trunk / branches / tags,则允许指定前缀为遥控器名称的前缀。前缀不会自动包含尾部斜杠,因此请确保在参数中包含一个前缀,如果这是您想要的。如果指定了—branches / -b,则前缀必须包含尾部斜杠。在任何情况下都强烈建议设置前缀(带斜杠),因为你的SVN跟踪引用将位于“refs / remotes / $ prefix / ”,这与Git自己的远程跟踪引用兼容layout(refs / remotes / $ remote / )。如果要跟踪共享公共存储库的多个项目,则设置前缀也很有用。默认情况下,前缀设置为 origin /

| 注意 | 在Git v2.0之前,默认前缀是“”(没有前缀)。这意味着SVN跟踪引用被放在“refs / remotes / *”,这与Git自己的远程跟踪引用的组织方式不兼容。如果您仍然需要旧的默认值,可以通过在命令行上传递--prefix ""来获取它(如果你的Perl的Getopt :: Long是< v2.37,--prefix=""可能不起作用)。 |

  1. --ignore-refs=<regex>

传递给 initclone 时,此正则表达式将作为配置键保留。有关--ignore-refs的说明,请参见 fetch

  1. --ignore-paths=<regex>

传递给 initclone 时,此正则表达式将作为配置键保留。有关--ignore-paths的说明,请参见 fetch

  1. --include-paths=<regex>

传递给 initclone 时,此正则表达式将作为配置键保留。有关--include-paths的说明,请参见 fetch

  1. --no-minimize-url

当跟踪多个目录(使用—stdlayout, - blank或—tags选项)时,git svn将尝试连接到Subversion存储库的根目录(或允许的最高级别)。如果整个项目在存储库中移动,则此默认设置允许更好地跟踪历史记录,但可能会导致读取访问限制到位的存储库出现问题。传递--no-minimize-url将允许git svn按原样接受URL,而不尝试连接到更高级别的目录。默认情况下,当仅跟踪一个URL /分支时,此选项处于关闭状态(这样做不太好)。

  1. fetch

从我们正在跟踪的Subversion远程获取未经修改的修订。 $ GIT_DIR / config文件中[svn-remote“…”]部分的名称可以指定为可选的命令行参数。

如果需要,这会自动更新revmap(有关详细信息,请参阅下面的FILES部分中的 $ GITDIR / svn / \ /。rev_map。* )。

  1. --localtime

将Git提交时间存储在本地时区而不是UTC中。这使 git log (即使没有—date = local)显示与svn log在本地时区相同的时间。

这不会干扰与您克隆的Subversion存储库的互操作,但如果您希望本地Git存储库能够与其他人的本地Git存储库进行互操作,请不要使用此选项,或者您应该同时使用它同一个当地时区。

  1. --parent

仅从当前HEAD的SVN父级获取。

  1. --ignore-refs=<regex>

忽略与Perl正则表达式匹配的分支或标记的引用。像^refs/remotes/origin/(?!tags/wanted-tag|wanted-branch).*$这样的“负前瞻断言”可用于仅允许某些参考。

  1. config key: svn-remote.<name>.ignore-refs

如果设置了ignore-refs配置键,并且还给出了命令行选项,则将使用两个正则表达式。

  1. --ignore-paths=<regex>

这允许指定Perl正则表达式,该表达式将导致从SVN的checkout跳过所有匹配路径。 --ignore-paths选项应匹配每个 fetch (包括克隆dcommitrebase 等)的自动提取)给定存储库。

  1. config key: svn-remote.<name>.ignore-paths

如果设置了ignore-paths配置密钥,并且还给出了命令行选项,则将使用两个正则表达式。

例子:

  1. Skip "doc*" directory for every fetch
  1. --ignore-paths="^doc"
  1. Skip "branches" and "tags" of first level directories
  1. --ignore-paths="^[^/]+/(?:branches|tags)"
  1. --include-paths=<regex>

这允许指定一个Perl正则表达式,该表达式将仅包含来自SVN的checkout的匹配路径。 --include-paths选项应匹配每个 fetch (包括克隆dcommitrebase 等)的自动提取)给定存储库。 --ignore-paths优先于--include-paths

  1. config key: svn-remote.<name>.include-paths
  1. --log-window-size=<n>

获取< n>扫描Subversion历史记录时每个请求的日志条目。默认值为100.对于非常大的Subversion存储库, clone / fetch 可能需要更大的值才能在合理的时间内完成。但过大的值可能会导致更高的内存使用量和请求超时。

  1. clone

运行 init获取。它将根据传递给它的URL的基名自动创建一个目录;或者如果第二个论点通过;它将创建一个目录并在其中工作。它接受 initfetch 命令接受的所有参数; --fetch-all--parent除外。克隆存储库后, fetch 命令将能够在不影响工作树的情况下更新修订版;并且 rebase 命令将能够使用最新更改更新工作树。

  1. --preserve-empty-dirs

在本地Git存储库中为从Subversion获取的每个空目录创建一个占位符文件。这包括通过删除Subversion存储库中的所有条目(但不是目录本身)而变为空的目录。不再需要时,也会跟踪和删除占位符文件。

  1. --placeholder-filename=<filename>

设置—preserve-empty-dirs创建的占位符文件的名称。默认值:“。gitignore”

  1. rebase

这将从当前HEAD的SVN父级获取修订,并针对它重新定义当前(未提交到SVN)的工作。

这与svn updategit pull 类似,只是它保留 git rebase 而不是 git merge 的线性历史,以便于 git的同意svn

这接受 git svn fetchgit rebase 接受的所有选项。但是,--fetch-all仅从当前[svn-remote]获取,而不是所有[svn-remote]定义。

git rebase ;这要求工作树清洁并且没有未提交的更改。

如果需要,这会自动更新revmap(有关详细信息,请参阅下面的FILES部分中的 $ GITDIR / svn / \ /。rev_map。* )。

  1. -l
  1. --local

不要远程取;仅针对上游SVN上次提取的提交运行 git rebase

  1. dcommit

将每个diff从当前分支直接提交到SVN存储库,然后rebase或reset(取决于SVN和head之间是否存在差异)。这将在SVN中为Git中的每个提交创建一个修订版本。

当可选的Git分支名称(或Git提交对象名称)被指定为参数时,子命令在指定的分支上工作,而不在当前分支上工作。

使用 dcommit 优于 set-tree (下文)。

  1. --no-rebase

提交后,不要改变或重置。

  1. --commit-url <URL>

提交此SVN URL(完整路径)。这旨在允许使用一种传输方法创建的现有 git svn 存储库(例如,用于匿名读取的svn://http://)如果用户稍后被授权访问备用传输方法(例如,用于提交的svn+ssh://https://)。

  1. config key: svn-remote.<name>.commiturl
  2. config key: svn.commiturl (overwrites all svn-remote.<name>.commiturl options)

请注意,commiturl配置密钥的SVN URL包括SVN分支。如果您想要为整个SVN存储库设置提交URL,请使用svn-remote。< name> .pushurl。

强烈建议不要将此选项用于任何其他目的(不要问)。

  1. --mergeinfo=<mergeinfo>

在dcommit期间添加给定的合并信息(例如--mergeinfo="/branches/foo:1-10")。所有svn服务器版本都可以存储此信息(作为属性),从1.5版开始的svn客户端可以使用它。要指定来自多个分支的合并信息,请在分支之间使用单个空格字符(--mergeinfo="/branches/foo:1-10 /branches/bar:3,5-6,8"

  1. config key: svn.pushmergeinfo

此选项将导致git-svn尝试在可能的情况下自动填充SVN存储库中的svn:mergeinfo属性。目前,这只能在提交非快进合并时才能完成,其中除第一个之外的所有父级已经被推入SVN。

  1. --interactive

要求用户确认应该将补丁集实际发送到SVN。对于每个补丁,可以回答“是”(接受此补丁),“否”(丢弃此补丁),“全部”(接受所有补丁)或“退出”。

git svn dcommit 如果回答为“no”或“quit”则立即返回,而不向SVN提交任何内容。

  1. branch

在SVN存储库中创建分支。

  1. -m
  1. --message

允许指定提交消息。

  1. -t
  1. --tag

使用tags_subdir而不是git svn init期间指定的branches_subdir创建标记。

  1. -d<path>
  1. --destination=<path>

如果为 initclone 命令提供了多个 - 分支(或—tags)选项,则必须提供您希望的分支(或标记)的位置在SVN存储库中创建。 <路径>指定用于创建分支或标记的路径,并且应该与其中一个已配置的分支或标记refspecs的左侧模式匹配。您可以使用命令查看这些refspecs

  1. git config --get-all svn-remote.<name>.branches
  2. git config --get-all svn-remote.<name>.tags

其中< name>是 init 的-R选项(默认情况下为“svn”)指定的SVN存储库的名称。

  1. --username

指定要执行提交的SVN用户名。此选项会覆盖用户名配置属性。

  1. --commit-url

使用指定的URL连接到目标Subversion存储库。这在源SVN存储库是只读的情况下很有用。此选项会覆盖配置属性 commiturl

  1. git config --get-all svn-remote.<name>.commiturl
  1. --parents

创建父文件夹。此参数等效于参数—parents on svn cp命令,对非标准存储库布局很有用。

  1. tag

在SVN存储库中创建标记。这是 branch -t 的简写。

  1. log

当svn用户引用-r / - 版本号时,这应该可以很容易地查找svn日志消息。

支持’svn log’的以下功能:

  1. -r <n>[:<n>]
  1. --revision=<n>[:<n>]

支持,非数字args不是:HEAD,NEXT,BASE,PREV等…

  1. -v
  1. --verbose

它与svn log中的—verbose输出不完全兼容,但相当接近。

  1. --limit=<n>

与—max-count不同,不计算合并/排除的提交

  1. --incremental

支持的

新功能:

  1. --show-commit

还显示了Git commit sha1

  1. --oneline

我们的版本—pretty = oneline

| 注意 | SVN本身只存储UTC时间,没有别的。常规svn客户端将UTC时间转换为本地时间(或基于TZ =环境)。此命令具有相同的行为。 |

任何其他参数直接传递给 git log

  1. blame

显示修订版和作者上次修改文件的每一行。默认情况下,此模式的输出与’svn blame’的输出格式兼容。与SVN blame命令一样,忽略工作树中的本地未提交更改; HEAD修订版中的文件版本已注释。未知参数直接传递给 git blame

  1. --git-format

以与 git blame 相同的格式生成输出,但使用SVN修订号而不是Git提交哈希值。在此模式下,尚未提交到SVN的更改(包括本地工作副本编辑)显示为修订版0。

  1. find-rev

当给定形式为 rN 的SVN修订号时,返回相应的Git提交哈希(这可以选择后跟树,以指定应搜索哪个分支)。给定tree-ish时,返回相应的SVN修订号。

  1. -B
  1. --before

如果给出SVN修订版,则不需要完全匹配,而是在指定的修订版中找到与SVN存储库(在当前分支上)的状态相对应的提交。

  1. -A
  1. --after

如果给出SVN修订版,则不要求完全匹配;如果没有完全匹配,则返回在历史记录中向前搜索的最接近的匹配。

  1. set-tree

您应该考虑使用 dcommit 而不是此命令。将指定的提交或树对象提交给SVN。这取决于您导入的获取数据是最新的。这使得在提交SVN时绝对不会尝试进行修补,它只是用树中指定的文件或提交覆盖文件。假设所有合并都独立于 git svn 功能发生。

  1. create-ignore

递归地在目录上找到svn:ignore属性并创建匹配的.gitignore文件。生成的文件将暂存,但未提交。使用-r / - revision来引用特定的修订版。

  1. show-ignore

递归查找并列出目录上的svn:ignore属性。输出适合附加到$ GIT_DIR / info / exclude文件。

  1. mkdirs

尝试根据$ GIT_DIR / svn /< refname> /unhandled.log文件中的信息重新创建核心Git无法跟踪的空目录。使用“git svn clone”和“git svn rebase”时会自动重新创建空目录,因此“mkdirs”适用于“git checkout”或“git reset”之类的命令。 (有关详细信息,请参阅svn-remote。< name> .automkdirs配置文件选项。)

  1. commit-diff

从命令行提交两个tree-ish参数的diff。此命令不依赖于git svn init -ed存储库。该命令有三个参数,(a)要反对的原始树,(b)新的树结果,(c)目标Subversion存储库的URL。如果您使用的是 git svn -aware存储库(已经initgit svn 一起使用),则可以省略最终参数(URL)。 -r< revision>此选项是必需的。

提交消息直接使用-m-F选项提供,或者在第二个tree-ish表示此类对象时间接提供标记或提交,或者通过调用编辑器请求提交消息(请参阅--edit选项)下面)。

  1. -m <msg>
  1. --message=<msg>

使用给定的msg作为提交消息。此选项禁用--edit选项。

  1. -F <filename>
  1. --file=<filename>

从给定文件中获取提交消息。此选项禁用--edit选项。

  1. info

显示与“svn info”提供的文件或目录类似的信息。目前不支持-r / - revision参数。使用—url选项仅输出 URL:字段的值。

  1. proplist

列出存储在Subversion存储库中的有关给定文件或目录的属性。使用-r / - revision来引用特定的Subversion修订版。

  1. propget

获取作为文件的第一个参数给出的Subversion属性。可以使用-r / - revision指定特定修订。

  1. propset

将作为第一个参数给出的Subversion属性设置为作为第三个参数给出的文件的第二个参数给出的值。

例:

  1. git svn propset svn:keywords "FreeBSD=%H" devel/py-tipper/Makefile

这将为文件 devel / py-tipper / Makefile 设置属性 svn:keywordsFreeBSD =%H

  1. show-externals

显示Subversion外部。使用-r / - revision指定特定修订。

  1. gc

压缩$ GIT_DIR / svn /< refname> /unhandled.log文件并删除$ GIT_DIR / svn /< refname> / index文件。

  1. reset

fetch 的效果撤消回指定的修订版。这允许您重新获取 SVN修订版。通常,SVN修订版的内容永远不会改变,并且重置不应该是必需的。但是,如果SVN权限发生更改,或者您更改了—ignore-paths选项,则 fetch 可能会失败,并且“未在提交中找到”(文件以前未显示)或“校验和不匹配”(错过了修改)。如果问题文件永远不能被忽略(使用—ignore-paths)修复repo的唯一方法是使用 reset

仅更改了revmap和refs / remotes / git-svn(有关详细信息,请参阅下面FILES部分中的 $ GITDIR / svn / \ /。rev_map。* )。使用 fetch 然后 git resetgit rebase 关注重置,将本地分支移动到新树上。

  1. -r <n>
  1. --revision=<n>

指定要保留的最新修订。所有后来的修订都被丢弃了。

  1. -p
  1. --parent

同时丢弃指定的修订版,保留最近的父版本。

  1. Example:

假设您在“master”中有本地更改,但您需要重新获取“r2”。

  1. r1---r2---r3 remotes/git-svn
  2. \
  3. A---B master

修复了忽略路径或SVN权限问题,导致“r2”首先不完整。然后:

  1. git svn reset -r2 -p
  2. git svn fetch
  1. r1---r2'--r3' remotes/git-svn
  2. \
  3. r2---r3---A---B master

然后使用 git rebase 修复“master”。不要使用 git merge 或者您的历史记录将与以后的 dcommit 不兼容!

  1. git rebase --onto remotes/git-svn A^ master
  1. r1---r2'--r3' remotes/git-svn
  2. \
  3. A'--B' master

OPTIONS

  1. --shared[=(false|true|umask|group|all|world|everybody)]
  1. --template=<template_directory>

仅用于 init 命令。这些直接传递给 git init

  1. -r <arg>
  1. --revision <arg>

fetch 命令一起使用。

这允许支持部分/烧灼历史的修订范围。 $ NUMBER,$ NUMBER1:$ NUMBER2(数字范围),$ NUMBER:HEAD和BASE:$ NUMBER均受支持。

这可以让你在运行fetch时制作部分镜像;但通常不推荐,因为历史将被跳过和丢失。

  1. -
  1. --stdin

仅用于 set-tree 命令。

从stdin读取提交列表并以相反的顺序提交它们。只从每一行读取前导sha1,因此可以使用 git rev-list —pretty = oneline 输出。

  1. --rmdir

仅用于 dcommitset-treecommit-diff 命令。

如果没有留下文件,则从SVN树中删除目录。 SVN可以对空目录进行编辑,如果没有文件,则默认情况下不会删除它们。 Git无法对空目录进行版本控制。启用此标志将使提交到SVN的行为与Git相同。

  1. config key: svn.rmdir
  1. -e
  1. --edit

仅用于 dcommitset-treecommit-diff 命令。

在提交SVN之前编辑提交消息。对于提交的对象,默认情况下处于关闭状态,并且在提交树对象时强制关闭。

  1. config key: svn.edit
  1. -l<num>
  1. --find-copies-harder

仅用于 dcommitset-treecommit-diff 命令。

它们都直接传递给 git diff-tree ;有关详细信息,请参阅 git-diff-tree [1]

  1. config key: svn.l
  2. config key: svn.findcopiesharder
  1. -A<filename>
  1. --authors-file=<filename>

语法与 git cvsimport 使用的文件兼容,但<>可以提供空的电子邮件地址。

  1. loginname = Joe User <user@example.com>

如果指定了此选项并且 git svn 遇到作者文件中不存在的SVN提交者名称, git svn 将中止操作。然后,用户必须添加适当的条目。修改authors文件后重新运行以前的 git svn 命令应继续操作。

  1. config key: svn.authorsfile
  1. --authors-prog=<filename>

如果指定了此选项,则对于authors文件中不存在的每个SVN提交者名称,将使用提交者名称作为第一个参数执行给定文件。该程序预计将返回“Name< email>”形式的单行或“名称<>”,将被视为包含在作者文件中。

由于历史原因,首先相对于 initclone 的当前目录搜索相对文件名并且相对于的工作树的根目录获取。如果找不到文件名,则会像 $ PATH 中的任何其他命令一样进行搜索。

  1. config key: svn.authorsProg
  1. -q
  1. --quiet

使 git svn 不那么冗长。再次指定使其更简洁。

  1. -m
  1. --merge
  1. -s<strategy>
  1. --strategy=<strategy>
  1. -p
  1. --preserve-merges

这些仅用于 dcommitrebase 命令。

当使用 dcommit 时,如果不能使用 git reset ,则直接传递给 git rebase (参见 dcommit )。

  1. -n
  1. --dry-run

这可以与 dcommitrebase分支标签命令一起使用。

对于 dcommit ,打印出一系列Git参数,这些参数将显示哪些差异将被提交给SVN。

对于 rebase ,显示与当前分支关联的上游svn存储库关联的本地分支以及将从中获取的svn存储库的URL。

对于分支标签,显示创建分支或标记时将用于复制的URL。

  1. --use-log-author

当检索svn提交到Git中时(作为 fetchrebasedcommit 操作)的一部分,查找第一个From:Signed-off-by:行日志消息并将其用作作者字符串。

  1. config key: svn.useLogAuthor
  1. --add-author-from

当从Git提交svn时(作为 set-treedcommit 操作的一部分),如果现有的日志消息还没有From:Signed-off-by:行,根据Git提交的作者字符串附加From:行。如果您使用此,则--use-log-author将为所有提交检索有效的作者字符串。

  1. config key: svn.addAuthorFrom

高级选项

  1. -i<GIT_SVN_ID>
  1. --id <GIT_SVN_ID>

这设置了GITSVN_ID(而不是使用环境)。这允许用户在跟踪单个URL时覆盖默认的refname以从中获取。 _logdcommit 命令不再需要此开关作为参数。

  1. -R<remote name>
  1. --svn-remote <remote name>

指定要使用的[svn-remote“< remote name>”]部分,这允许跟踪SVN多个存储库。默认值:“svn”

  1. --follow-parent

此选项仅在我们跟踪分支时使用(使用其中一个存储库布局选项—trunk, - label, - blank, - stdlayout)。对于每个跟踪的分支,尝试找出其修订版本的位置,并在分支的第一个Git提交中设置合适的父代。当我们跟踪已在存储库中移动的目录时,这尤其有用。如果禁用此功能, git svn 创建的分支将全部为线性且不共享任何历史记录,这意味着没有关于分支分支或合并的信息。但是,长时间/错综复杂的历史记录可能需要很长时间,因此禁用此功能可能会加快克隆过程。默认情况下启用此功能,使用—no-follow-parent禁用它。

  1. config key: svn.followparent

配置文件选项

  1. svn.noMetadata
  1. 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-branch [1] 。 filter-branch还允许重新格式化元数据,以便于阅读和重写非“svn.authorsFile”用户的作者信息。

  1. svn.useSvmProps
  1. svn-remote.<name>.useSvmProps

这允许 git svn 从使用SVN :: Mirror(或svk)为元数据创建的镜像重新映射存储库URL和UUID。

如果SVN修订版具有属性“svm:headrev”,则修订版很可能是由SVN :: Mirror创建的(也是SVK使用的)。该属性包含存储库UUID和修订版。我们希望看起来像是在镜像原始URL,因此引入一个辅助函数,它返回原始标识URL和UUID,并在提交消息中生成元数据时使用它。

  1. svn.useSvnsyncProps
  1. svn-remote.<name>.useSvnsyncprops

与useSvmProps选项类似;这适用于随SVN 1.4.x及更高版本一起发布的svnsync(1)命令的用户。

  1. svn-remote.<name>.rewriteRoot

这允许用户从备用URL创建存储库。例如,管理员可以在本地服务器上运行 git svn (通过 file:// 访问)但希望使用公共http://或svn:/分发存储库/元数据中的URL,以便用户看到公共URL。

  1. svn-remote.<name>.rewriteUUID

与useSvmProps选项类似;这适用于需要手动重新映射UUID的用户。在通过useSvmProps或useSvnsyncProps无法使用原始UUID的情况下,这可能很有用。

  1. svn-remote.<name>.pushurl

与Git的remote.&lt;name&gt;.pushurl类似,此密钥设计用于 url 通过只读传输指向SVN存储库的情况,以提供备用读/写传输。假设两个键都指向同一个存储库。与 commiturl 不同, pushurl 是基本路径。如果可以使用 commiturlpushurlcommiturl 优先。

  1. svn.brokenSymlinkWorkaround

这会禁用可能昂贵的检查,以解决由损坏的客户端检入SVN的损坏的符号链接。如果跟踪具有许多非符号链接的空blob的SVN存储库,请将此选项设置为“false”。当 git svn 正在运行时,此选项可能会更改,并在下一个修订版本生效时生效。如果未设置, git svn 假定此选项为“true”。

  1. svn.pathnameencoding

这指示git svn将路径名重新编码为给定的编码。它可以被Windows用户和非utf8语言环境中的用户使用,以避免使用非ASCII字符损坏文件名。有效编码是Perl的Encode模块支持的编码。

  1. 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管理项目的主干(忽略标签和分支):

  1. # Clone a repo (like git clone):
  2. git svn clone http://svn.example.com/project/trunk
  3. # Enter the newly cloned directory:
  4. cd trunk
  5. # You should be on master branch, double-check with 'git branch'
  6. git branch
  7. # Do some work and commit locally to Git:
  8. git commit ...
  9. # Something is committed to SVN, rebase your local changes against the
  10. # latest changes in SVN:
  11. git svn rebase
  12. # Now commit your changes (that were committed previously using Git) to SVN,
  13. # as well as automatically updating your working HEAD:
  14. git svn dcommit
  15. # Append svn:ignore settings to the default Git exclude file:
  16. git svn show-ignore >> .git/info/exclude

跟踪并贡献整个Subversion管理的项目(包括主干,标签和分支):

  1. # Clone a repo with standard SVN directory layout (like git clone):
  2. git svn clone http://svn.example.com/project --stdlayout --prefix svn/
  3. # Or, if the repo uses a non-standard directory layout:
  4. git svn clone http://svn.example.com/project -T tr -b branch -t tag --prefix svn/
  5. # View all branches and tags you have cloned:
  6. git branch -r
  7. # Create a new branch in SVN
  8. git svn branch waldo
  9. # Reset your master to trunk (or any other branch, replacing 'trunk'
  10. # with the appropriate name):
  11. git reset --hard svn/trunk
  12. # You may only dcommit to one branch/tag/trunk at a time. The usage
  13. # of dcommit/rebase/show-ignore should be the same as above.

最初的 git svn clone 可能非常耗时(特别是对于大型Subversion存储库)。如果多个人(或一个拥有多台机器的人)想要使用 git svn 与同一个Subversion存储库进行交互,您可以将初始 git svn clone 作为服务器上的存储库让每个人用 git clone 克隆该存储库:

  1. # Do the initial import on a server
  2. ssh server "cd /pub && git svn clone http://svn.example.com/project [options...]"
  3. # Clone locally - make sure the refs/remotes/ space matches the server
  4. mkdir project
  5. cd project
  6. git init
  7. git remote add origin server:/pub/project
  8. git config --replace-all remote.origin.fetch '+refs/remotes/*:refs/remotes/*'
  9. git fetch
  10. # Prevent fetch/pull from remote Git server in the future,
  11. # we only want to use git svn for future updates
  12. git config --remove-section remote.origin
  13. # Create a local branch from one of the branches just fetched
  14. git checkout -b master FETCH_HEAD
  15. # Initialize 'git svn' locally (be sure to use the same URL and
  16. # --stdlayout/-T/-b/-t/--prefix options as were used on server)
  17. git svn init http://svn.example.com/project [options...]
  18. # Pull the latest changes from Subversion
  19. git svn rebase

REBASE VS. PULL / MERGE

更喜欢使用 git svn rebasegit rebase ,而不是 git pullgit merge 来同步未整合的提交与 git svn 分支。这样做将使未集成提交的历史相对于上游SVN存储库保持线性,并允许使用首选 git svn dcommit 子命令将未集成的提交推送回SVN。

最初, git svn 建议开发人员从 git svn 分支中撤出或合并。这是因为作者赞成git svn set-tree B提交单个头而不是git svn set-tree A..B符号来提交多个提交。使用 git pullgit mergegit 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提交。这由消息“初始化父:< branchname>”表示。

此外,它将创建一个名为< branchname> @< SVN-Revision>的特殊分支。 ,其中< SVN-Revision>是从中复制分支的SVN修订版号。该分支将指向新创建的分支的父提交。如果在SVN中分支被删除并且稍后从不同版本重新创建,则将存在多个具有 @ 的分支。

请注意,这可能意味着为单个SVN修订创建了多个Git提交。

例如:在具有标准中继/标签/分支布局的SVN存储库中,在r.100中创建目录中继/子。在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 /的提交)。

CAVEATS

为了简单和与Subversion互操作,建议所有 git svn 用户直接从SVN服务器克隆,获取和提交,并避免所有 git clone / / 合并 / 推送 Git存储库和分支之间的操作。在Git分支和用户之间交换代码的推荐方法是 git format-patchgit am ,或者只是’dcommit’ing到SVN存储库。

在您计划 dcommit 的分支上不建议运行 git mergegit pull ,因为Subversion用户无法看到您所做的任何合并。此外,如果您从作为SVN分支镜像的Git分支合并或拉出, dcommit 可能会提交错误的分支。

如果你合并,请注意以下规则: git svn dcommit 将尝试在名为的SVN提交之上提交

  1. git log --grep=^git-svn-id: --first-parent -1

必须因此确保你想要提交的分支的最新提交是合并的第一父。否则会发生混乱,特别是如果第一个父级是同一SVN分支上的较旧提交。

git clone 不会在refs / remotes / hierarchy或任何 git svn 元数据或config下克隆分支。所以使用 git svn 创建和管理的存储库应该使用 rsync 进行克隆,如果要完成克隆的话。

由于 dcommit 内部使用rebase,任何Git分支你 git pushdcommit 之前将需要强制覆盖远程存储库上的现有ref。这通常被认为是不好的做法,详见 git-push [1] 文档。

对于您已经提交的更改,请勿使用 git-commit [1] 的—amend选项。将 - 已经推送到其他用户的远程存储库提交的提交视为不好的做法,并且与SVN的命令类似于此。

克隆SVN存储库时,如果没有使用描述存储库布局的选项(—trunk, - targs, - .branches, - stdlayout), git svn clone 将创建一个Git存储库具有完全线性历史记录,其中分支和标记在工作副本中显示为单独的目录。虽然这是获取完整存储库副本的最简单方法,但对于具有多个分支的项目,它将导致工作副本比主干大许多倍。因此,对于使用标准目录结构(主干/分支/标签)的项目,建议使用选项--stdlayout进行克隆。如果项目使用非标准结构,和/或不需要分支和标记,则最简单的方法是仅克隆一个目录(通常是主干),而不提供任何存储库布局选项。如果需要带分支和标签的完整历史记录,则必须使用选项--trunk / --branches / --tags

当使用多个 - 分支或—tags时, git svn 不会自动处理名称冲突(例如,如果来自不同路径的两个分支具有相同的名称,或者分支和标记具有相同的名称冲突名称)。在这些情况下,使用 init 设置你的Git存储库然后,在你的第一个 fetch 之前,编辑$ GIT_DIR / config文件,以便分支和标签与不同的名称空间相关联。例如:

  1. branches = stable/*:refs/remotes/svn/stable/*
  2. branches = debug/*:refs/remotes/svn/debug/*

BUGS

我们忽略除svn:executable之外的所有SVN属性。任何未处理的属性都会记录到$ GIT_DIR / svn /< refname> /unhandled.log

Git未检测到重命名和复制的目录,因此在提交SVN时不会进行跟踪。我不打算为此添加支持,因为为所有可能的极端情况工作是非常困难和耗时的(Git也没有这样做)。如果它们足够相似,Git可以检测它们,则完全支持提交重命名和复制的文件。

在SVN中,可以(虽然不鼓励)提交对标记的更改(因为标记只是目录副本,因此在技术上与分支相同)。克隆SVN存储库时, git svn 无法知道将来是否会发生对标记的提交。因此它保守地运作并将所有SVN标签作为分支导入,在标签名称前加上标签/

组态

git svn 将[svn-remote]配置信息存储在存储库$ GITDIR / config文件中。它类似于核心Git [remote]部分,除了 _fetch 键不接受glob参数;但它们由分支标签键处理。由于某些SVN存储库奇怪地配置了多个项目,因此允许使用以下列出的扩展:

  1. [svn-remote "project-a"]
  2. url = http://server.org/svn
  3. fetch = trunk/project-a:refs/remotes/project-a/trunk
  4. branches = branches/*/project-a:refs/remotes/project-a/branches/*
  5. branches = branches/release_*:refs/remotes/project-a/branches/release_*
  6. branches = branches/re*se:refs/remotes/project-a/branches/*
  7. tags = tags/*/project-a:refs/remotes/project-a/tags/*

请记住,本地参考的 * (星号)通配符(的右侧)必须是最右边的路径组件;但是远程通配符可以是任何地方,只要它是一个独立的路径组件(由 / 或EOL包围)。这种类型的配置不是由 init 自动创建的,应该使用文本编辑器或使用 git config 手动输入。

另请注意,每个单词只允许使用一个星号。例如:

  1. branches = branches/re*se:refs/remotes/project-a/branches/*

将匹配分支释放研究re123se ,但

  1. branches = branches/re*s*e:refs/remotes/project-a/branches/*

会产生错误。

也可以通过在大括号内使用逗号分隔的名称列表来获取分支或标记的子集。例如:

  1. [svn-remote "huge-project"]
  2. url = http://server.org/svn
  3. fetch = trunk/src:refs/remotes/trunk
  4. branches = branches/{red,green}/src:refs/remotes/project-a/branches/*
  5. tags = tags/{1.0,2.0}/src:refs/remotes/project-a/tags/*

支持多个提取,分支和标记键:

  1. [svn-remote "messy-repo"]
  2. url = http://server.org/svn
  3. fetch = trunk/project-a:refs/remotes/project-a/trunk
  4. fetch = branches/demos/june-project-a-demo:refs/remotes/project-a/demos/june-demo
  5. branches = branches/server/*:refs/remotes/project-a/branches/*
  6. branches = branches/demos/2011/*:refs/remotes/project-a/2011-demos/*
  7. tags = tags/server/*:refs/remotes/project-a/tags/*

在这样的配置中创建分支需要使用-d或—destination标志消除使用哪个位置的歧义:

  1. $ git svn branch -d branches/server release-2-3-0

请注意,git-svn会跟踪分支或标记出现的最高版本。如果在获取后更改了分支或标记的子集,则必须手动编辑$ GIT_DIR / svn / .metadata以根据需要删除(或重置)branches-maxRev和/或tags-maxRev。

FILES

  1. $GIT_DIR/svn/*\*/.rev_map.*

Subversion修订号和Git提交名之间的映射。在未设置noMetadata选项的存储库中,可以从每次提交结束时的git-svn-id:行重建(有关详细信息,请参阅上面的 svn.noMetadata 部分)。

git svn fetchgit svn rebase 会自动更新revmap,如果它丢失或不是最新的。 _git svn reset 自动倒带。

也可以看看

git-rebase [1]

GIT

部分 git [1] 套件