summaryrefslogtreecommitdiff
path: root/bin/dircombine
diff options
context:
space:
mode:
authorJoerg Jaspert <joerg@debian.org>2008-09-27 22:22:44 +0200
committerJoerg Jaspert <joerg@debian.org>2008-09-27 22:22:44 +0200
commitcf9e1969ac3777edb2b12d2d821c24604db4408e (patch)
treeaa086273af8f0fa953ca3a8091c3fdcbe2127bdb /bin/dircombine
parentf4eb4ab8a597a0241d78918d9a8dae58b1fe7dc9 (diff)
dircombine
Add dircombine from joeyh Signed-off-by: Joerg Jaspert <joerg@debian.org>
Diffstat (limited to 'bin/dircombine')
-rw-r--r--bin/dircombine62
1 files changed, 62 insertions, 0 deletions
diff --git a/bin/dircombine b/bin/dircombine
new file mode 100644
index 0000000..e029c39
--- /dev/null
+++ b/bin/dircombine
@@ -0,0 +1,62 @@
+#!/usr/bin/perl
+# Uses symlinks to merge the files contained in a set of vcs
+# 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: dircombine 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' || $_ eq '.git' || $_ eq '.gitignore' || $_ eq '_darcs';
+ 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;
+}