]> git.donarmstrong.com Git - bin.git/blobdiff - svnmerge
add svnmerge and update stodo to work remotely
[bin.git] / svnmerge
diff --git a/svnmerge b/svnmerge
new file mode 100755 (executable)
index 0000000..bc39922
--- /dev/null
+++ b/svnmerge
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+# Uses symlinks to merge the files contained in a set of subversion
+# checkouts to into a single directory. Keeps track of when files are
+# removed from the merged directories and removes the symlinks.
+#
+# Only merges files that match the specified pattern.
+#
+# Note that the directories given to merge should be paths that will work
+# for symlink targets from the destination directory (so either full paths,
+# or they should be right inside the destination directory).
+#
+# Note that other files in the destination directory will be left as-is.
+#
+# Copyright 2006 by Joey Hess, licensed under the GPL.
+
+if (! @ARGV) {
+       die "usage: svnmerge include-pattern dest dir1 [dir2 ...]\n";
+}
+
+my $pattern=shift;
+my $dest=shift;
+
+foreach my $dir (@ARGV) {
+     my %known;
+
+     # Link in each thing from the dir.
+     opendir(DIR, $dir) || die "opendir: $!";
+     while ($_=readdir(DIR)) {
+         next if $_ eq '.' || $_ eq '..' || $_ eq 'known' || $_ eq '.svn';
+         next unless /$pattern/;
+
+         $known{$_}=1;
+
+         if (! -l "$dest/$_" && -e "$dest/$_") {
+              print STDERR "$_ in $dir is also in $dest\n";
+         }
+         elsif (! -l "$dest/$_") {
+              system("ln", "-svf", "$dir/$_", $dest);
+         }
+     }
+     closedir(DIR);
+
+     # Remove anything that was previously linked in but is not in the
+     # dir anymore.
+     if (-e "$dir/known") {
+         open(KNOWN, "$dir/known") || die "open $dir/known: $!";
+         while (<KNOWN>) {
+              chomp;
+              if (! $known{$_}) {
+                   system("rm", "-vf", "$dest/$_");
+              }
+         }
+         close KNOWN;
+     }
+
+     # Save state for next time.
+     open(KNOWN, ">$dir/known") || die "write $dir/known: $!";
+     foreach my $file (sort keys %known) {
+         print KNOWN "$file\n";
+     }
+     close KNOWN;
+}