#!/usr/bin/perl
#
# Copyright 2005, Ryan Anderson <ryan@michonline.com>
#                 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
#
# This file is licensed under the GPL v2, or a later version
# at the discretion of Linus Torvalds.


use warnings;
use strict;
use Getopt::Std;

sub usage() {
	print <<EOT;
$0 [-f] [-n] <source> <dest>
$0 [-f] [-k] [-n] <source> ... <dest directory>

In the first form, source must exist and be either a file,
symlink or directory, dest must not exist. It renames source to dest.
In the second form, the last argument has to be an existing
directory; the given sources will be moved into this directory.

Updates the git cache to reflect the change.
Use "git commit" to make the change permanently.

Options:
  -f   Force renaming/moving, even if target exists
  -k   Continue on error by skipping
       not-existing or not revision-controlled source
  -n   Do nothing; show what would happen
EOT
	exit(1);
}

# Sanity checks:
my $GIT_DIR = $ENV{'GIT_DIR'} || ".git";

unless ( -d $GIT_DIR && -d $GIT_DIR . "/objects" && 
	-d $GIT_DIR . "/objects/" && -d $GIT_DIR . "/refs") {
    print "Git repository not found.";
    usage();
}


our ($opt_n, $opt_f, $opt_h, $opt_k, $opt_v);
getopts("hnfkv") || usage;
usage() if $opt_h;
@ARGV >= 1 or usage;

my (@srcArgs, @dstArgs, @srcs, @dsts);
my ($src, $dst, $base, $dstDir);

my $argCount = scalar @ARGV;
if (-d $ARGV[$argCount-1]) {
	$dstDir = $ARGV[$argCount-1];
	# remove any trailing slash
	$dstDir =~ s/\/$//;
	@srcArgs = @ARGV[0..$argCount-2];
	
	foreach $src (@srcArgs) {
		$base = $src;
		$base =~ s/^.*\///;
		$dst = "$dstDir/". $base;
		push @dstArgs, $dst;
	}
}
else {
    if ($argCount != 2) {
	print "Error: moving to directory '"
	    . $ARGV[$argCount-1]
	    . "' not possible; not exisiting\n";
	usage;
    }
    @srcArgs = ($ARGV[0]);
    @dstArgs = ($ARGV[1]);
    $dstDir = "";
}

my (@allfiles,@srcfiles,@dstfiles);
my $safesrc;
my (%overwritten, %srcForDst);

$/ = "\0";
open(F,"-|","git-ls-files","-z")
        or die "Failed to open pipe from git-ls-files: " . $!;

@allfiles = map { chomp; $_; } <F>;
close(F);


my ($i, $bad);
while(scalar @srcArgs > 0) {
    $src = shift @srcArgs;
    $dst = shift @dstArgs;
    $bad = "";

    if ($opt_v) {
	print "Checking rename of '$src' to '$dst'\n";
    }

    unless (-f $src || -l $src || -d $src) {
	$bad = "bad source '$src'";
    }

    $overwritten{$dst} = 0;
    if (($bad eq "") && -e $dst) {
	$bad = "destination '$dst' already exists";
	if (-f $dst && $opt_f) {
	    print "Warning: $bad; will overwrite!\n";
	    $bad = "";
	    $overwritten{$dst} = 1;
	}
    }
    
    if (($bad eq "") && ($src eq $dstDir)) {
	$bad = "can not move directory '$src' into itself";
    }

    if ($bad eq "") {
	$safesrc = quotemeta($src);
	@srcfiles = grep /^$safesrc(\/|$)/, @allfiles;
        if (scalar @srcfiles == 0) {
	    $bad = "'$src' not under version control";
	}
    }

    if ($bad eq "") {
       if (defined $srcForDst{$dst}) {
           $bad = "can not move '$src' to '$dst'; already target of ";
           $bad .= "'".$srcForDst{$dst}."'";
       }
       else {
           $srcForDst{$dst} = $src;
       }
    }

    if ($bad ne "") {
	if ($opt_k) {
	    print "Warning: $bad; skipping\n";
	    next;
	}
	print "Error: $bad\n";
	usage();
    }
    push @srcs, $src;
    push @dsts, $dst;
}

# Final pass: rename/move
my (@deletedfiles,@addedfiles,@changedfiles);
while(scalar @srcs > 0) {
    $src = shift @srcs;
    $dst = shift @dsts;

    if ($opt_n || $opt_v) { print "Renaming $src to $dst\n"; }
    if (!$opt_n) {
	rename($src,$dst)
	    or die "rename failed: $!";
    }

    $safesrc = quotemeta($src);
    @srcfiles = grep /^$safesrc(\/|$)/, @allfiles;
    @dstfiles = @srcfiles;
    s/^$safesrc(\/|$)/$dst$1/ for @dstfiles;

    push @deletedfiles, @srcfiles;
    if (scalar @srcfiles == 1) {
	if ($overwritten{$dst} ==1) {
	    push @changedfiles, $dst;
	} else {
	    push @addedfiles, $dst;
	}
    }
    else {
	push @addedfiles, @dstfiles;
    }
}

if ($opt_n) {
	print "Changed  : ". join(", ", @changedfiles) ."\n";
	print "Adding   : ". join(", ", @addedfiles) ."\n";
	print "Deleting : ". join(", ", @deletedfiles) ."\n";
	exit(1);
}
	
my $rc;
if (scalar @changedfiles >0) {
	$rc = system("git-update-index","--",@changedfiles);
	die "git-update-index failed to update changed files with code $?\n" if $rc;
}
if (scalar @addedfiles >0) {
	$rc = system("git-update-index","--add","--",@addedfiles);
	die "git-update-index failed to add new names with code $?\n" if $rc;
}
$rc = system("git-update-index","--remove","--",@deletedfiles);
die "git-update-index failed to remove old names with code $?\n" if $rc;
