#!/usr/bin/perl -w
# The GIT scripted toolkit - in perl
# Copyright (c) Petr Baudis, 2005
# Copyright (c) David Greaves, 2005
#
# This is the central command for the GIT toolkit, providing a humanly
# usable SCM-like interface to GIT.
#
# This command mostly only multiplexes to the individual script based
# on the first argument.

# generalised usage:
# git [options] command [command options] [command args]

use Pod::Usage;        # Lets see if we can have a consistent form of
                       # documenting what we do that can also be
                       # extracted automatically
use English;           # Reduce obfuscation (nb performance hit on
                       # regexps may be an issue one day)

use File::Basename;

use lib ("".dirname($0));  # For now add the git executable dir to lib

use Cogito;


# This quietly tries to handle any changes to the repository format
perform_fixups();

# Set up standard initialisation variables
our $repo = ".git";
our $verbose = 1 ; # set using prefs??

execute_commands();

exit;

sub execute_commands
  {
    # FIX: Process any intermediate args (eg --verbose?)
    my $cmd = shift @ARGV;

    help(-msg=>"git: missing command", -exitval=>1, -verbose=>1)
      if !$cmd;

  COMMAND: for ($cmd) {
      /^add$/ && do {
	require "gitadd.pl";
	add(@ARGV);
	last COMMAND;
      };

      /^(addremote|apply|cancel|commit|diff|export|fork|
         init|log|ls|lsobj|lsremote|merge|pull|status|
         tag|track|version)$/x && do {
	system("git$1.sh ".join(' ',@ARGV));
	last COMMAND;
      };

      /^help$/ && do {
	$cmd = shift @ARGV;
	if ($cmd) { # is this git help <command>
	  error("help $cmd - not supported until all commands take --help");
	  exit(1);
	  unshift @ARGV,"--help";
	  unshift @ARGV,$cmd;
	  execute_commands(@ARGV);
	} else {
	  pod2usage(-verbose=>1, -exitval=>0);
	}
	last COMMAND;
      };

      pod2usage(-msg=>"unknown command: $cmd", -exitval=>1, -verbose=>2);
    }
  }


sub perform_fixups
  {
    ### XXX: Compatibility hack.
    # Introduced at 2005-04-12, to be removed few days later.
    if (-d '.dircache'&& ! -e '.git') {
      system("mv .dircache .git");
    }

    # Introduced at 2005-04-13:
    if (-d '.git' && ! -d '.git/heads') {
      system("mkdir .git/heads");
      for $h (glob '.git/HEAD.*') {
	if ( $h ne "local") {
	  my (undef, undef, $i) = split("\.",$h);
	  system ("mv $h .git/heads/$i");
	}
      }
    }
    # Introduced at 2005-04-16:
    if ( -d '.git' &&  ! -e '.git/heads/master') {
      system("mv .git/HEAD .git/heads/master");
      system("ln -s heads/master .git/HEAD");
    }
  }

__END__

=head1 git

The GIT scripted toolkit  $(gitversion.sh)

=head1 SYNOPSIS

Usage: git COMMAND [ARG]...

=head1 OPTIONS

Available commands:

	add		FILE...
	addremote	RNAME RSYNC_URL
	apply				< patch on stdin
	cancel
	ci, commit	[FILE]...	< log message on stdin
	diff		[-p] [-r FROM_ID[:TO_ID]] [FILE]...
	export		DESTDIR [TREE_ID]
	fork		BNAME BRANCH_DIR [COMMIT_ID]
	help
	init		RSYNC_URL
	log
	ls		[TREE_ID]
	lsobj		[OBJTYPE]
	lsremote
	merge		[-c] [-b BASE_ID] FROM_ID
	pull		[RNAME]
	rm		FILE...
	seek		[COMMIT_ID]
	status
	tag		TNAME [COMMIT_ID]
	track		[RNAME]
	version


Note that these expressions can be used interchangably as "ID"s:
	empty string (current HEAD)
	remote name (as registered with git addremote)
	tag name (as registered with git tag)
	shortcut hash (shorted unambiguous hash lead)
	commit object hash (as returned by commit-id)
	tree object hash (accepted only by some commands)

=head1 DESCRIPTION

Takes a list of file names at the command line, and schedules them for
addition to the GIT repository at the next commit.


=cut
