summaryrefslogtreecommitdiffstats
path: root/bin/git
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2011-11-09 10:49:25 -0600
committerJesse Luehrs <doy@tozt.net>2011-11-09 10:50:19 -0600
commitbb79169c4eba10c11cff5317a50bc3aa41f8526b (patch)
tree63d3e972ab1fd39632a752faf324e246d31e3422 /bin/git
parent907bbc3cadb92257dae15e80230c204364ee9578 (diff)
downloadconf-bb79169c4eba10c11cff5317a50bc3aa41f8526b.tar.gz
conf-bb79169c4eba10c11cff5317a50bc3aa41f8526b.zip
add nothingmuch's git-svn-abandon scripts
Diffstat (limited to 'bin/git')
-rwxr-xr-xbin/git/git-svn-abandon-cleanup16
-rwxr-xr-xbin/git/git-svn-abandon-fix-refs63
-rwxr-xr-xbin/git/git-svn-abandon-msg-filter52
3 files changed, 131 insertions, 0 deletions
diff --git a/bin/git/git-svn-abandon-cleanup b/bin/git/git-svn-abandon-cleanup
new file mode 100755
index 0000000..2e2a547
--- /dev/null
+++ b/bin/git/git-svn-abandon-cleanup
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+# strip svk and git-svn noise, retaining tags
+git filter-branch --tag-name-filter cat --msg-filter "git svn-abandon-msg-filter" -- --all
+
+# remove the backup refs
+git for-each-ref --format='%(refname)' refs/original/ refs/remotes/svn/ | while read ref; do
+ git update-ref -d "$ref"
+done
+
+# ditch all pre-conversion objects forcefully
+git reflog expire --all --expire=now
+git gc --aggressive
+
+git prune
+git fsck --full
diff --git a/bin/git/git-svn-abandon-fix-refs b/bin/git/git-svn-abandon-fix-refs
new file mode 100755
index 0000000..c47405d
--- /dev/null
+++ b/bin/git/git-svn-abandon-fix-refs
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+# clean up working dir
+
+git update-ref -d master
+
+# create annotated tags out of svn tags
+git for-each-ref --format='%(refname)' refs/remotes/svn/tags/* | while read tag_ref; do
+ tag=${tag_ref#refs/remotes/svn/tags/}
+ tree=$( git rev-parse "$tag_ref": )
+
+ # find the oldest ancestor for which the tree is the same
+ parent_ref="$tag_ref";
+ while [ $( git rev-parse --quiet --verify "$parent_ref"^: ) = "$tree" ]; do
+ parent_ref="$parent_ref"^
+ done
+ parent=$( git rev-parse "$parent_ref" );
+
+ # if this ancestor is in trunk then we can just tag it
+ # otherwise the tag has diverged from trunk and it's actually more like a
+ # branch than a tag
+ merge=$( git merge-base "refs/remotes/svn/trunk" $parent );
+ if [ "$merge" = "$parent" ]; then
+ target_ref=$parent
+ else
+ echo "tag has diverged: $tag"
+ target_ref="$tag_ref"
+ fi
+
+ # create an annotated tag based on the last commit in the tag, and delete the "branchy" ref for the tag
+ git show -s --pretty='format:%s%n%n%b' "$tag_ref" | \
+ perl -ne 'next if /^git-svn-id:/; $s++, next if /^\s*r\d+\@.*:.*\|/; s/^ // if $s; print' | \
+ env GIT_COMMITTER_NAME="$( git show -s --pretty='format:%an' "$tag_ref" )" \
+ GIT_COMMITTER_EMAIL="$( git show -s --pretty='format:%ae' "$tag_ref" )" \
+ GIT_COMMITTER_DATE="$( git show -s --pretty='format:%ad' "$tag_ref" )" \
+ git tag -a -F - "$tag" "$target_ref"
+
+ git update-ref -d "$tag_ref"
+done
+
+# create local branches out of svn branches
+git for-each-ref --format='%(refname)' refs/remotes/svn/ | while read branch_ref; do
+ branch=${branch_ref#refs/remotes/svn/}
+ git branch "$branch" "$branch_ref"
+ git update-ref -d "$branch_ref"
+done
+
+# rename 'trunk' to 'master'
+git checkout trunk
+git branch -M trunk master
+
+# remove merged branches
+git for-each-ref --format='%(refname)' refs/heads | while read branch; do
+ git rev-parse --quiet --verify "$branch" || continue # make sure it still exists
+ git symbolic-ref HEAD "$branch"
+ git branch -d $( git branch --merged | grep -v '^\*' )
+done
+
+git checkout master
+
+# list possible merge commits to help create a grafts file
+git log --pretty=one --all -E --grep='[mM]erge|\(orig r'
+
diff --git a/bin/git/git-svn-abandon-msg-filter b/bin/git/git-svn-abandon-msg-filter
new file mode 100755
index 0000000..540b4c8
--- /dev/null
+++ b/bin/git/git-svn-abandon-msg-filter
@@ -0,0 +1,52 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+my $svn_id;
+my $msg = '';
+
+while (<>) {
+ if ( /^git-svn-id: (.*)/ ) {
+ $svn_id = $1;
+ } else {
+ $msg .= $_;
+ }
+}
+
+# if this is a merge commit, rewrite the message to have a better "subject"
+if ( $msg =~ /^\s*r\d+\@.*\(orig r\d+\):/ ) {
+ # print the original message
+ $msg =~ s/^ //mg;
+
+ my ( $to, @from ) = ( split /\s+/, `git show -s --pretty='format:%P' $ENV{GIT_COMMIT}` );
+
+ print "Merge ",
+ join(", ", map { format_branch($_) } @from),
+ " into ",
+ format_branch($to),
+ "\n\n",
+ $msg;
+} else {
+ if ( $msg =~ s/^\s*r\d+\@.*:.*$//m ) {
+ $msg =~ s/^ //mg;
+ }
+
+ print $msg;
+}
+
+sub format_branch {
+ my $commit = shift;
+
+ my $body = `git show -s --pretty='format:%b' $commit`;
+
+ if ( $body =~ m{git-svn-id: .*/branches/(.*?)\@} ) {
+ return "'$1'";
+ } elsif ( $body =~ m{git-svn-id: .*/trunk\@} ) {
+ return "'trunk'";
+ } elsif ( $body =~ /\@r(\d+)/ ) {
+ return $1;
+ } else {
+ die "unknown rev for $commit";
+ }
+}