Merge branch 'master' into pb/gitpm
authorJunio C Hamano <junkio@cox.net>
Tue, 8 Aug 2006 00:02:07 +0000 (17:02 -0700)
committerJunio C Hamano <junkio@cox.net>
Tue, 8 Aug 2006 00:02:07 +0000 (17:02 -0700)
This is to resolve the conflicts with Ryan's annotate updates early.

12 files changed:
1  2 
Documentation/git-repo-config.txt
INSTALL
Makefile
builtin-repo-config.c
cache.h
commit.c
environment.c
git-annotate.perl
git-send-email.perl
sha1_file.c
sha1_name.c
t/test-lib.sh

Simple merge
diff --cc INSTALL
Simple merge
diff --cc Makefile
+++ b/Makefile
@@@ -239,10 -254,11 +264,11 @@@ BUILTIN_OBJS = 
        builtin-apply.o builtin-show-branch.o builtin-diff-files.o \
        builtin-diff-index.o builtin-diff-stages.o builtin-diff-tree.o \
        builtin-cat-file.o builtin-mailsplit.o builtin-stripspace.o \
-       builtin-update-ref.o
+       builtin-update-ref.o builtin-fmt-merge-msg.o builtin-prune.o \
+       builtin-mv.o builtin-prune-packed.o builtin-repo-config.o
  
  GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
 -LIBS = $(GITLIBS) -lz
 +EXTLIBS = -lz
  
  #
  # Platform specific tweaks
@@@ -259,15 -278,17 +288,17 @@@ ifeq ($(uname_S),Darwin
        NEEDS_SSL_WITH_CRYPTO = YesPlease
        NEEDS_LIBICONV = YesPlease
        NO_STRLCPY = YesPlease
-       ## fink
-       ifeq ($(shell test -d /sw/lib && echo y),y)
-               BASIC_CFLAGS += -I/sw/include
-               BASIC_LDFLAGS += -L/sw/lib
+       ifndef NO_FINK
+               ifeq ($(shell test -d /sw/lib && echo y),y)
 -                      ALL_CFLAGS += -I/sw/include
 -                      ALL_LDFLAGS += -L/sw/lib
++                      BASIC_CFLAGS += -I/sw/include
++                      BASIC_LDFLAGS += -L/sw/lib
+               endif
        endif
-       ## darwinports
-       ifeq ($(shell test -d /opt/local/lib && echo y),y)
-               BASIC_CFLAGS += -I/opt/local/include
-               BASIC_LDFLAGS += -L/opt/local/lib
+       ifndef NO_DARWIN_PORTS
+               ifeq ($(shell test -d /opt/local/lib && echo y),y)
 -                      ALL_CFLAGS += -I/opt/local/include
 -                      ALL_LDFLAGS += -L/opt/local/lib
++                      BASIC_CFLAGS += -I/opt/local/include
++                      BASIC_LDFLAGS += -L/opt/local/lib
+               endif
        endif
  endif
  ifeq ($(uname_S),SunOS)
@@@ -341,10 -361,8 +372,11 @@@ endi
  ifneq (,$(findstring arm,$(uname_M)))
        ARM_SHA1 = YesPlease
  endif
 +ifeq ($(uname_M),x86_64)
 +      USE_PIC = YesPlease
 +endif
  
+ -include config.mak.autogen
  -include config.mak
  
  ifdef WITH_OWN_SUBPROCESS_PY
@@@ -415,13 -433,16 +447,16 @@@ ifdef NEEDS_NS
        SIMPLE_LIB += -lnsl
  endif
  ifdef NO_D_TYPE_IN_DIRENT
 -      ALL_CFLAGS += -DNO_D_TYPE_IN_DIRENT
 +      BASIC_CFLAGS += -DNO_D_TYPE_IN_DIRENT
  endif
  ifdef NO_D_INO_IN_DIRENT
 -      ALL_CFLAGS += -DNO_D_INO_IN_DIRENT
 +      BASIC_CFLAGS += -DNO_D_INO_IN_DIRENT
  endif
+ ifdef NO_C99_FORMAT
+       ALL_CFLAGS += -DNO_C99_FORMAT
+ endif
  ifdef NO_SYMLINK_HEAD
 -      ALL_CFLAGS += -DNO_SYMLINK_HEAD
 +      BASIC_CFLAGS += -DNO_SYMLINK_HEAD
  endif
  ifdef NO_STRCASESTR
        COMPAT_CFLAGS += -DNO_STRCASESTR
@@@ -474,18 -495,15 +509,18 @@@ ifdef MOZILLA_SHA
        LIB_OBJS += mozilla-sha1/sha1.o
  else
        SHA1_HEADER = <openssl/sha.h>
 -      LIBS += $(LIB_4_CRYPTO)
 +      EXTLIBS += $(LIB_4_CRYPTO)
 +endif
  endif
  endif
 +ifdef USE_PIC
 +      ALL_CFLAGS += -fPIC
  endif
  ifdef NO_ACCURATE_DIFF
 -      ALL_CFLAGS += -DNO_ACCURATE_DIFF
 +      BASIC_CFLAGS += -DNO_ACCURATE_DIFF
  endif
  
- # Shell quote (do not use $(call) to accomodate ancient setups);
+ # Shell quote (do not use $(call) to accommodate ancient setups);
  
  SHA1_HEADER_SQ = $(subst ','\'',$(SHA1_HEADER))
  
@@@ -707,8 -721,7 +766,8 @@@ install: al
        $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(gitexecdir_SQ)'
        $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
        $(INSTALL) git$X gitk '$(DESTDIR_SQ)$(bindir_SQ)'
-       $(MAKE) -C templates install
+       $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install
 +      $(MAKE) -C perl install
        $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)'
        $(INSTALL) $(PYMODULES) '$(DESTDIR_SQ)$(GIT_PYTHON_DIR_SQ)'
        if test 'z$(bindir_SQ)' != 'z$(gitexecdir_SQ)'; \
Simple merge
diff --cc cache.h
+++ b/cache.h
@@@ -115,10 -115,8 +115,11 @@@ static inline unsigned int create_ce_mo
  extern struct cache_entry **active_cache;
  extern unsigned int active_nr, active_alloc, active_cache_changed;
  extern struct cache_tree *active_cache_tree;
+ extern int cache_errno;
  
 +extern void setup_git(char *new_git_dir, char *new_git_object_dir,
 +                      char *new_git_index_file, char *new_git_graft_file);
 +
  #define GIT_DIR_ENVIRONMENT "GIT_DIR"
  #define DEFAULT_GIT_DIR_ENVIRONMENT ".git"
  #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
diff --cc commit.c
Simple merge
diff --cc environment.c
@@@ -20,21 -21,18 +21,24 @@@ int repository_format_version = 0
  char git_commit_encoding[MAX_ENCODING_LENGTH] = "utf-8";
  int shared_repository = PERM_UMASK;
  const char *apply_default_whitespace = NULL;
+ int zlib_compression_level = Z_DEFAULT_COMPRESSION;
+ int pager_in_use;
+ int pager_use_color = 1;
  
 +static int dyn_git_object_dir, dyn_git_index_file, dyn_git_graft_file;
  static char *git_dir, *git_object_dir, *git_index_file, *git_refs_dir,
        *git_graft_file;
 -static void setup_git_env(void)
 +
 +void setup_git(char *new_git_dir, char *new_git_object_dir,
 +               char *new_git_index_file, char *new_git_graft_file)
  {
 -      git_dir = getenv(GIT_DIR_ENVIRONMENT);
 +      git_dir = new_git_dir;
        if (!git_dir)
                git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
 -      git_object_dir = getenv(DB_ENVIRONMENT);
 +
 +      if (dyn_git_object_dir)
 +              free(git_object_dir);
 +      git_object_dir = new_git_object_dir;
        if (!git_object_dir) {
                git_object_dir = xmalloc(strlen(git_dir) + 9);
                sprintf(git_object_dir, "%s/objects", git_dir);
@@@ -105,11 -102,15 +105,11 @@@ while (my $bound = pop @stack) 
  push @revqueue, $head;
  init_claim( defined $starting_rev ? $head : 'dirty');
  unless (defined $starting_rev) {
 -      my $diff = open_pipe("git","diff","HEAD", "--",$filename)
 -              or die "Failed to call git diff to check for dirty state: $!";
 -
 -      _git_diff_parse($diff, [$head], "dirty", (
 -                              'author' => gitvar_name("GIT_AUTHOR_IDENT"),
 -                              'author_date' => sprintf("%s +0000",time()),
 -                              )
 -                      );
 -      close($diff);
 +      my %ident;
 +      @ident{'author', 'author_email', 'author_date'} = $repo->ident('author');
 +      my $diff = $repo->command_output_pipe('diff', '-R', 'HEAD', '--', $filename);
-       _git_diff_parse($diff, $head, "dirty", %ident);
++      _git_diff_parse($diff, [$head], "dirty", %ident);
 +      $repo->command_close_pipe($diff);
  }
  handle_rev();
  
@@@ -240,19 -247,131 +239,117 @@@ sub git_find_parent 
        return $parent;
  }
  
 -      my $revparent = open_pipe("git-rev-list","--remove-empty", "--parents","--max-count=1","$rev")
 -              or die "Failed to open git-rev-list to find a single parent: $!";
 -
 -      my $parentline = <$revparent>;
 -      chomp $parentline;
+ sub git_find_all_parents {
+       my ($rev) = @_;
 -      close($revparent);
 -
++      my $parentline = $repo->command_oneline("rev-list","--remove-empty", "--parents","--max-count=1","$rev");
+       my ($origrev, @parents) = split m/\s+/, $parentline;
 -      my $mb = open_pipe("git-merge-base", $rev1, $rev2)
 -              or die "Failed to open git-merge-base: $!";
 -
 -      my $base = <$mb>;
 -      chomp $base;
 -
 -      close($mb);
 -
+       return @parents;
+ }
+ sub git_merge_base {
+       my ($rev1, $rev2) = @_;
++      my $base = $repo->command_oneline("merge-base", $rev1, $rev2);
+       return $base;
+ }
+ # Construct a set of pseudo parents that are in the same order,
+ # and the same quantity as the real parents,
+ # but whose SHA1s are as similar to the logical parents
+ # as possible.
+ sub get_pseudo_parents {
+       my ($all, $fake) = @_;
+       my @all = @$all;
+       my @fake = @$fake;
+       my @pseudo;
+       my %fake = map {$_ => 1} @fake;
+       my %seenfake;
+       my $fakeidx = 0;
+       foreach my $p (@all) {
+               if (exists $fake{$p}) {
+                       if ($fake[$fakeidx] ne $p) {
+                               die sprintf("parent mismatch: %s != %s\nall:%s\nfake:%s\n",
+                                           $fake[$fakeidx], $p,
+                                           join(", ", @all),
+                                           join(", ", @fake),
+                                          );
+                       }
+                       push @pseudo, $p;
+                       $fakeidx++;
+                       $seenfake{$p}++;
+               } else {
+                       my $base = git_merge_base($fake[$fakeidx], $p);
+                       if ($base ne $fake[$fakeidx]) {
+                               die sprintf("Result of merge-base doesn't match fake: %s,%s != %s\n",
+                                      $fake[$fakeidx], $p, $base);
+                       }
+                       # The details of how we parse the diffs
+                       # mean that we cannot have a duplicate
+                       # revision in the list, so if we've already
+                       # seen the revision we would normally add, just use
+                       # the actual revision.
+                       if ($seenfake{$base}) {
+                               push @pseudo, $p;
+                       } else {
+                               push @pseudo, $base;
+                               $seenfake{$base}++;
+                       }
+               }
+       }
+       return @pseudo;
+ }
  
  # Get a diff between the current revision and a parent.
  # Record the commit information that results.
  sub git_diff_parse {
-       my ($parent, $rev, %revinfo) = @_;
+       my ($parents, $rev, %revinfo) = @_;
  
-       my $diff = $repo->command_output_pipe('diff-tree', '-M', '-p',
-                       $rev, $parent, '--',
-                       $revs{$rev}{'filename'}, $revs{$parent}{'filename'});
+       my @pseudo_parents;
 -      my @command = ("git-diff-tree");
++      my @command = ("diff-tree");
+       my $revision_spec;
+       if (scalar @$parents == 1) {
+               $revision_spec = join("..", $parents->[0], $rev);
+               @pseudo_parents = @$parents;
+       } else {
+               my @all_parents = git_find_all_parents($rev);
+               if (@all_parents !=  @$parents) {
+                       @pseudo_parents = get_pseudo_parents(\@all_parents, $parents);
+               } else {
+                       @pseudo_parents = @$parents;
+               }
+               $revision_spec = $rev;
+               push @command, "-c";
+       }
  
-       _git_diff_parse($diff, $parent, $rev, %revinfo);
+       my @filenames = ( $revs{$rev}{'filename'} );
+       foreach my $parent (@$parents) {
+               push @filenames, $revs{$parent}{'filename'};
+       }
+       push @command, "-p", "-M", $revision_spec, "--", @filenames;
 -      my $diff = open_pipe( @command )
 -              or die "Failed to call git-diff for annotation: $!";
++      my $diff = $repo->command_output_pipe(@command);
+       _git_diff_parse($diff, \@pseudo_parents, $rev, %revinfo);
  
 -      close($diff);
 +      $repo->command_close_pipe($diff);
  }
  
  sub _git_diff_parse {
@@@ -21,11 -21,56 +21,57 @@@ use warnings
  use Term::ReadLine;
  use Getopt::Long;
  use Data::Dumper;
 +use Git;
  
+ package FakeTerm;
+ sub new {
+       my ($class, $reason) = @_;
+       return bless \$reason, shift;
+ }
+ sub readline {
+       my $self = shift;
+       die "Cannot use readline on FakeTerm: $$self";
+ }
+ package main;
  # most mail servers generate the Date: header, but not all...
- $ENV{LC_ALL} = 'C';
- use POSIX qw/strftime/;
+ sub format_2822_time {
+       my ($time) = @_;
+       my @localtm = localtime($time);
+       my @gmttm = gmtime($time);
+       my $localmin = $localtm[1] + $localtm[2] * 60;
+       my $gmtmin = $gmttm[1] + $gmttm[2] * 60;
+       if ($localtm[0] != $gmttm[0]) {
+               die "local zone differs from GMT by a non-minute interval\n";
+       }
+       if ((($gmttm[6] + 1) % 7) == $localtm[6]) {
+               $localmin += 1440;
+       } elsif ((($gmttm[6] - 1) % 7) == $localtm[6]) {
+               $localmin -= 1440;
+       } elsif ($gmttm[6] != $localtm[6]) {
+               die "local time offset greater than or equal to 24 hours\n";
+       }
+       my $offset = $localmin - $gmtmin;
+       my $offhour = $offset / 60;
+       my $offmin = abs($offset % 60);
+       if (abs($offhour) >= 24) {
+               die ("local time offset greater than or equal to 24 hours\n");
+       }
+       return sprintf("%s, %2d %s %d %02d:%02d:%02d %s%02d%02d",
+                      qw(Sun Mon Tue Wed Thu Fri Sat)[$localtm[6]],
+                      $localtm[3],
+                      qw(Jan Feb Mar Apr May Jun
+                         Jul Aug Sep Oct Nov Dec)[$localtm[4]],
+                      $localtm[5]+1900,
+                      $localtm[2],
+                      $localtm[1],
+                      $localtm[0],
+                      ($offset >= 0) ? '+' : '-',
+                      abs($offhour),
+                      $offmin,
+                      );
+ }
  
  my $have_email_valid = eval { require Email::Valid; 1 };
  my $smtp;
@@@ -47,9 -92,12 +93,13 @@@ my $smtp_server
  # Example reply to:
  #$initial_reply_to = ''; #<20050203173208.GA23964@foobar.com>';
  
- my $term = new Term::ReadLine 'git-send-email';
 +my $repo = Git->repository();
+ my $term = eval {
+       new Term::ReadLine 'git-send-email';
+ };
+ if ($@) {
+       $term = new FakeTerm "$@: going non-interactive";
+ }
  
  # Begin by accumulating all the variables (defined above), that we will end up
  # needing, first, from the command line:
@@@ -353,10 -422,13 +403,10 @@@ sub send_messag
        my @recipients = unique_email_list(@to);
        my $to = join (",\n\t", @recipients);
        @recipients = unique_email_list(@recipients,@cc,@bcclist);
-       my $date = strftime('%a, %d %b %Y %H:%M:%S %z', localtime($time++));
+       my $date = format_2822_time($time++);
        my $gitversion = '@@GIT_VERSION@@';
        if ($gitversion =~ m/..GIT_VERSION../) {
 -          $gitversion = `git --version`;
 -          chomp $gitversion;
 -          # keep only what's after the last space
 -          $gitversion =~ s/^.* //;
 +          $gitversion = Git::version();
        }
  
        my $header = "From: $from
diff --cc sha1_file.c
Simple merge
diff --cc sha1_name.c
Simple merge
diff --cc t/test-lib.sh
Simple merge