问题
I am using git-svn to work with a svn repository. The git master
branch is mirroring the svn trunk
branch (the only svn branch in use), i.e. there is a one to one relation between elements on the master branch and the trunk branch.
I want to have git tags that corresponds to svn revisions, so that I can do things like for instance git diff r123 workbranch
to see what I have done compared to svn revision 123.
The revisions are not tagged when I do git svn rebase
, so I have created the following script that I run post 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(@_);
}
This script gets the job done, but I have to run it manually every time, and I have (arbitrarily) capped it at checking the last 21 revisions so there is a theoretical risk of missing some (but I will see that from the printing).
The question: Is there any way I can automate this so that I just run git svn rebase
and all imported revisions will be tagged in git? Any hooks I can use?
PS
Yes, I am aware of svn find-rev, but I want in absolutely no way having to write commands as complicated as git diff $(git svn find-rev r123) $(git svn find-rev r124)
instead of just git diff r123 r124
.
回答1:
Here's a crazy idea: Trap bash
commands and automatically replace any r1234
strings with SHA hashes:
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
回答2:
Short Answer and Caveats
There is not a way to hook the git svn rebase
command that I'm aware of (or git svn dcommit
).
What you can do is use the post-rebase
hook. However, this is only invoked when the history is actually updated by the rebase -- if you run git svn rebase
and there's no new SVN commits that affect the current Git branch, no changes will take effect.
Ensure You Used --stdlayout
With regard to creating Git tags for SVN tags in a single command, if you did not originally clone the repository with...
git svn clone --stdlayout
I would recommend that you re-clone the repository. This will make your life much easier.
Telling Git About New SVN Tags
To tell Git about new SVN tags and branches, use the command git svn fetch --all
. The command git svn rebase --fetch-all
also performs this action.
Automatically git tag
all SVN tags
In order to convert thse newly-fetched SVN tags into Git tags, one way is to just walk the the references.
#!/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
Put this file as .git/hooks/post-rebase
.
来源:https://stackoverflow.com/questions/13740165/git-svn-automatically-importing-creating-svn-revisions-as-git-tags