From: Junio C Hamano Date: Tue, 8 Aug 2006 00:02:07 +0000 (-0700) Subject: Merge branch 'master' into pb/gitpm X-Git-Tag: v1.4.3-rc1~2^2~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9673198ee867cea4ed70d2cf54c1a2eb8f27bb46;p=thirdparty%2Fgit.git Merge branch 'master' into pb/gitpm This is to resolve the conflicts with Ryan's annotate updates early. --- 9673198ee867cea4ed70d2cf54c1a2eb8f27bb46 diff --cc Makefile index 01b9a94823,0761d6c6ed..2ab112bbd8 --- a/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 = - 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)'; \ diff --cc cache.h index 962f2fc346,b8c21e07b2..ed26b47852 --- a/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 environment.c index 6b64d111f5,87162b2572..1ce34118dd --- a/environment.c +++ b/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); diff --cc git-annotate.perl index d924e8771c,215ed26f3a..742a51c501 --- a/git-annotate.perl +++ b/git-annotate.perl @@@ -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; } + sub git_find_all_parents { + my ($rev) = @_; + - 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; ++ my $parentline = $repo->command_oneline("rev-list","--remove-empty", "--parents","--max-count=1","$rev"); + my ($origrev, @parents) = split m/\s+/, $parentline; + - close($revparent); - + return @parents; + } + + sub git_merge_base { + my ($rev1, $rev2) = @_; + - my $mb = open_pipe("git-merge-base", $rev1, $rev2) - or die "Failed to open git-merge-base: $!"; - - my $base = <$mb>; - chomp $base; - - close($mb); - ++ 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 { diff --cc git-send-email.perl index 79e82f5a80,a83c7e9094..1e2777c8e2 --- a/git-send-email.perl +++ b/git-send-email.perl @@@ -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 $repo = Git->repository(); - - my $term = new Term::ReadLine 'git-send-email'; + 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