summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/buildsystems/Generators.pm42
-rw-r--r--contrib/buildsystems/Generators/QMake.pm189
-rw-r--r--contrib/buildsystems/Generators/Vcproj.pm626
-rw-r--r--contrib/buildsystems/engine.pl356
-rw-r--r--contrib/buildsystems/generate29
-rw-r--r--contrib/buildsystems/parse.pl228
-rwxr-xr-xcontrib/completion/git-completion.bash108
-rw-r--r--contrib/emacs/git-blame.el156
-rwxr-xr-xcontrib/examples/git-merge.sh8
-rwxr-xr-xcontrib/examples/git-resolve.sh2
-rwxr-xr-xcontrib/fast-import/import-tars.perl7
-rwxr-xr-xcontrib/hooks/post-receive-email6
12 files changed, 1669 insertions, 88 deletions
diff --git a/contrib/buildsystems/Generators.pm b/contrib/buildsystems/Generators.pm
new file mode 100644
index 0000000000..408ef714b8
--- /dev/null
+++ b/contrib/buildsystems/Generators.pm
@@ -0,0 +1,42 @@
+package Generators;
+require Exporter;
+
+use strict;
+use File::Basename;
+no strict 'refs';
+use vars qw($VERSION @AVAILABLE);
+
+our $VERSION = '1.00';
+our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
+@ISA = qw(Exporter);
+
+BEGIN {
+ local(*D);
+ my $me = $INC{"Generators.pm"};
+ die "Couldn't find myself in \@INC, which is required to load the generators!" if ("$me" eq "");
+ $me = dirname($me);
+ if (opendir(D,"$me/Generators")) {
+ foreach my $gen (readdir(D)) {
+ next if ($gen =~ /^\.\.?$/);
+ require "${me}/Generators/$gen";
+ $gen =~ s,\.pm,,;
+ push(@AVAILABLE, $gen);
+ }
+ closedir(D);
+ my $gens = join(', ', @AVAILABLE);
+ }
+
+ push @EXPORT_OK, qw(available);
+}
+
+sub available {
+ return @AVAILABLE;
+}
+
+sub generate {
+ my ($gen, $git_dir, $out_dir, $rel_dir, %build_structure) = @_;
+ return eval("Generators::${gen}::generate(\$git_dir, \$out_dir, \$rel_dir, \%build_structure)") if grep(/^$gen$/, @AVAILABLE);
+ die "Generator \"${gen}\" is not available!\nAvailable generators are: @AVAILABLE\n";
+}
+
+1;
diff --git a/contrib/buildsystems/Generators/QMake.pm b/contrib/buildsystems/Generators/QMake.pm
new file mode 100644
index 0000000000..ff3b657e61
--- /dev/null
+++ b/contrib/buildsystems/Generators/QMake.pm
@@ -0,0 +1,189 @@
+package Generators::QMake;
+require Exporter;
+
+use strict;
+use vars qw($VERSION);
+
+our $VERSION = '1.00';
+our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
+@ISA = qw(Exporter);
+
+BEGIN {
+ push @EXPORT_OK, qw(generate);
+}
+
+sub generate {
+ my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
+
+ my @libs = @{$build_structure{"LIBS"}};
+ foreach (@libs) {
+ createLibProject($_, $git_dir, $out_dir, $rel_dir, %build_structure);
+ }
+
+ my @apps = @{$build_structure{"APPS"}};
+ foreach (@apps) {
+ createAppProject($_, $git_dir, $out_dir, $rel_dir, %build_structure);
+ }
+
+ createGlueProject($git_dir, $out_dir, $rel_dir, %build_structure);
+ return 0;
+}
+
+sub createLibProject {
+ my ($libname, $git_dir, $out_dir, $rel_dir, %build_structure) = @_;
+ print "Generate $libname lib project\n";
+ $rel_dir = "../$rel_dir";
+
+ my $sources = join(" \\\n\t", sort(map("$rel_dir/$_", @{$build_structure{"LIBS_${libname}_SOURCES"}})));
+ my $defines = join(" \\\n\t", sort(@{$build_structure{"LIBS_${libname}_DEFINES"}}));
+ my $includes= join(" \\\n\t", sort(map("$rel_dir/$_", @{$build_structure{"LIBS_${libname}_INCLUDES"}})));
+ my $cflags = join(" ", sort(@{$build_structure{"LIBS_${libname}_CFLAGS"}}));
+
+ my $cflags_debug = $cflags;
+ $cflags_debug =~ s/-MT/-MTd/;
+ $cflags_debug =~ s/-O.//;
+
+ my $cflags_release = $cflags;
+ $cflags_release =~ s/-MTd/-MT/;
+
+ my @tmp = @{$build_structure{"LIBS_${libname}_LFLAGS"}};
+ my @tmp2 = ();
+ foreach (@tmp) {
+ if (/^-LTCG/) {
+ } elsif (/^-L/) {
+ $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
+ }
+ push(@tmp2, $_);
+ }
+ my $lflags = join(" ", sort(@tmp));
+
+ my $target = $libname;
+ $target =~ s/\//_/g;
+ $defines =~ s/-D//g;
+ $defines =~ s/"/\\\\"/g;
+ $includes =~ s/-I//g;
+ mkdir "$target" || die "Could not create the directory $target for lib project!\n";
+ open F, ">$target/$target.pro" || die "Could not open $target/$target.pro for writing!\n";
+ print F << "EOM";
+TEMPLATE = lib
+TARGET = $target
+DESTDIR = $rel_dir
+
+CONFIG -= qt
+CONFIG += static
+
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_RELEASE = $cflags_release
+QMAKE_CFLAGS_DEBUG = $cflags_debug
+QMAKE_LIBFLAGS = $lflags
+
+DEFINES += \\
+ $defines
+
+INCLUDEPATH += \\
+ $includes
+
+SOURCES += \\
+ $sources
+EOM
+ close F;
+}
+
+sub createAppProject {
+ my ($appname, $git_dir, $out_dir, $rel_dir, %build_structure) = @_;
+ print "Generate $appname app project\n";
+ $rel_dir = "../$rel_dir";
+
+ my $sources = join(" \\\n\t", sort(map("$rel_dir/$_", @{$build_structure{"APPS_${appname}_SOURCES"}})));
+ my $defines = join(" \\\n\t", sort(@{$build_structure{"APPS_${appname}_DEFINES"}}));
+ my $includes= join(" \\\n\t", sort(map("$rel_dir/$_", @{$build_structure{"APPS_${appname}_INCLUDES"}})));
+ my $cflags = join(" ", sort(@{$build_structure{"APPS_${appname}_CFLAGS"}}));
+
+ my $cflags_debug = $cflags;
+ $cflags_debug =~ s/-MT/-MTd/;
+ $cflags_debug =~ s/-O.//;
+
+ my $cflags_release = $cflags;
+ $cflags_release =~ s/-MTd/-MT/;
+
+ my $libs;
+ foreach (sort(@{$build_structure{"APPS_${appname}_LIBS"}})) {
+ $_ =~ s/\//_/g;
+ $libs .= " $_";
+ }
+ my @tmp = @{$build_structure{"APPS_${appname}_LFLAGS"}};
+ my @tmp2 = ();
+ foreach (@tmp) {
+ # next if ($_ eq "-NODEFAULTLIB:MSVCRT.lib");
+ if (/^-LTCG/) {
+ } elsif (/^-L/) {
+ $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
+ }
+ push(@tmp2, $_);
+ }
+ my $lflags = join(" ", sort(@tmp));
+
+ my $target = $appname;
+ $target =~ s/\.exe//;
+ $target =~ s/\//_/g;
+ $defines =~ s/-D//g;
+ $defines =~ s/"/\\\\"/g;
+ $includes =~ s/-I//g;
+ mkdir "$target" || die "Could not create the directory $target for app project!\n";
+ open F, ">$target/$target.pro" || die "Could not open $target/$target.pro for writing!\n";
+ print F << "EOM";
+TEMPLATE = app
+TARGET = $target
+DESTDIR = $rel_dir
+
+CONFIG -= qt embed_manifest_exe
+CONFIG += console
+
+QMAKE_CFLAGS =
+QMAKE_CFLAGS_RELEASE = $cflags_release
+QMAKE_CFLAGS_DEBUG = $cflags_debug
+QMAKE_LFLAGS = $lflags
+LIBS = $libs
+
+DEFINES += \\
+ $defines
+
+INCLUDEPATH += \\
+ $includes
+
+win32:QMAKE_LFLAGS += -LIBPATH:$rel_dir
+else: QMAKE_LFLAGS += -L$rel_dir
+
+SOURCES += \\
+ $sources
+EOM
+ close F;
+}
+
+sub createGlueProject {
+ my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
+ my $libs = join(" \\ \n", map("\t$_|$_.pro", @{$build_structure{"LIBS"}}));
+ my $apps = join(" \\ \n", map("\t$_|$_.pro", @{$build_structure{"APPS"}}));
+ $libs =~ s/\.a//g;
+ $libs =~ s/\//_/g;
+ $libs =~ s/\|/\//g;
+ $apps =~ s/\.exe//g;
+ $apps =~ s/\//_/g;
+ $apps =~ s/\|/\//g;
+
+ my $filename = $out_dir;
+ $filename =~ s/.*\/([^\/]+)$/$1/;
+ $filename =~ s/\/$//;
+ print "Generate glue project $filename.pro\n";
+ open F, ">$filename.pro" || die "Could not open $filename.pro for writing!\n";
+ print F << "EOM";
+TEMPLATE = subdirs
+CONFIG += ordered
+SUBDIRS += \\
+$libs \\
+$apps
+EOM
+ close F;
+}
+
+1;
diff --git a/contrib/buildsystems/Generators/Vcproj.pm b/contrib/buildsystems/Generators/Vcproj.pm
new file mode 100644
index 0000000000..cfa74adcc2
--- /dev/null
+++ b/contrib/buildsystems/Generators/Vcproj.pm
@@ -0,0 +1,626 @@
+package Generators::Vcproj;
+require Exporter;
+
+use strict;
+use vars qw($VERSION);
+
+our $VERSION = '1.00';
+our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
+@ISA = qw(Exporter);
+
+BEGIN {
+ push @EXPORT_OK, qw(generate);
+}
+
+my $guid_index = 0;
+my @GUIDS = (
+ "{E07B9989-2BF7-4F21-8918-BE22BA467AC3}",
+ "{278FFB51-0296-4A44-A81A-22B87B7C3592}",
+ "{7346A2C4-F0FD-444F-9EBE-1AF23B2B5650}",
+ "{67F421AC-EB34-4D49-820B-3196807B423F}",
+ "{385DCFE1-CC8C-4211-A451-80FCFC31CA51}",
+ "{97CC46C5-D2CC-4D26-B634-E75792B79916}",
+ "{C7CE21FE-6EF8-4012-A5C7-A22BCEDFBA11}",
+ "{51575134-3FDF-42D1-BABD-3FB12669C6C9}",
+ "{0AE195E4-9823-4B87-8E6F-20C5614AF2FF}",
+ "{4B918255-67CA-43BB-A46C-26704B666E6B}",
+ "{18CCFEEF-C8EE-4CC1-A265-26F95C9F4649}",
+ "{5D5D90FA-01B7-4973-AFE5-CA88C53AC197}",
+ "{1F054320-036D-49E1-B384-FB5DF0BC8AC0}",
+ "{7CED65EE-F2D9-4171-825B-C7D561FE5786}",
+ "{8D341679-0F07-4664-9A56-3BA0DE88B9BC}",
+ "{C189FEDC-2957-4BD7-9FA4-7622241EA145}",
+ "{66844203-1B9F-4C53-9274-164FFF95B847}",
+ "{E4FEA145-DECC-440D-AEEA-598CF381FD43}",
+ "{73300A8E-C8AC-41B0-B555-4F596B681BA7}",
+ "{873FDEB1-D01D-40BF-A1BF-8BBC58EC0F51}",
+ "{7922C8BE-76C5-4AC6-8BF7-885C0F93B782}",
+ "{E245D370-308B-4A49-BFC1-1E527827975F}",
+ "{F6FA957B-66FC-4ED7-B260-E59BBE4FE813}",
+ "{E6055070-0198-431A-BC49-8DB6CEE770AE}",
+ "{54159234-C3EB-43DA-906B-CE5DA5C74654}",
+ "{594CFC35-0B60-46F6-B8EF-9983ACC1187D}",
+ "{D93FCAB7-1F01-48D2-B832-F761B83231A5}",
+ "{DBA5E6AC-E7BE-42D3-8703-4E787141526E}",
+ "{6171953F-DD26-44C7-A3BE-CC45F86FC11F}",
+ "{9E19DDBE-F5E4-4A26-A2FE-0616E04879B8}",
+ "{AE81A615-99E3-4885-9CE0-D9CAA193E867}",
+ "{FBF4067E-1855-4F6C-8BCD-4D62E801A04D}",
+ "{17007948-6593-4AEB-8106-F7884B4F2C19}",
+ "{199D4C8D-8639-4DA6-82EF-08668C35DEE0}",
+ "{E085E50E-C140-4CF3-BE4B-094B14F0DDD6}",
+ "{00785268-A9CC-4E40-AC29-BAC0019159CE}",
+ "{4C06F56A-DCDB-46A6-B67C-02339935CF12}",
+ "{3A62D3FD-519E-4EC9-8171-D2C1BFEA022F}",
+ "{3A62D3FD-519E-4EC9-8171-D2C1BFEA022F}",
+ "{9392EB58-D7BA-410B-B1F0-B2FAA6BC89A7}",
+ "{2ACAB2D5-E0CE-4027-BCA0-D78B2D7A6C66}",
+ "{86E216C3-43CE-481A-BCB2-BE5E62850635}",
+ "{FB631291-7923-4B91-9A57-7B18FDBB7A42}",
+ "{0A176EC9-E934-45B8-B87F-16C7F4C80039}",
+ "{DF55CA80-46E8-4C53-B65B-4990A23DD444}",
+ "{3A0F9895-55D2-4710-BE5E-AD7498B5BF44}",
+ "{294BDC5A-F448-48B6-8110-DD0A81820F8C}",
+ "{4B9F66E9-FAC9-47AB-B1EF-C16756FBFD06}",
+ "{72EA49C6-2806-48BD-B81B-D4905102E19C}",
+ "{5728EB7E-8929-486C-8CD5-3238D060E768}"
+);
+
+sub generate {
+ my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
+ my @libs = @{$build_structure{"LIBS"}};
+ foreach (@libs) {
+ createLibProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure);
+ }
+
+ my @apps = @{$build_structure{"APPS"}};
+ foreach (@apps) {
+ createAppProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure);
+ }
+
+ createGlueProject($git_dir, $out_dir, $rel_dir, %build_structure);
+ return 0;
+}
+
+sub createLibProject {
+ my ($libname, $git_dir, $out_dir, $rel_dir, $build_structure) = @_;
+ print "Generate $libname vcproj lib project\n";
+ $rel_dir = "..\\$rel_dir";
+ $rel_dir =~ s/\//\\/g;
+
+ my $target = $libname;
+ $target =~ s/\//_/g;
+ $target =~ s/\.a//;
+
+ my $uuid = $GUIDS[$guid_index];
+ $$build_structure{"LIBS_${target}_GUID"} = $uuid;
+ $guid_index += 1;
+
+ my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"LIBS_${libname}_SOURCES"}}));
+ my @sources;
+ foreach (@srcs) {
+ $_ =~ s/\//\\/g;
+ push(@sources, $_);
+ }
+ my $defines = join(",", sort(@{$$build_structure{"LIBS_${libname}_DEFINES"}}));
+ my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"LIBS_${libname}_INCLUDES"}})));
+ my $cflags = join(" ", sort(@{$$build_structure{"LIBS_${libname}_CFLAGS"}}));
+ $cflags =~ s/\"/&quot;/g;
+
+ my $cflags_debug = $cflags;
+ $cflags_debug =~ s/-MT/-MTd/;
+ $cflags_debug =~ s/-O.//;
+
+ my $cflags_release = $cflags;
+ $cflags_release =~ s/-MTd/-MT/;
+
+ my @tmp = @{$$build_structure{"LIBS_${libname}_LFLAGS"}};
+ my @tmp2 = ();
+ foreach (@tmp) {
+ if (/^-LTCG/) {
+ } elsif (/^-L/) {
+ $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
+ }
+ push(@tmp2, $_);
+ }
+ my $lflags = join(" ", sort(@tmp));
+
+ $defines =~ s/-D//g;
+ $defines =~ s/\"/\\&quot;/g;
+ $defines =~ s/\'//g;
+ $includes =~ s/-I//g;
+ mkdir "$target" || die "Could not create the directory $target for lib project!\n";
+ open F, ">$target/$target.vcproj" || die "Could not open $target/$target.pro for writing!\n";
+ binmode F, ":crlf";
+ print F << "EOM";
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="$target"
+ ProjectGUID="$uuid">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$rel_dir"
+ ConfigurationType="4"
+ CharacterSet="0"
+ IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="$cflags_debug"
+ Optimization="0"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="$includes"
+ PreprocessorDefinitions="WIN32,_DEBUG,$defines"
+ MinimalRebuild="true"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$rel_dir"
+ ConfigurationType="4"
+ CharacterSet="0"
+ WholeProgramOptimization="1"
+ IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="$cflags_release"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="$includes"
+ PreprocessorDefinitions="WIN32,NDEBUG,$defines"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+EOM
+ foreach(@sources) {
+ print F << "EOM";
+ <File
+ RelativePath="$_"/>
+EOM
+ }
+ print F << "EOM";
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
+EOM
+ close F;
+}
+
+sub createAppProject {
+ my ($appname, $git_dir, $out_dir, $rel_dir, $build_structure) = @_;
+ print "Generate $appname vcproj app project\n";
+ $rel_dir = "..\\$rel_dir";
+ $rel_dir =~ s/\//\\/g;
+
+ my $target = $appname;
+ $target =~ s/\//_/g;
+ $target =~ s/\.exe//;
+
+ my $uuid = $GUIDS[$guid_index];
+ $$build_structure{"APPS_${target}_GUID"} = $uuid;
+ $guid_index += 1;
+
+ my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"APPS_${appname}_SOURCES"}}));
+ my @sources;
+ foreach (@srcs) {
+ $_ =~ s/\//\\/g;
+ push(@sources, $_);
+ }
+ my $defines = join(",", sort(@{$$build_structure{"APPS_${appname}_DEFINES"}}));
+ my $includes= join(";", sort(map("&quot;$rel_dir\\$_&quot;", @{$$build_structure{"APPS_${appname}_INCLUDES"}})));
+ my $cflags = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}}));
+ $cflags =~ s/\"/&quot;/g;
+
+ my $cflags_debug = $cflags;
+ $cflags_debug =~ s/-MT/-MTd/;
+ $cflags_debug =~ s/-O.//;
+
+ my $cflags_release = $cflags;
+ $cflags_release =~ s/-MTd/-MT/;
+
+ my $libs;
+ foreach (sort(@{$$build_structure{"APPS_${appname}_LIBS"}})) {
+ $_ =~ s/\//_/g;
+ $libs .= " $_";
+ }
+ my @tmp = @{$$build_structure{"APPS_${appname}_LFLAGS"}};
+ my @tmp2 = ();
+ foreach (@tmp) {
+ if (/^-LTCG/) {
+ } elsif (/^-L/) {
+ $_ =~ s/^-L/-LIBPATH:$rel_dir\//;
+ }
+ push(@tmp2, $_);
+ }
+ my $lflags = join(" ", sort(@tmp)) . " -LIBPATH:$rel_dir";
+
+ $defines =~ s/-D//g;
+ $defines =~ s/\"/\\&quot;/g;
+ $defines =~ s/\'//g;
+ $defines =~ s/\\\\/\\/g;
+ $includes =~ s/-I//g;
+ mkdir "$target" || die "Could not create the directory $target for lib project!\n";
+ open F, ">$target/$target.vcproj" || die "Could not open $target/$target.pro for writing!\n";
+ binmode F, ":crlf";
+ print F << "EOM";
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="$target"
+ ProjectGUID="$uuid">
+ <Platforms>
+ <Platform
+ Name="Win32"/>
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$rel_dir"
+ ConfigurationType="1"
+ CharacterSet="0"
+ IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="$cflags_debug"
+ Optimization="0"
+ InlineFunctionExpansion="1"
+ AdditionalIncludeDirectories="$includes"
+ PreprocessorDefinitions="WIN32,_DEBUG,$defines"
+ MinimalRebuild="true"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$libs"
+ AdditionalOptions="$lflags"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$rel_dir"
+ ConfigurationType="1"
+ CharacterSet="0"
+ WholeProgramOptimization="1"
+ IntermediateDirectory="\$(ProjectDir)\$(ConfigurationName)"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalOptions="$cflags_release"
+ Optimization="2"
+ InlineFunctionExpansion="1"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="$includes"
+ PreprocessorDefinitions="WIN32,NDEBUG,$defines"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ ProgramDataBaseFileName="\$(IntDir)\\\$(TargetName).pdb"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="$libs"
+ AdditionalOptions="$lflags"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+EOM
+ foreach(@sources) {
+ print F << "EOM";
+ <File
+ RelativePath="$_"/>
+EOM
+ }
+ print F << "EOM";
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
+EOM
+ close F;
+}
+
+sub createGlueProject {
+ my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
+ print "Generate solutions file\n";
+ $rel_dir = "..\\$rel_dir";
+ $rel_dir =~ s/\//\\/g;
+ my $SLN_HEAD = "Microsoft Visual Studio Solution File, Format Version 10.00\n# Visual Studio 2008\n";
+ my $SLN_PRE = "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = ";
+ my $SLN_POST = "\nEndProject\n";
+
+ my @libs = @{$build_structure{"LIBS"}};
+ my @tmp;
+ foreach (@libs) {
+ $_ =~ s/\//_/g;
+ $_ =~ s/\.a//;
+ push(@tmp, $_);
+ }
+ @libs = @tmp;
+
+ my @apps = @{$build_structure{"APPS"}};
+ @tmp = ();
+ foreach (@apps) {
+ $_ =~ s/\//_/g;
+ $_ =~ s/\.exe//;
+ push(@tmp, $_);
+ }
+ @apps = @tmp;
+
+ open F, ">git.sln" || die "Could not open git.sln for writing!\n";
+ binmode F, ":crlf";
+ print F "$SLN_HEAD";
+ foreach (@libs) {
+ my $libname = $_;
+ my $uuid = $build_structure{"LIBS_${libname}_GUID"};
+ print F "$SLN_PRE";
+ print F "\"${libname}\", \"${libname}\\${libname}.vcproj\", \"${uuid}\"";
+ print F "$SLN_POST";
+ }
+ my $uuid_libgit = $build_structure{"LIBS_libgit_GUID"};
+ my $uuid_xdiff_lib = $build_structure{"LIBS_xdiff_lib_GUID"};
+ foreach (@apps) {
+ my $appname = $_;
+ my $uuid = $build_structure{"APPS_${appname}_GUID"};
+ print F "$SLN_PRE";
+ print F "\"${appname}\", \"${appname}\\${appname}.vcproj\", \"${uuid}\"\n";
+ print F " ProjectSection(ProjectDependencies) = postProject\n";
+ print F " ${uuid_libgit} = ${uuid_libgit}\n";
+ print F " ${uuid_xdiff_lib} = ${uuid_xdiff_lib}\n";
+ print F " EndProjectSection";
+ print F "$SLN_POST";
+ }
+
+ print F << "EOM";
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+EOM
+ print F << "EOM";
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+EOM
+ foreach (@libs) {
+ my $libname = $_;
+ my $uuid = $build_structure{"LIBS_${libname}_GUID"};
+ print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
+ print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
+ print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";
+ print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n";
+ }
+ foreach (@apps) {
+ my $appname = $_;
+ my $uuid = $build_structure{"APPS_${appname}_GUID"};
+ print F "\t\t${uuid}.Debug|Win32.ActiveCfg = Debug|Win32\n";
+ print F "\t\t${uuid}.Debug|Win32.Build.0 = Debug|Win32\n";
+ print F "\t\t${uuid}.Release|Win32.ActiveCfg = Release|Win32\n";
+ print F "\t\t${uuid}.Release|Win32.Build.0 = Release|Win32\n";
+ }
+
+ print F << "EOM";
+ EndGlobalSection
+EndGlobal
+EOM
+ close F;
+}
+
+1;
diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl
new file mode 100644
index 0000000000..d506717bfd
--- /dev/null
+++ b/contrib/buildsystems/engine.pl
@@ -0,0 +1,356 @@
+#!/usr/bin/perl -w
+######################################################################
+# Do not call this script directly!
+#
+# The generate script ensures that @INC is correct before the engine
+# is executed.
+#
+# Copyright (C) 2009 Marius Storm-Olsen <mstormo@gmail.com>
+######################################################################
+use strict;
+use File::Basename;
+use File::Spec;
+use Cwd;
+use Generators;
+
+my (%build_structure, %compile_options, @makedry);
+my $out_dir = getcwd();
+my $git_dir = $out_dir;
+$git_dir =~ s=\\=/=g;
+$git_dir = dirname($git_dir) while (!-e "$git_dir/git.c" && "$git_dir" ne "");
+die "Couldn't find Git repo" if ("$git_dir" eq "");
+
+my @gens = Generators::available();
+my $gen = "Vcproj";
+
+sub showUsage
+{
+ my $genlist = join(', ', @gens);
+ print << "EOM";
+generate usage:
+ -g <GENERATOR> --gen <GENERATOR> Specify the buildsystem generator (default: $gen)
+ Available: $genlist
+ -o <PATH> --out <PATH> Specify output directory generation (default: .)
+ -i <FILE> --in <FILE> Specify input file, instead of running GNU Make
+ -h,-? --help This help
+EOM
+ exit 0;
+}
+
+# Parse command-line options
+while (@ARGV) {
+ my $arg = shift @ARGV;
+ if ("$arg" eq "-h" || "$arg" eq "--help" || "$arg" eq "-?") {
+ showUsage();
+ exit(0);
+ } elsif("$arg" eq "--out" || "$arg" eq "-o") {
+ $out_dir = shift @ARGV;
+ } elsif("$arg" eq "--gen" || "$arg" eq "-g") {
+ $gen = shift @ARGV;
+ } elsif("$arg" eq "--in" || "$arg" eq "-i") {
+ my $infile = shift @ARGV;
+ open(F, "<$infile") || die "Couldn't open file $infile";
+ @makedry = <F>;
+ close(F);
+ }
+}
+
+# NOT using File::Spec->rel2abs($path, $base) here, as
+# it fails badly for me in the msysgit environment
+$git_dir = File::Spec->rel2abs($git_dir);
+$out_dir = File::Spec->rel2abs($out_dir);
+my $rel_dir = makeOutRel2Git($git_dir, $out_dir);
+
+# Print some information so the user feels informed
+print << "EOM";
+-----
+Generator: $gen
+Git dir: $git_dir
+Out dir: $out_dir
+-----
+Running GNU Make to figure out build structure...
+EOM
+
+# Pipe a make --dry-run into a variable, if not already loaded from file
+@makedry = `cd $git_dir && make -n MSVC=1 V=1 2>/dev/null` if !@makedry;
+
+# Parse the make output into usable info
+parseMakeOutput();
+
+# Finally, ask the generator to start generating..
+Generators::generate($gen, $git_dir, $out_dir, $rel_dir, %build_structure);
+
+# main flow ends here
+# -------------------------------------------------------------------------------------------------
+
+
+# 1) path: /foo/bar/baz 2) path: /foo/bar/baz 3) path: /foo/bar/baz
+# base: /foo/bar/baz/temp base: /foo/bar base: /tmp
+# rel: .. rel: baz rel: ../foo/bar/baz
+sub makeOutRel2Git
+{
+ my ($path, $base) = @_;
+ my $rel;
+ if ("$path" eq "$base") {
+ return ".";
+ } elsif ($base =~ /^$path/) {
+ # case 1
+ my $tmp = $base;
+ $tmp =~ s/^$path//;
+ foreach (split('/', $tmp)) {
+ $rel .= "../" if ("$_" ne "");
+ }
+ } elsif ($path =~ /^$base/) {
+ # case 2
+ $rel = $path;
+ $rel =~ s/^$base//;
+ $rel = "./$rel";
+ } else {
+ my $tmp = $base;
+ foreach (split('/', $tmp)) {
+ $rel .= "../" if ("$_" ne "");
+ }
+ $rel .= $path;
+ }
+ $rel =~ s/\/\//\//g; # simplify
+ $rel =~ s/\/$//; # don't end with /
+ return $rel;
+}
+
+sub parseMakeOutput
+{
+ print "Parsing GNU Make output to figure out build structure...\n";
+ my $line = 0;
+ while (my $text = shift @makedry) {
+ my $ate_next;
+ do {
+ $ate_next = 0;
+ $line++;
+ chomp $text;
+ chop $text if ($text =~ /\r$/);
+ if ($text =~ /\\$/) {
+ $text =~ s/\\$//;
+ $text .= shift @makedry;
+ $ate_next = 1;
+ }
+ } while($ate_next);
+
+ if($text =~ / -c /) {
+ # compilation
+ handleCompileLine($text, $line);
+
+ } elsif ($text =~ / -o /) {
+ # linking executable
+ handleLinkLine($text, $line);
+
+ } elsif ($text =~ /\.o / && $text =~ /\.a /) {
+ # libifying
+ handleLibLine($text, $line);
+#
+# } elsif ($text =~ /^cp /) {
+# # copy file around
+#
+# } elsif ($text =~ /^rm -f /) {
+# # shell command
+#
+# } elsif ($text =~ /^make[ \[]/) {
+# # make output
+#
+# } elsif ($text =~ /^echo /) {
+# # echo to file
+#
+# } elsif ($text =~ /^if /) {
+# # shell conditional
+#
+# } elsif ($text =~ /^tclsh /) {
+# # translation stuff
+#
+# } elsif ($text =~ /^umask /) {
+# # handling boilerplates
+#
+# } elsif ($text =~ /\$\(\:\)/) {
+# # ignore
+#
+# } elsif ($text =~ /^FLAGS=/) {
+# # flags check for dependencies
+#
+# } elsif ($text =~ /^'\/usr\/bin\/perl' -MError -e/) {
+# # perl commands for copying files
+#
+# } elsif ($text =~ /generate-cmdlist\.sh/) {
+# # command for generating list of commands
+#
+# } elsif ($text =~ /^test / && $text =~ /|| rm -f /) {
+# # commands removing executables, if they exist
+#
+# } elsif ($text =~ /new locations or Tcl/) {
+# # command for detecting Tcl/Tk changes
+#
+# } elsif ($text =~ /mkdir -p/) {
+# # command creating path
+#
+# } elsif ($text =~ /: no custom templates yet/) {
+# # whatever
+#
+# } else {
+# print "Unhandled (line: $line): $text\n";
+ }
+ }
+
+# use Data::Dumper;
+# print "Parsed build structure:\n";
+# print Dumper(%build_structure);
+}
+
+# variables for the compilation part of each step
+my (@defines, @incpaths, @cflags, @sources);
+
+sub clearCompileStep
+{
+ @defines = ();
+ @incpaths = ();
+ @cflags = ();
+ @sources = ();
+}
+
+sub removeDuplicates
+{
+ my (%dupHash, $entry);
+ %dupHash = map { $_, 1 } @defines;
+ @defines = keys %dupHash;
+
+ %dupHash = map { $_, 1 } @incpaths;
+ @incpaths = keys %dupHash;
+
+ %dupHash = map { $_, 1 } @cflags;
+ @cflags = keys %dupHash;
+}
+
+sub handleCompileLine
+{
+ my ($line, $lineno) = @_;
+ my @parts = split(' ', $line);
+ my $sourcefile;
+ shift(@parts); # ignore cmd
+ while (my $part = shift @parts) {
+ if ("$part" eq "-o") {
+ # ignore object file
+ shift @parts;
+ } elsif ("$part" eq "-c") {
+ # ignore compile flag
+ } elsif ("$part" eq "-c") {
+ } elsif ($part =~ /^.?-I/) {
+ push(@incpaths, $part);
+ } elsif ($part =~ /^.?-D/) {
+ push(@defines, $part);
+ } elsif ($part =~ /^-/) {
+ push(@cflags, $part);
+ } elsif ($part =~ /\.(c|cc|cpp)$/) {
+ $sourcefile = $part;
+ } else {
+ die "Unhandled compiler option @ line $lineno: $part";
+ }
+ }
+ @{$compile_options{"${sourcefile}_CFLAGS"}} = @cflags;
+ @{$compile_options{"${sourcefile}_DEFINES"}} = @defines;
+ @{$compile_options{"${sourcefile}_INCPATHS"}} = @incpaths;
+ clearCompileStep();
+}
+
+sub handleLibLine
+{
+ my ($line, $lineno) = @_;
+ my (@objfiles, @lflags, $libout, $part);
+ # kill cmd and rm 'prefix'
+ $line =~ s/^rm -f .* && .* rcs //;
+ my @parts = split(' ', $line);
+ while ($part = shift @parts) {
+ if ($part =~ /^-/) {
+ push(@lflags, $part);
+ } elsif ($part =~ /\.(o|obj)$/) {
+ push(@objfiles, $part);
+ } elsif ($part =~ /\.(a|lib)$/) {
+ $libout = $part;
+ $libout =~ s/\.a$//;
+ } else {
+ die "Unhandled lib option @ line $lineno: $part";
+ }
+ }
+# print "LibOut: '$libout'\nLFlags: @lflags\nOfiles: @objfiles\n";
+# exit(1);
+ foreach (@objfiles) {
+ my $sourcefile = $_;
+ $sourcefile =~ s/\.o/.c/;
+ push(@sources, $sourcefile);
+ push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}});
+ push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}});
+ push(@incpaths, @{$compile_options{"${sourcefile}_INCPATHS"}});
+ }
+ removeDuplicates();
+
+ push(@{$build_structure{"LIBS"}}, $libout);
+ @{$build_structure{"LIBS_${libout}"}} = ("_DEFINES", "_INCLUDES", "_CFLAGS", "_SOURCES",
+ "_OBJECTS");
+ @{$build_structure{"LIBS_${libout}_DEFINES"}} = @defines;
+ @{$build_structure{"LIBS_${libout}_INCLUDES"}} = @incpaths;
+ @{$build_structure{"LIBS_${libout}_CFLAGS"}} = @cflags;
+ @{$build_structure{"LIBS_${libout}_LFLAGS"}} = @lflags;
+ @{$build_structure{"LIBS_${libout}_SOURCES"}} = @sources;
+ @{$build_structure{"LIBS_${libout}_OBJECTS"}} = @objfiles;
+ clearCompileStep();
+}
+
+sub handleLinkLine
+{
+ my ($line, $lineno) = @_;
+ my (@objfiles, @lflags, @libs, $appout, $part);
+ my @parts = split(' ', $line);
+ shift(@parts); # ignore cmd
+ while ($part = shift @parts) {
+ if ($part =~ /^-IGNORE/) {
+ push(@lflags, $part);
+ } elsif ($part =~ /^-[GRIMDO]/) {
+ # eat compiler flags
+ } elsif ("$part" eq "-o") {
+ $appout = shift @parts;
+ } elsif ("$part" eq "-lz") {
+ push(@libs, "zlib.lib");
+ } elsif ("$part" eq "-lcrypto") {
+ push(@libs, "libeay32.lib");
+ push(@libs, "ssleay32.lib");
+ } elsif ($part =~ /^-/) {
+ push(@lflags, $part);
+ } elsif ($part =~ /\.(a|lib)$/) {
+ $part =~ s/\.a$/.lib/;
+ push(@libs, $part);
+ } elsif ($part =~ /\.(o|obj)$/) {
+ push(@objfiles, $part);
+ } else {
+ die "Unhandled lib option @ line $lineno: $part";
+ }
+ }
+# print "AppOut: '$appout'\nLFlags: @lflags\nLibs : @libs\nOfiles: @objfiles\n";
+# exit(1);
+ foreach (@objfiles) {
+ my $sourcefile = $_;
+ $sourcefile =~ s/\.o/.c/;
+ push(@sources, $sourcefile);
+ push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}});
+ push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}});
+ push(@incpaths, @{$compile_options{"${sourcefile}_INCPATHS"}});
+ }
+ removeDuplicates();
+
+ removeDuplicates();
+ push(@{$build_structure{"APPS"}}, $appout);
+ @{$build_structure{"APPS_${appout}"}} = ("_DEFINES", "_INCLUDES", "_CFLAGS", "_LFLAGS",
+ "_SOURCES", "_OBJECTS", "_LIBS");
+ @{$build_structure{"APPS_${appout}_DEFINES"}} = @defines;
+ @{$build_structure{"APPS_${appout}_INCLUDES"}} = @incpaths;
+ @{$build_structure{"APPS_${appout}_CFLAGS"}} = @cflags;
+ @{$build_structure{"APPS_${appout}_LFLAGS"}} = @lflags;
+ @{$build_structure{"APPS_${appout}_SOURCES"}} = @sources;
+ @{$build_structure{"APPS_${appout}_OBJECTS"}} = @objfiles;
+ @{$build_structure{"APPS_${appout}_LIBS"}} = @libs;
+ clearCompileStep();
+}
diff --git a/contrib/buildsystems/generate b/contrib/buildsystems/generate
new file mode 100644
index 0000000000..bc10f25ff2
--- /dev/null
+++ b/contrib/buildsystems/generate
@@ -0,0 +1,29 @@
+#!/usr/bin/perl -w
+######################################################################
+# Generate buildsystem files
+#
+# This script generate buildsystem files based on the output of a
+# GNU Make --dry-run, enabling Windows users to develop Git with their
+# trusted IDE with native projects.
+#
+# Note:
+# It is not meant as *the* way of building Git with MSVC, but merely a
+# convenience. The correct way of building Git with MSVC is to use the
+# GNU Make tool to build with the maintained Makefile in the root of
+# the project. If you have the msysgit environment installed and
+# available in your current console, together with the Visual Studio
+# environment you wish to build for, all you have to do is run the
+# command:
+# make MSVC=1
+#
+# Copyright (C) 2009 Marius Storm-Olsen <mstormo@gmail.com>
+######################################################################
+use strict;
+use File::Basename;
+use Cwd;
+
+my $git_dir = getcwd();
+$git_dir =~ s=\\=/=g;
+$git_dir = dirname($git_dir) while (!-e "$git_dir/git.c" && "$git_dir" ne "");
+die "Couldn't find Git repo" if ("$git_dir" eq "");
+exec join(" ", ("PERL5LIB=${git_dir}/contrib/buildsystems ${git_dir}/contrib/buildsystems/engine.pl", @ARGV));
diff --git a/contrib/buildsystems/parse.pl b/contrib/buildsystems/parse.pl
new file mode 100644
index 0000000000..c9656ece99
--- /dev/null
+++ b/contrib/buildsystems/parse.pl
@@ -0,0 +1,228 @@
+#!/usr/bin/perl -w
+######################################################################
+# Do not call this script directly!
+#
+# The generate script ensures that @INC is correct before the engine
+# is executed.
+#
+# Copyright (C) 2009 Marius Storm-Olsen <mstormo@gmail.com>
+######################################################################
+use strict;
+use File::Basename;
+use Cwd;
+
+my $file = $ARGV[0];
+die "No file provided!" if !defined $file;
+
+my ($cflags, $target, $type, $line);
+
+open(F, "<$file") || die "Couldn't open file $file";
+my @data = <F>;
+close(F);
+
+while (my $text = shift @data) {
+ my $ate_next;
+ do {
+ $ate_next = 0;
+ $line++;
+ chomp $text;
+ chop $text if ($text =~ /\r$/);
+ if ($text =~ /\\$/) {
+ $text =~ s/\\$//;
+ $text .= shift @data;
+ $ate_next = 1;
+ }
+ } while($ate_next);
+
+ if($text =~ / -c /) {
+ # compilation
+ handleCompileLine($text, $line);
+
+ } elsif ($text =~ / -o /) {
+ # linking executable
+ handleLinkLine($text, $line);
+
+ } elsif ($text =~ /\.o / && $text =~ /\.a /) {
+ # libifying
+ handleLibLine($text, $line);
+
+# } elsif ($text =~ /^cp /) {
+# # copy file around
+#
+# } elsif ($text =~ /^rm -f /) {
+# # shell command
+#
+# } elsif ($text =~ /^make[ \[]/) {
+# # make output
+#
+# } elsif ($text =~ /^echo /) {
+# # echo to file
+#
+# } elsif ($text =~ /^if /) {
+# # shell conditional
+#
+# } elsif ($text =~ /^tclsh /) {
+# # translation stuff
+#
+# } elsif ($text =~ /^umask /) {
+# # handling boilerplates
+#
+# } elsif ($text =~ /\$\(\:\)/) {
+# # ignore
+#
+# } elsif ($text =~ /^FLAGS=/) {
+# # flags check for dependencies
+#
+# } elsif ($text =~ /^'\/usr\/bin\/perl' -MError -e/) {
+# # perl commands for copying files
+#
+# } elsif ($text =~ /generate-cmdlist\.sh/) {
+# # command for generating list of commands
+#
+# } elsif ($text =~ /^test / && $text =~ /|| rm -f /) {
+# # commands removing executables, if they exist
+#
+# } elsif ($text =~ /new locations or Tcl/) {
+# # command for detecting Tcl/Tk changes
+#
+# } elsif ($text =~ /mkdir -p/) {
+# # command creating path
+#
+# } elsif ($text =~ /: no custom templates yet/) {
+# # whatever
+
+ } else {
+# print "Unhandled (line: $line): $text\n";
+ }
+}
+close(F);
+
+# use Data::Dumper;
+# print "Parsed build structure:\n";
+# print Dumper(%build_structure);
+
+# -------------------------------------------------------------------
+# Functions under here
+# -------------------------------------------------------------------
+my (%build_structure, @defines, @incpaths, @cflags, @sources);
+
+sub clearCompileStep
+{
+ @defines = ();
+ @incpaths = ();
+ @cflags = ();
+ @sources = ();
+}
+
+sub removeDuplicates
+{
+ my (%dupHash, $entry);
+ %dupHash = map { $_, 1 } @defines;
+ @defines = keys %dupHash;
+
+ %dupHash = map { $_, 1 } @incpaths;
+ @incpaths = keys %dupHash;
+
+ %dupHash = map { $_, 1 } @cflags;
+ @cflags = keys %dupHash;
+
+ %dupHash = map { $_, 1 } @sources;
+ @sources = keys %dupHash;
+}
+
+sub handleCompileLine
+{
+ my ($line, $lineno) = @_;
+ my @parts = split(' ', $line);
+ shift(@parts); # ignore cmd
+ while (my $part = shift @parts) {
+ if ("$part" eq "-o") {
+ # ignore object file
+ shift @parts;
+ } elsif ("$part" eq "-c") {
+ # ignore compile flag
+ } elsif ("$part" eq "-c") {
+ } elsif ($part =~ /^.?-I/) {
+ push(@incpaths, $part);
+ } elsif ($part =~ /^.?-D/) {
+ push(@defines, $part);
+ } elsif ($part =~ /^-/) {
+ push(@cflags, $part);
+ } elsif ($part =~ /\.(c|cc|cpp)$/) {
+ push(@sources, $part);
+ } else {
+ die "Unhandled compiler option @ line $lineno: $part";
+ }
+ }
+ #print "Sources: @sources\nCFlags: @cflags\nDefine: @defines\nIncpat: @incpaths\n";
+ #exit(1);
+}
+
+sub handleLibLine
+{
+ my ($line, $lineno) = @_;
+ my (@objfiles, @lflags, $libout, $part);
+ # kill cmd and rm 'prefix'
+ $line =~ s/^rm -f .* && .* rcs //;
+ my @parts = split(' ', $line);
+ while ($part = shift @parts) {
+ if ($part =~ /^-/) {
+ push(@lflags, $part);
+ } elsif ($part =~ /\.(o|obj)$/) {
+ push(@objfiles, $part);
+ } elsif ($part =~ /\.(a|lib)$/) {
+ $libout = $part;
+ } else {
+ die "Unhandled lib option @ line $lineno: $part";
+ }
+ }
+ #print "LibOut: '$libout'\nLFlags: @lflags\nOfiles: @objfiles\n";
+ #exit(1);
+ removeDuplicates();
+ push(@{$build_structure{"LIBS"}}, $libout);
+ @{$build_structure{"LIBS_${libout}"}} = ("_DEFINES", "_INCLUDES", "_CFLAGS", "_SOURCES",
+ "_OBJECTS");
+ @{$build_structure{"LIBS_${libout}_DEFINES"}} = @defines;
+ @{$build_structure{"LIBS_${libout}_INCLUDES"}} = @incpaths;
+ @{$build_structure{"LIBS_${libout}_CFLAGS"}} = @cflags;
+ @{$build_structure{"LIBS_${libout}_SOURCES"}} = @sources;
+ @{$build_structure{"LIBS_${libout}_OBJECTS"}} = @objfiles;
+ clearCompileStep();
+}
+
+sub handleLinkLine
+{
+ my ($line, $lineno) = @_;
+ my (@objfiles, @lflags, @libs, $appout, $part);
+ my @parts = split(' ', $line);
+ shift(@parts); # ignore cmd
+ while ($part = shift @parts) {
+ if ($part =~ /^-[GRIDO]/) {
+ # eat compiler flags
+ } elsif ("$part" eq "-o") {
+ $appout = shift @parts;
+ } elsif ($part =~ /^-/) {
+ push(@lflags, $part);
+ } elsif ($part =~ /\.(a|lib)$/) {
+ push(@libs, $part);
+ } elsif ($part =~ /\.(o|obj)$/) {
+ push(@objfiles, $part);
+ } else {
+ die "Unhandled lib option @ line $lineno: $part";
+ }
+ }
+ #print "AppOut: '$appout'\nLFlags: @lflags\nLibs : @libs\nOfiles: @objfiles\n";
+ #exit(1);
+ removeDuplicates();
+ push(@{$build_structure{"APPS"}}, $appout);
+ @{$build_structure{"APPS_${appout}"}} = ("_DEFINES", "_INCLUDES", "_CFLAGS", "_LFLAGS",
+ "_SOURCES", "_OBJECTS", "_LIBS");
+ @{$build_structure{"APPS_${appout}_DEFINES"}} = @defines;
+ @{$build_structure{"APPS_${appout}_INCLUDES"}} = @incpaths;
+ @{$build_structure{"APPS_${appout}_CFLAGS"}} = @cflags;
+ @{$build_structure{"APPS_${appout}_LFLAGS"}} = @lflags;
+ @{$build_structure{"APPS_${appout}_SOURCES"}} = @sources;
+ @{$build_structure{"APPS_${appout}_OBJECTS"}} = @objfiles;
+ @{$build_structure{"APPS_${appout}_LIBS"}} = @libs;
+ clearCompileStep();
+}
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 2d2d5794ad..bd66639d48 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -496,7 +496,7 @@ __git_all_commands ()
return
fi
local i IFS=" "$'\n'
- for i in $(git help -a|egrep '^ ')
+ for i in $(git help -a|egrep '^ [a-zA-Z0-9]')
do
case $i in
*--*) : helper pattern;;
@@ -602,8 +602,12 @@ __git_aliases ()
{
local i IFS=$'\n'
for i in $(git --git-dir="$(__gitdir)" config --get-regexp "alias\..*" 2>/dev/null); do
- i="${i#alias.}"
- echo "${i/ */}"
+ case "$i" in
+ alias.*)
+ i="${i#alias.}"
+ echo "${i/ */}"
+ ;;
+ esac
done
}
@@ -620,8 +624,8 @@ __git_aliased_command ()
done
}
-# __git_find_subcommand requires 1 argument
-__git_find_subcommand ()
+# __git_find_on_cmdline requires 1 argument
+__git_find_on_cmdline ()
{
local word subcommand c=1
@@ -668,7 +672,7 @@ _git_am ()
--3way --committer-date-is-author-date --ignore-date
--ignore-whitespace --ignore-space-change
--interactive --keep --no-utf8 --signoff --utf8
- --whitespace=
+ --whitespace= --scissors
"
return
esac
@@ -740,7 +744,7 @@ _git_bisect ()
__git_has_doubledash && return
local subcommands="start bad good skip reset visualize replay log run"
- local subcommand="$(__git_find_subcommand "$subcommands")"
+ local subcommand="$(__git_find_on_cmdline "$subcommands")"
if [ -z "$subcommand" ]; then
__gitcomp "$subcommands"
return
@@ -810,7 +814,21 @@ _git_checkout ()
{
__git_has_doubledash && return
- __gitcomp "$(__git_refs)"
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --conflict=*)
+ __gitcomp "diff3 merge" "" "${cur##--conflict=}"
+ ;;
+ --*)
+ __gitcomp "
+ --quiet --ours --theirs --track --no-track --merge
+ --conflict= --patch
+ "
+ ;;
+ *)
+ __gitcomp "$(__git_refs)"
+ ;;
+ esac
}
_git_cherry ()
@@ -880,6 +898,7 @@ _git_commit ()
__gitcomp "
--all --author= --signoff --verify --no-verify
--edit --amend --include --only --interactive
+ --dry-run
"
return
esac
@@ -912,6 +931,8 @@ __git_diff_common_options="--stat --numstat --shortstat --summary
--inter-hunk-context=
--patience
--raw
+ --dirstat --dirstat= --dirstat-by-file
+ --dirstat-by-file= --cumulative
"
_git_diff ()
@@ -932,11 +953,13 @@ _git_diff ()
}
__git_mergetools_common="diffuse ecmerge emerge kdiff3 meld opendiff
- tkdiff vimdiff gvimdiff xxdiff araxis
+ tkdiff vimdiff gvimdiff xxdiff araxis p4merge
"
_git_difftool ()
{
+ __git_has_doubledash && return
+
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--tool=*)
@@ -944,11 +967,15 @@ _git_difftool ()
return
;;
--*)
- __gitcomp "--tool="
+ __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
+ --base --ours --theirs
+ --no-renames --diff-filter= --find-copies-harder
+ --relative --ignore-submodules
+ --tool="
return
;;
esac
- COMPREPLY=()
+ __git_complete_file
}
__git_fetch_options="
@@ -1048,7 +1075,8 @@ _git_grep ()
return
;;
esac
- COMPREPLY=()
+
+ __gitcomp "$(__git_refs)"
}
_git_help ()
@@ -1165,6 +1193,10 @@ _git_log ()
__gitcomp "$__git_log_date_formats" "" "${cur##--date=}"
return
;;
+ --decorate=*)
+ __gitcomp "long short" "" "${cur##--decorate=}"
+ return
+ ;;
--*)
__gitcomp "
$__git_log_common_options
@@ -1177,7 +1209,7 @@ _git_log ()
--pretty= --format= --oneline
--cherry-pick
--graph
- --decorate
+ --decorate --decorate=
--walk-reflogs
--parents --children
$merge
@@ -1192,7 +1224,7 @@ _git_log ()
__git_merge_options="
--no-commit --no-stat --log --no-log --squash --strategy
- --commit --stat --no-squash --ff --no-ff
+ --commit --stat --no-squash --ff --no-ff --ff-only
"
_git_merge ()
@@ -1297,8 +1329,18 @@ _git_rebase ()
fi
__git_complete_strategy && return
case "$cur" in
+ --whitespace=*)
+ __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
+ return
+ ;;
--*)
- __gitcomp "--onto --merge --strategy --interactive"
+ __gitcomp "
+ --onto --merge --strategy --interactive
+ --preserve-merges --stat --no-stat
+ --committer-date-is-author-date --ignore-date
+ --ignore-whitespace --whitespace=
+ "
+
return
esac
__gitcomp "$(__git_refs)"
@@ -1749,7 +1791,7 @@ _git_config ()
_git_remote ()
{
local subcommands="add rename rm show prune update set-head"
- local subcommand="$(__git_find_subcommand "$subcommands")"
+ local subcommand="$(__git_find_on_cmdline "$subcommands")"
if [ -z "$subcommand" ]; then
__gitcomp "$subcommands"
return
@@ -1773,6 +1815,11 @@ _git_remote ()
esac
}
+_git_replace ()
+{
+ __gitcomp "$(__git_refs)"
+}
+
_git_reset ()
{
__git_has_doubledash && return
@@ -1780,7 +1827,7 @@ _git_reset ()
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
- __gitcomp "--merge --mixed --hard --soft"
+ __gitcomp "--merge --mixed --hard --soft --patch"
return
;;
esac
@@ -1876,18 +1923,30 @@ _git_show_branch ()
_git_stash ()
{
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ local save_opts='--keep-index --no-keep-index --quiet --patch'
local subcommands='save list show apply clear drop pop create branch'
- local subcommand="$(__git_find_subcommand "$subcommands")"
+ local subcommand="$(__git_find_on_cmdline "$subcommands")"
if [ -z "$subcommand" ]; then
- __gitcomp "$subcommands"
+ case "$cur" in
+ --*)
+ __gitcomp "$save_opts"
+ ;;
+ *)
+ if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
+ __gitcomp "$subcommands"
+ else
+ COMPREPLY=()
+ fi
+ ;;
+ esac
else
- local cur="${COMP_WORDS[COMP_CWORD]}"
case "$subcommand,$cur" in
save,--*)
- __gitcomp "--keep-index"
+ __gitcomp "$save_opts"
;;
apply,--*|pop,--*)
- __gitcomp "--index"
+ __gitcomp "--index --quiet"
;;
show,--*|drop,--*|branch,--*)
COMPREPLY=()
@@ -1908,7 +1967,7 @@ _git_submodule ()
__git_has_doubledash && return
local subcommands="add status init update summary foreach sync"
- if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
+ if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
@@ -1930,7 +1989,7 @@ _git_svn ()
proplist show-ignore show-externals branch tag blame
migrate
"
- local subcommand="$(__git_find_subcommand "$subcommands")"
+ local subcommand="$(__git_find_on_cmdline "$subcommands")"
if [ -z "$subcommand" ]; then
__gitcomp "$subcommands"
else
@@ -2129,6 +2188,7 @@ _git ()
push) _git_push ;;
rebase) _git_rebase ;;
remote) _git_remote ;;
+ replace) _git_replace ;;
reset) _git_reset ;;
revert) _git_revert ;;
rm) _git_rm ;;
diff --git a/contrib/emacs/git-blame.el b/contrib/emacs/git-blame.el
index 4fa70c5ad4..7f4c792978 100644
--- a/contrib/emacs/git-blame.el
+++ b/contrib/emacs/git-blame.el
@@ -80,6 +80,57 @@
(eval-when-compile (require 'cl)) ; to use `push', `pop'
+(defface git-blame-prefix-face
+ '((((background dark)) (:foreground "gray"
+ :background "black"))
+ (((background light)) (:foreground "gray"
+ :background "white"))
+ (t (:weight bold)))
+ "The face used for the hash prefix."
+ :group 'git-blame)
+
+(defgroup git-blame nil
+ "A minor mode showing Git blame information."
+ :group 'git
+ :link '(function-link git-blame-mode))
+
+
+(defcustom git-blame-use-colors t
+ "Use colors to indicate commits in `git-blame-mode'."
+ :type 'boolean
+ :group 'git-blame)
+
+(defcustom git-blame-prefix-format
+ "%h %20A:"
+ "The format of the prefix added to each line in `git-blame'
+mode. The format is passed to `format-spec' with the following format keys:
+
+ %h - the abbreviated hash
+ %H - the full hash
+ %a - the author name
+ %A - the author email
+ %c - the committer name
+ %C - the committer email
+ %s - the commit summary
+"
+ :group 'git-blame)
+
+(defcustom git-blame-mouseover-format
+ "%h %a %A: %s"
+ "The format of the description shown when pointing at a line in
+`git-blame' mode. The format string is passed to `format-spec'
+with the following format keys:
+
+ %h - the abbreviated hash
+ %H - the full hash
+ %a - the author name
+ %A - the author email
+ %c - the committer name
+ %C - the committer email
+ %s - the commit summary
+"
+ :group 'git-blame)
+
(defun git-blame-color-scale (&rest elements)
"Given a list, returns a list of triples formed with each
@@ -302,72 +353,69 @@ See also function `git-blame-mode'."
(src-line (string-to-number (match-string 2)))
(res-line (string-to-number (match-string 3)))
(num-lines (string-to-number (match-string 4))))
- (setq git-blame-current
- (if (string= hash "0000000000000000000000000000000000000000")
- nil
- (git-blame-new-commit
- hash src-line res-line num-lines))))
- (delete-region (point) (match-end 0))
- t)
- ((looking-at "filename \\(.+\\)\n")
- (let ((filename (match-string 1)))
- (git-blame-add-info "filename" filename))
- (delete-region (point) (match-end 0))
+ (delete-region (point) (match-end 0))
+ (setq git-blame-current (list (git-blame-new-commit hash)
+ src-line res-line num-lines)))
t)
((looking-at "\\([a-z-]+\\) \\(.+\\)\n")
(let ((key (match-string 1))
(value (match-string 2)))
- (git-blame-add-info key value))
- (delete-region (point) (match-end 0))
- t)
- ((looking-at "boundary\n")
- (setq git-blame-current nil)
- (delete-region (point) (match-end 0))
+ (delete-region (point) (match-end 0))
+ (git-blame-add-info (car git-blame-current) key value)
+ (when (string= key "filename")
+ (git-blame-create-overlay (car git-blame-current)
+ (caddr git-blame-current)
+ (cadddr git-blame-current))
+ (setq git-blame-current nil)))
t)
(t
nil)))
-(defun git-blame-new-commit (hash src-line res-line num-lines)
+(defun git-blame-new-commit (hash)
+ (with-current-buffer git-blame-file
+ (or (gethash hash git-blame-cache)
+ ;; Assign a random color to each new commit info
+ ;; Take care not to select the same color multiple times
+ (let* ((color (if git-blame-colors
+ (git-blame-random-pop git-blame-colors)
+ git-blame-ancient-color))
+ (info `(,hash (color . ,color))))
+ (puthash hash info git-blame-cache)
+ info))))
+
+(defun git-blame-create-overlay (info start-line num-lines)
(save-excursion
(set-buffer git-blame-file)
- (let ((info (gethash hash git-blame-cache))
- (inhibit-point-motion-hooks t)
+ (let ((inhibit-point-motion-hooks t)
(inhibit-modification-hooks t))
- (when (not info)
- ;; Assign a random color to each new commit info
- ;; Take care not to select the same color multiple times
- (let ((color (if git-blame-colors
- (git-blame-random-pop git-blame-colors)
- git-blame-ancient-color)))
- (setq info (list hash src-line res-line num-lines
- (git-describe-commit hash)
- (cons 'color color))))
- (puthash hash info git-blame-cache))
- (goto-line res-line)
- (while (> num-lines 0)
- (if (get-text-property (point) 'git-blame)
- (forward-line)
- (let* ((start (point))
- (end (progn (forward-line 1) (point)))
- (ovl (make-overlay start end)))
- (push ovl git-blame-overlays)
- (overlay-put ovl 'git-blame info)
- (overlay-put ovl 'help-echo hash)
+ (goto-line start-line)
+ (let* ((start (point))
+ (end (progn (forward-line num-lines) (point)))
+ (ovl (make-overlay start end))
+ (hash (car info))
+ (spec `((?h . ,(substring hash 0 6))
+ (?H . ,hash)
+ (?a . ,(git-blame-get-info info 'author))
+ (?A . ,(git-blame-get-info info 'author-mail))
+ (?c . ,(git-blame-get-info info 'committer))
+ (?C . ,(git-blame-get-info info 'committer-mail))
+ (?s . ,(git-blame-get-info info 'summary)))))
+ (push ovl git-blame-overlays)
+ (overlay-put ovl 'git-blame info)
+ (overlay-put ovl 'help-echo
+ (format-spec git-blame-mouseover-format spec))
+ (if git-blame-use-colors
(overlay-put ovl 'face (list :background
- (cdr (assq 'color (nthcdr 5 info)))))
- ;; the point-entered property doesn't seem to work in overlays
- ;;(overlay-put ovl 'point-entered
- ;; `(lambda (x y) (git-blame-identify ,hash)))
- (let ((modified (buffer-modified-p)))
- (put-text-property (if (= start 1) start (1- start)) (1- end)
- 'point-entered
- `(lambda (x y) (git-blame-identify ,hash)))
- (set-buffer-modified-p modified))))
- (setq num-lines (1- num-lines))))))
-
-(defun git-blame-add-info (key value)
- (if git-blame-current
- (nconc git-blame-current (list (cons (intern key) value)))))
+ (cdr (assq 'color (cdr info))))))
+ (overlay-put ovl 'line-prefix
+ (propertize (format-spec git-blame-prefix-format spec)
+ 'face 'git-blame-prefix-face))))))
+
+(defun git-blame-add-info (info key value)
+ (nconc info (list (cons (intern key) value))))
+
+(defun git-blame-get-info (info key)
+ (cdr (assq key (cdr info))))
(defun git-blame-current-commit ()
(let ((info (get-char-property (point) 'git-blame)))
diff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh
index e9588eec33..500635fe4b 100755
--- a/contrib/examples/git-merge.sh
+++ b/contrib/examples/git-merge.sh
@@ -14,7 +14,7 @@ summary (synonym to --stat)
log add list of one-line log to merge commit message
squash create a single commit instead of doing a merge
commit perform a commit if the merge succeeds (default)
-ff allow fast forward (default)
+ff allow fast-forward (default)
s,strategy= merge strategy to use
m,message= message to be used for the merge commit (if any)
"
@@ -353,7 +353,7 @@ t,1,"$head",*)
# Again the most common case of merging one remote.
echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $1)"
git update-index --refresh 2>/dev/null
- msg="Fast forward"
+ msg="Fast-forward"
if test -n "$have_message"
then
msg="$msg (no commit created; -m option ignored)"
@@ -365,11 +365,11 @@ t,1,"$head",*)
exit 0
;;
?,1,?*"$LF"?*,*)
- # We are not doing octopus and not fast forward. Need a
+ # We are not doing octopus and not fast-forward. Need a
# real merge.
;;
?,1,*,)
- # We are not doing octopus, not fast forward, and have only
+ # We are not doing octopus, not fast-forward, and have only
# one common.
git update-index --refresh 2>/dev/null
case "$allow_trivial_merge" in
diff --git a/contrib/examples/git-resolve.sh b/contrib/examples/git-resolve.sh
index 0ee1bd898e..8f98142f77 100755
--- a/contrib/examples/git-resolve.sh
+++ b/contrib/examples/git-resolve.sh
@@ -48,7 +48,7 @@ case "$common" in
"$head")
echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $merge)"
git read-tree -u -m $head $merge || exit 1
- git update-ref -m "resolve $merge_name: Fast forward" \
+ git update-ref -m "resolve $merge_name: Fast-forward" \
HEAD "$merge" "$head"
git diff-tree -p $head $merge | git apply --stat
dropheads
diff --git a/contrib/fast-import/import-tars.perl b/contrib/fast-import/import-tars.perl
index a909716682..95438e1ed4 100755
--- a/contrib/fast-import/import-tars.perl
+++ b/contrib/fast-import/import-tars.perl
@@ -20,7 +20,7 @@ use Getopt::Long;
my $metaext = '';
-die "usage: import-tars [--metainfo=extension] *.tar.{gz,bz2,Z}\n"
+die "usage: import-tars [--metainfo=extension] *.tar.{gz,bz2,lzma,xz,Z}\n"
unless GetOptions('metainfo=s' => \$metaext) && @ARGV;
my $branch_name = 'import-tars';
@@ -49,6 +49,9 @@ foreach my $tar_file (@ARGV)
} elsif ($tar_name =~ s/\.tar\.Z$//) {
open(I, '-|', 'uncompress', '-c', $tar_file)
or die "Unable to uncompress -c $tar_file: $!\n";
+ } elsif ($tar_name =~ s/\.(tar\.(lzma|xz)|(tlz|txz))$//) {
+ open(I, '-|', 'xz', '-dc', $tar_file)
+ or die "Unable to xz -dc $tar_file: $!\n";
} elsif ($tar_name =~ s/\.tar$//) {
open(I, $tar_file) or die "Unable to open $tar_file: $!\n";
} else {
@@ -140,7 +143,7 @@ foreach my $tar_file (@ARGV)
} elsif (!$header_done && /^Author:\s+([^<>]*)\s+<(.*)>\s*$/i) {
$this_author_name = $1;
$this_author_email = $2;
- } elsif (!$header_done && /^$/ { # empty line ends header.
+ } elsif (!$header_done && /^$/) { # empty line ends header.
$header_done = 1;
} else {
$commit_msg .= $_;
diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email
index 2a66063e44..58a35c8287 100755
--- a/contrib/hooks/post-receive-email
+++ b/contrib/hooks/post-receive-email
@@ -315,8 +315,8 @@ generate_update_branch_email()
# "remotes/" will be ignored as well.
# List all of the revisions that were removed by this update, in a
- # fast forward update, this list will be empty, because rev-list O
- # ^N is empty. For a non fast forward, O ^N is the list of removed
+ # fast-forward update, this list will be empty, because rev-list O
+ # ^N is empty. For a non-fast-forward, O ^N is the list of removed
# revisions
fast_forward=""
rev=""
@@ -411,7 +411,7 @@ generate_update_branch_email()
# revision because the base is effectively a random revision at this
# point - the user will be interested in what this revision changed
# - including the undoing of previous revisions in the case of
- # non-fast forward updates.
+ # non-fast-forward updates.
echo ""
echo "Summary of changes:"
git diff-tree --stat --summary --find-copies-harder $oldrev..$newrev