Tags git svn:自动导入/创建svn修订作为git标记
我正在使用git svn处理svn存储库。gitTags git svn:自动导入/创建svn修订作为git标记,tags,automation,git-svn,Tags,Automation,Git Svn,我正在使用git svn处理svn存储库。gitmaster分支镜像了svntrunk分支(唯一正在使用的svn分支),即主分支和主干分支上的元素之间存在一对一的关系 我希望有与svn修订版相对应的git标记,这样我就可以做一些事情,例如git diff r123 workbranch,查看与svn修订版123相比我做了些什么 当我执行git svn rebase时,修订没有标记,因此我创建了以下脚本,在svn rebase之后运行: #!/usr/bin/perl use strict;
master
分支镜像了svntrunk
分支(唯一正在使用的svn分支),即主分支和主干分支上的元素之间存在一对一的关系
我希望有与svn修订版相对应的git标记,这样我就可以做一些事情,例如git diff r123 workbranch
,查看与svn修订版123相比我做了些什么
当我执行git svn rebase
时,修订没有标记,因此我创建了以下脚本,在svn rebase之后运行:
#!/usr/bin/perl
use strict;
use warnings;
open(PIPE, "git log master |");
# Format for the pipe output:
# ...
# commit 6b24b8fdc6a25d35b01140dc1ac054697133423d
# ...
# git-svn-id: https://server.example.com/svn/project/trunk@594 164096ca-3471-41d1-a9ce-9541462a8c31
# ...
my $commit = "";
my $i = 0;
foreach my $line (<PIPE>) {
if ($line =~ /^commit ([\da-f]+)/) {
$commit = $1;
next;
}
next unless $line =~ /^\s+git-svn-id: .*\/trunk\@(\d+) /;
my $git_svn_id = $1;
run("git", "tag", "-f", "r$git_svn_id", $commit);
last if $i++ == 20;
}
close(PIPE);
sub run {
print join(' ', @_), "\n";
return system(@_);
}
#/usr/bin/perl
严格使用;
使用警告;
打开(管道,“git log master |”);
#管道输出的格式:
# ...
#提交6b24b8fdc6a25d35b01140dc1ac054697133423d
# ...
#git svn id:https://server.example.com/svn/project/trunk@594 164096ca-3471-41d1-a9ce-9541462a8c31
# ...
我的$commit=“”;
我的$i=0;
foreach我的$line(){
如果($line=~/^commit([\da-f]+)/){
$commit=$1;
下一个
}
下一步除非$line=~/^\s+git svn id:.\/trunk\@(\d+)/;
我的$git\u svn\u id=$1;
运行(“git”、“tag”、“-f”、“r$git\u svn\u id”、$commit);
如果$i++==20,则为最后一个;
}
关闭(管道);
分段{
打印联接(“”,@,\n);
返回系统(@);
}
这个脚本完成了任务,但每次我都必须手动运行它,并且我(任意地)在检查最后21个版本时限制了它,因此理论上有丢失一些版本的风险(但我将从打印中看到这一点)
问题:是否有任何方法可以自动执行此操作,以便只运行git svn rebase
,所有导入的修订都将在git中标记?有我能用的吗
PS
是的,我知道svn find rev,但我绝对不想编写像git diff$(git svn find rev r123)$(git svn find rev r124)
这样复杂的命令,而不仅仅是git diff r123 r124
简短的回答和注意事项
据我所知,没有办法钩住git svn rebase
命令(或git svn dcommit
)
您可以使用post-rebase
hook。但是,只有当rebase实际更新了历史记录时才会调用此函数——如果运行git svn rebase
,并且没有影响当前git分支的新svn提交,则任何更改都不会生效
确保使用了--stdlayout
关于在单个命令中为SVN标记创建Git标记,如果您最初没有使用
git svn克隆--stdlayout
我建议您重新克隆存储库。这会让你的生活更轻松
告诉Git新的SVN标签
要告诉Git新的SVN标记和分支,请使用命令Git SVN fetch--all
。git svn rebase--fetch all命令也执行此操作
自动git标记
所有SVN标记
为了将这些新获取的SVN标记转换为Git标记,一种方法是遍历引用
#!/bin/sh
git svn fetch --all &&
git for-each-ref refs/remotes/origin/tags |
while read ref
do
tagName=$(echo $ref | cut --delimiter / --fields=5)
git tag -f "$tagName" "refs/remotes/origin/tags/$ref"
done
将此文件作为
.git/hooks/post-rebase
放在这里有一个疯狂的想法:Trapbash
命令并自动用SHA哈希替换任何r1234
字符串:
shopt -s extdebug
enhance_rev_parse () {
[ -n "$COMP_LINE" ] && return # do nothing if completing
case "$BASH_COMMAND" in
*r[0-9]*)
eval $(echo "$BASH_COMMAND" | sed -e 's/r[0-9][0-9]*/$(git svn find-rev &)/g')
return 1
;;
esac
}
trap 'enhance_rev_parse' DEBUG
为什么这么难?如果你不喜欢写复杂的命令,你可以创建一个别名。-医生,我这样做时手臂会痛。-那就别那么做!在文档(,)和最新的git源代码中,我都找不到任何关于后重基钩子的引用。您是否以其他方式扩展了git?还要注意,我正在寻找导入svn修订版,而不是svn标签。这实际上是一种工作方式,但它有点像黑客和“泄漏”太多<例如,code>git标记-dr123将不起作用。而且我无法使用
git tag-l
获取列表,因为它们不是正确的标记。我甚至在测试后忘记将git
放入案例
模式,因此它甚至会影响其他命令!