Tags git svn:自动导入/创建svn修订作为git标记

Tags 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;

我正在使用git svn处理svn存储库。git
master
分支镜像了svn
trunk
分支(唯一正在使用的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

放在这里有一个疯狂的想法:Trap
bash
命令并自动用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
放入
案例
模式,因此它甚至会影响其他命令!