chiark / gitweb /
wip more merge driver
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 21 Jan 2012 11:40:05 +0000 (11:40 +0000)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sat, 21 Jan 2012 11:40:05 +0000 (11:40 +0000)
DESIGN
topbloke-merge-driver [new file with mode: 0755]
topbloke-merge-lists [new file with mode: 0755]

diff --git a/DESIGN b/DESIGN
index 23d5a16..f68272b 100644 (file)
--- a/DESIGN
+++ b/DESIGN
@@ -143,6 +143,13 @@ Branch removal:
  undeleting
    - just unmark the branch as deleted
 
+
+Foreign branches:
+ When merging from a foreign dependency, check that it
+ does not have .topbloke/included or .topbloke/flags; if it
+ does, could produce a new commit which has .topbloke removed
+ and merge from that
+
 Branch naming:
  needs to be globally unique
  so put email address in it
diff --git a/topbloke-merge-driver b/topbloke-merge-driver
new file mode 100755 (executable)
index 0000000..c90680e
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/sh
+set -e
+
+fail () { echo >&2 "$0: $*"; exit 127; }
+
+case "$1" in
+--v1) on=tip ;;
+--base-v1) on=base ;;
+*) fail "bad usage" ;;
+esac
+
+whichfile=$1
+ancestor=$2
+current=$3
+other=$4
+markersize=$5
+
+case $on.$whichfile in
+tip.msg)
+       exec git-merge-file --marker-size=$markersize \
+               "$current" "$ancestor" "$other"
+       ;;
+base.msg|base.deps)
+       echo '# not applicable' >"$current"
+       exit 0
+       ;;
+*.included|tip.deps|tip.flags)
+       exec topbloke-merge-lists "$current" "$ancestor" "$other"
+       ;;
+base.flags)
+       exec topbloke-merge-lists -UDeleted \
+               "$current" "$ancestor" "$other"
+       ;;
+*)
+       fail "huh $on $whichfile ?"
+       ;;
+esac
diff --git a/topbloke-merge-lists b/topbloke-merge-lists
new file mode 100755 (executable)
index 0000000..42737e0
--- /dev/null
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use IO::Handle;
+
+our %flag;
+our @order, @order_final_maybe;
+
+while (@ARGV && $ARGV[0] =~ m/^\-/) {
+    $_ = shift @ARGV;
+    if (s/^-U//) {
+       $flag{$_}{Result} = 0;
+       push @order_final_maybe, $_;
+    } elsif (s/^-D//) {
+       $flag{$_}{Result} = 1;
+       push @order_final_maybe, $_;
+    } elsif (m/^--$/) {
+       last;
+    } else {
+       die "$0: bad option\n";
+    }
+}
+
+@ARGV==3 or die "$0: bad usage\n";
+
+foreach my $ix (qw(0 1 2)) {
+    open F, '<', $ARGV[$ix] or die "$ix $!";
+    while (<F>) {
+       chomp or die;
+       $flag{$_}{Input}[$ix] = 1;
+       my $ff = $flag{$_};
+       push @order, $_ unless $ff->{InOrder}++;
+    }
+    F->error and die $!;
+    close F or die $!;
+}
+
+foreach $_ (@order_final_maybe) {
+    push @order, $_ unless $flags{$_}{InOrder}++;
+}
+
+open O, '>', "$current.tmp" or die "$current.tmp $!";
+
+foreach $_ (@order) {
+    my $ff = $flag{$_};
+    if (!defined $ff->{Result}) {
+       my $s = '';
+       foreach my $ix (qw(0 1 2)) {
+           $ff->{Input}[$ix] ||= 1;
+           $s .= $ff->{Input}[$ix];
+       }
+       $ff->{Result} =
+           $s eq '000' ? '000' :
+           $s eq '111' ? '111' :
+           $ff->{Input}[1];
+    }
+    if ($ff->{Result}) {
+       print O "$_\n" or die $!;
+    }
+}
+
+close O or die $!;
+rename "$current.tmp", "$current" or die "$current $!";
+exit 0;