summaryrefslogtreecommitdiff
path: root/bin/git-branchmove
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2019-05-03 14:01:53 -0700
committerSean Whitton <spwhitton@spwhitton.name>2019-05-03 15:43:12 -0700
commit7ec5c5de02388e412e7bd8fe9ce937d9827e3bf9 (patch)
treeda75f109e62930f9b170a48f35dab9d4e89665bf /bin/git-branchmove
parent8c7635593e5ef362cd5d03a634beb48ed99df785 (diff)
downloaddotfiles-7ec5c5de02388e412e7bd8fe9ce937d9827e3bf9.tar.gz
git-branchmove: code to attempt to detach the head
Diffstat (limited to 'bin/git-branchmove')
-rwxr-xr-xbin/git-branchmove53
1 files changed, 49 insertions, 4 deletions
diff --git a/bin/git-branchmove b/bin/git-branchmove
index fed28766..c59d936a 100755
--- a/bin/git-branchmove
+++ b/bin/git-branchmove
@@ -20,7 +20,7 @@
# This script is based on Ian Jackson's git-branchmove script, in the
# chiark-utils Debian source package. Ian's script assumes throughout
# that it is possible to have unrestricted shell access to the remote,
-# however, while this script avoids that assumption.
+# however, while this script avoids that global assumption.
#
# As much as possible we treat the remote argument as opaque, i.e., we
# don't distinguish between git URIs and named remotes. That means
@@ -94,6 +94,34 @@ die "git-branchmove: unknown operation\n"
# is this a named remote or a git URL?
my $named_remote = $remote =~ m|:| or $remote =~ m|^[/.]|;
+# Attempt to determine how we might be able to run commands in the
+# remote repo. This will only be used if we need to try to detach the
+# remote HEAD. These regexps are lifted from Ian's script
+my $rurl, my $rrune, my $rdir;
+if ($named_remote) {
+ $rurl = `git remote get-url --push $remote`;
+} else {
+ $rurl = $remote;
+}
+if ($rurl =~ m#^ssh://([^:/]+)(?:\:(\w+))?#) {
+ $rdir = "$'\''";
+ $rrune = "ssh ";
+ if ($2) {
+ $rrune .= " -p $3";
+ }
+ $rrune .= "$1";
+} elsif ($rurl =~ m#^([-+_.0-9a-zA-Z\@]+):(?!//|:)#) {
+ $rdir = "$'\''";
+ $rrune = "ssh $1";
+} elsif ($rurl =~ m#^[/.]#) {
+ $rdir = $rurl;
+ $rrune = undef;
+}
+
+# DEBUG
+print "dir is $rdir and rune is $rrune\n";
+exit 0;
+
# If we don't prefix the patterns, we might match branches the user
# doesn't intend. E.g. 'foo' would match 'wip/foo'
my @branch_pats = map { $_ =~ s|^|[r]efs/heads/|; $_ } @patterns;
@@ -134,9 +162,26 @@ if ($op eq "put") {
$source_head = (split /\s/, $lines[0])[1];
}
}
-die "git-branchmove: would delete checked-out branch $source_head"
- if (defined $source_head and
- grep /^$source_head$/, map {$_->{ref}} @source_branches);
+if (defined $source_head and
+ grep /^$source_head$/, map {$_->{ref}} @source_branches) {
+ if ($attempt_detach) {
+ if ($op eq 'put') {
+ $git->checkout('--detach');
+ } elsif ($op eq 'get') {
+ if (defined $rrune and defined $rdir) {
+ system "$rrune \"set -e; cd $rdir; git checkout --detach\""
+ or die "failed to detach remote HEAD";
+ } elsif (!defined $rrune and defined $rdir) {
+ my $dest_git = Git::Wrapper->new($rdir);
+ $dest_git->checkout('--detach');
+ } else {
+ die "git-branchmove: don't know how to detach remote HEAD";
+ }
+ }
+ } else {
+ die "git-branchmove: would delete checked-out branch $source_head";
+ }
+}
# check whether we would overwrite anything
foreach my $source_branch (@source_branches) {