Git 中文参考(六)(4)https://developer.aliyun.com/article/1565805
高级选项
-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, - label, - blank, - 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-branch [1] 。 filter-branch 还允许重新格式化元数据,以便于阅读和重写非“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 的用户。在通过 useSvmProps 或 useSvnsyncProps 无法使用原始 UUID 的情况下,这可能很有用。
svn-remote.<name>.pushurl
与 Git 的remote..pushurl
类似,此密钥设计用于 url 通过只读传输指向 SVN 存储库的情况,以提供备用读/写传输。假设两个键都指向同一个存储库。与 commiturl 不同, pushurl 是基本路径。如果可以使用 commiturl 或 pushurl , commiturl 优先。
svn.brokenSymlinkWorkaround
这会禁用可能昂贵的检查,以解决由损坏的客户端检入 SVN 的损坏的符号链接。如果跟踪具有许多非符号链接的空 blob 的 SVN 存储库,请将此选项设置为“false”。当 git svn 正在运行时,此选项可能会更改,并在下一个修订版本生效时生效。如果未设置, git svn 假定此选项为“true”。
svn.pathnameencoding
这指示 git svn 将路径名重新编码为给定的编码。它可以被 Windows 用户和非 utf8 语言环境中的用户使用,以避免使用非 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 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 VS. 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 提交。这由消息“初始化父:< 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-patch 和 git am ,或者只是’dcommit’ing 到 SVN 存储库。
在您计划 dcommit 的分支上不建议运行 git merge 或 git pull ,因为 Subversion 用户无法看到您所做的任何合并。此外,如果您从作为 SVN 分支镜像的 Git 分支合并或拉出, dcommit 可能会提交错误的分支。
如果你合并,请注意以下规则: git svn dcommit 将尝试在名为的 SVN 提交之上提交
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 push 到 dcommit 之前将需要强制覆盖远程存储库上的现有 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 文件,以便分支和标签与不同的名称空间相关联。例如:
branches = stable/*:refs/remotes/svn/stable/* 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]配置信息存储在存储库$ GIT_DIR / config 文件中。它类似于核心 Git [remote]部分,除了 fetch 键不接受 glob 参数;但它们由 _ 分支 _ 和 _ 标签 _ 键处理。由于某些 SVN 存储库奇怪地配置了多个项目,因此允许使用以下列出的扩展:
[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/*
请记住,本地参考的 * (星号)通配符(: 的右侧)必须是最右边的路径组件;但是远程通配符可以是任何地方,只要它是一个独立的路径组件(由 / 或 EOL 包围)。这种类型的配置不是由 init 自动创建的,应该使用文本编辑器或使用 git config 手动输入。
另请注意,每个单词只允许使用一个星号。例如:
branches = branches/re*se:refs/remotes/project-a/branches/*
将匹配分支 _ 释放 , 研究 _, 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/*
支持多个提取,分支和标记键:
[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。
FILES
$GIT_DIR/svn/*\*/.rev_map.*
Subversion 修订号和 Git 提交名之间的映射。在未设置 noMetadata 选项的存储库中,可以从每次提交结束时的 git-svn-id:行重建(有关详细信息,请参阅上面的 svn.noMetadata 部分)。
git svn fetch 和 git svn rebase 会自动更新 rev_map,如果它丢失或不是最新的。 git svn reset 自动倒带。
也可以看看
GIT
部分 git [1] 套件
git-fast-import
名称
git-fast-import - 快速 Git 数据导入器的后端
概要
frontend | git fast-import [<options>]
描述
该程序通常不是最终用户想要直接运行的程序。大多数最终用户希望使用现有的前端程序之一,该程序解析特定类型的外部源并将存储在那里的内容提供给 git fast-import 。
fast-import 从标准输入读取混合命令/数据流,并将一个或多个 packfiles 直接写入当前存储库。在标准输入上收到 EOF 时,快速导入会写出更新的分支和标记引用,使用新导入的数据完全更新当前存储库。
快速导入后端本身可以导入到空存储库(已经由 git init 初始化的存储库)或者逐步更新现有的已填充存储库。是否支持来自特定外部源的增量导入取决于正在使用的前端程序。
OPTIONS
--force
强制更新已修改的现有分支,即使这样做会导致提交丢失(因为新提交不包含旧提交)。
--quiet
禁用–stats 显示的输出,快速导入通常在成功时保持静默。但是,如果导入流具有旨在显示用户输出的指令(例如progress
指令),则仍将显示相应的消息。
--stats
显示有关快速导入已创建的对象,存储它们的包文件以及在此运行期间快速导入所使用的内存的一些基本统计信息。显示此输出目前是默认值,但可以使用–quiet 禁用。
前端的选项
--cat-blob-fd=<fd>
将对get-mark
,cat-blob
和ls
查询的响应写入文件描述符< fd>而不是stdout
。允许最终用户的progress
输出与其他输出分开。
--date-format=<fmt>
指定前端将在author
,committer
和tagger
命令中快速导入的日期类型。有关支持哪些格式及其语法的详细信息,请参阅下面的“日期格式”。
--done
如果流末尾没有done
命令,则终止并出错。此选项可用于检测导致前端在开始编写流之前终止的错误。
标记文件的位置
--export-marks=<file>
将内部标记表转储到< file>完成后。标记每行写为:markid SHA-1
。前端可以使用此文件在完成导入后验证导入,或者在增量运行中保存标记表。作为< file>仅在检查点(或完成)处打开和截断,同样的路径也可以安全地给予–import-marks。
--import-marks=<file>
在处理任何输入之前,请加载< file>中指定的标记。输入文件必须存在,必须是可读的,并且必须使用与–export-marks 生成的格式相同的格式。可以提供多个选项来导入多组标记。如果标记定义为不同的值,则最后一个文件获胜。
--import-marks-if-exists=<file>
像–import-marks 但不是错误输出,如果文件不存在,则以静默方式跳过该文件。
--[no-]relative-marks
指定–relative-marks 后,使用–import-marks =和–export-marks =指定的路径相对于当前存储库中的内部目录。在 git-fast-import 中,这意味着路径相对于.git / info / fast-import 目录。但是,其他进口商可能会使用其他位置。
相对和非相对标记可以通过交织 - (无 - ) - 相对标记与 - (import | export)-marks =选项相结合。
性能和压缩调整
--active-branches=<n>
一次保持活动的最大分支数。有关详细信息,请参阅下面的“内存使默认值为 5。
--big-file-threshold=<n>
快速导入将尝试创建增量的 blob 的最大大小,以字节为单位表示。默认值为 512 米(512 MiB)。一些进口商可能希望在具有受限内存的系统上降低此值。
--depth=<n>
最大增量深度,用于 blob 和树木划分。默认值为 50。
--export-pack-edges=<file>
创建包文件后,将一行数据打印到< file>列出 packfile 的文件名以及写入该 packfile 的每个分支上的最后一次提交。导入总对象集超过 4 GiB packfile 限制的项目后,此信息可能很有用,因为这些提交可以在调用 git pack-objects 时用作边缘点。
--max-pack-size=<n>
每个输出包文件的最大大小。默认值是无限制的。
fastimport.unpackLimit
Git 中文参考(六)(6)https://developer.aliyun.com/article/1565807