git-svn:自动导入/创建svn版本作为git标签

时间:2012-12-06 09:04:27

标签: tags automation git-svn

我正在使用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(@_);
}

这个脚本完成了工作,但我必须每次都手动运行它,并且我已经(任意)限制它检查最后21个修订版,因此理论上有一些错过的风险(但我会从印刷)。

问题:我有什么方法可以自动执行此操作,以便我只运行git svn rebase并且所有导入的修订都将在git中标记?我可以使用任何hooks吗?

PS 是的,我知道svn find-rev,但我绝对不希望编写像git diff $(git svn find-rev r123) $(git svn find-rev r124)那样复杂的命令,而不仅仅是git diff r123 r124

2 个答案:

答案 0 :(得分:1)

这是一个疯狂的想法:陷阱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

答案 1 :(得分:0)

简答和警告

没有办法挂钩我知道的git svn rebase命令(或git svn dcommit)。

可以做的是使用post-rebase挂钩。但是,只有当历史记录实际由rebase更新时才会调用此方法 - 如果运行git svn rebase并且没有新的SVN提交会影响当前的Git分支,则任何更改都不会生效。

确保您使用--stdlayout

关于在单个命令中为SVN标记创建Git标记,如果您最初没有使用...克隆存储库

git svn clone --stdlayout

我建议您重新克隆存储库。这将使您的生活更轻松。

告诉Git关于 SVN标签

要告诉Git有关新的SVN标记和分支,请使用命令git svn fetch --all。命令git svn rebase --fetch-all也执行此操作。

自动git tag所有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