3

我正在使用 git-svn 来处理 svn 存储库。gitmaster分支正在镜像 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(@_);
}

这个脚本完成了工作,但是我每次都必须手动运行它,并且我(任意)在检查最后 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.

4

2 回答 2

1

这是一个疯狂的想法:陷阱bash命令并自动r1234用 SHA 哈希替换任何字符串:

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
于 2013-02-28T00:29:40.583 回答
0

简答和注意事项

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

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

确保您使用过--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.

于 2013-02-26T22:49:54.023 回答