diff --git a/.gitignore b/.gitignore
index b2d74483331a25..466805c897bb51 100644
--- a/.gitignore
+++ b/.gitignore
@@ -186,6 +186,42 @@
/gitweb/static/gitweb.js
/gitweb/static/gitweb.min.*
/command-list.h
+/libgit
+/test-chmtime
+/test-ctype
+/test-config
+/test-date
+/test-delta
+/test-dump-cache-tree
+/test-dump-split-index
+/test-dump-untracked-cache
+/test-fake-ssh
+/test-scrap-cache-tree
+/test-genrandom
+/test-hashmap
+/test-index-version
+/test-line-buffer
+/test-match-trees
+/test-mergesort
+/test-mktemp
+/test-parse-options
+/test-path-utils
+/test-prio-queue
+/test-read-cache
+/test-regex
+/test-revision-walking
+/test-run-command
+/test-sha1
+/test-sha1-array
+/test-sigchain
+/test-string-list
+/test-submodule-config
+/test-subprocess
+/test-svn-fe
+/test-urlmatch-normalization
+/test-wildmatch
+/vcs-svn_lib
+/xdiff_lib
*.tar.gz
*.dsc
*.deb
@@ -224,6 +260,13 @@
*.idb
*.pdb
*.ilk
+*.iobj
+*.ipdb
+*.dll
.vs/
-/Debug/
-/Release/
+*.manifest
+Debug/
+Release/
+/UpgradeLog*.htm
+/git.VC.VC.opendb
+/git.VC.db
diff --git a/.nuget/NuGet.config b/.nuget/NuGet.config
new file mode 100644
index 00000000000000..93e50042cb7699
--- /dev/null
+++ b/.nuget/NuGet.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/Makefile b/Makefile
index 1c4f2b572e9f0d..96dd7b9908f255 100644
--- a/Makefile
+++ b/Makefile
@@ -2572,6 +2572,7 @@ GIT-BUILD-OPTIONS: FORCE
@echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@+
@echo PAGER_ENV=\''$(subst ','\'',$(subst ','\'',$(PAGER_ENV)))'\' >>$@+
@echo DC_SHA1=\''$(subst ','\'',$(subst ','\'',$(DC_SHA1)))'\' >>$@+
+ @echo X=\'$(X)\' >>$@+
ifdef TEST_OUTPUT_DIRECTORY
@echo TEST_OUTPUT_DIRECTORY=\''$(subst ','\'',$(subst ','\'',$(TEST_OUTPUT_DIRECTORY)))'\' >>$@+
endif
@@ -2606,6 +2607,9 @@ ifdef GIT_INTEROP_MAKE_OPTS
endif
ifdef TEST_GIT_INDEX_VERSION
@echo TEST_GIT_INDEX_VERSION=\''$(subst ','\'',$(subst ','\'',$(TEST_GIT_INDEX_VERSION)))'\' >>$@+
+endif
+ifdef MSVC_DEPS
+ @echo MSVC_DEPS=\''$(subst ','\'',$(subst ','\'',$(MSVC_DEPS)))'\' >>$@+
endif
@if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi
@@ -2630,7 +2634,7 @@ bin-wrappers/%: wrap-for-bin.sh
@mkdir -p bin-wrappers
$(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's|@@BUILD_DIR@@|$(shell pwd)|' \
- -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))|' < $< > $@ && \
+ -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%$(X),$(@F))$(patsubst git%,$(X),$(filter $(@F),$(BINDIR_PROGRAMS_NEED_X)))|' < $< > $@ && \
chmod +x $@
# GNU make supports exporting all variables by "export" without parameters.
diff --git a/compat/msvc.h b/compat/msvc.h
index b3ac4cc3affa47..d081043f539d27 100644
--- a/compat/msvc.h
+++ b/compat/msvc.h
@@ -6,6 +6,10 @@
#include
#include
+#pragma warning(disable: 4018) /* signed/unsigned comparison */
+#pragma warning(disable: 4244) /* type conversion, possible loss of data */
+#pragma warning(disable: 4090) /* 'function' : different 'const' qualifiers (ALLOC_GROW etc.)*/
+
/* porting function */
#define inline __inline
#define __inline__ __inline
diff --git a/compat/obstack.h b/compat/obstack.h
index 6bc24b76445686..f0807eaa3b899f 100644
--- a/compat/obstack.h
+++ b/compat/obstack.h
@@ -492,7 +492,7 @@ __extension__ \
( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
((((h)->temp.tempint > 0 \
&& (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
- ? (int) ((h)->next_free = (h)->object_base \
+ ? (ptrdiff_t) ((h)->next_free = (h)->object_base \
= (h)->temp.tempint + (char *) (h)->chunk) \
: (((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0)))
diff --git a/compat/terminal.c b/compat/terminal.c
index 1d37f0aafbaeb7..d9d3945afa391f 100644
--- a/compat/terminal.c
+++ b/compat/terminal.c
@@ -1,4 +1,6 @@
+#ifndef NO_INTTYPES_H
#include
+#endif
#include "git-compat-util.h"
#include "run-command.h"
#include "compat/terminal.h"
diff --git a/config.mak.uname b/config.mak.uname
index fbafa7943eba48..643b3917099e6f 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -1,5 +1,9 @@
# Platform specific Makefile tweaks based on uname detection
+# Define NO_SAFESEH if you need MSVC/Visual Studio to ignore the lack of
+# Microsoft's Safe Exception Handling in libraries (such as zlib).
+# Typically required for VS2013+/32-bit compilation on Vista+ versions.
+
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not')
uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not')
@@ -361,6 +365,7 @@ ifeq ($(uname_S),Windows)
NEEDS_LIBICONV = YesPlease
NO_STRTOUMAX = YesPlease
NO_MKDTEMP = YesPlease
+ NO_INTTYPES_H = YesPlease
# VS2015 with UCRT claims that snprintf and friends are C99 compliant,
# so we don't need this.
#
@@ -396,6 +401,9 @@ ifeq ($(uname_S),Windows)
compat/win32/dirent.o compat/win32/fscache.o
COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DDETECT_MSYS_TTY -DNOGDI -DHAVE_STRING_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\"
BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE
+ # invalidcontinue.obj allows Git's source code to close the same file
+ # handle twice, or to access the osfhandle of an already-closed stdout
+ # See https://msdn.microsoft.com/en-us/library/ms235330.aspx
EXTLIBS = user32.lib advapi32.lib shell32.lib wininet.lib ws2_32.lib invalidcontinue.obj kernel32.lib ntdll.lib
PTHREAD_LIBS =
lib =
@@ -428,6 +436,11 @@ ifeq ($(uname_S),Windows)
# release mode) to force a PDB to be generated (like RelWithDebInfo).
BASIC_CFLAGS += -Zi
BASIC_LDFLAGS += -debug
+
+ifdef NO_SAFESEH
+ LDFLAGS += -SAFESEH:NO
+endif
+
ifndef DEBUG
BASIC_CFLAGS += -GL -Gy -O2 -Oy- -MD -DNDEBUG
BASIC_LDFLAGS += -release -LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO /DEBUGTYPE:CV,FIXUP
@@ -438,6 +451,80 @@ endif
X = .exe
compat/msvc.o: compat/msvc.c compat/mingw.c GIT-CFLAGS
+
+vcxproj:
+ # Require clean work tree
+ git update-index -q --refresh && \
+ git diff-files --quiet && \
+ git diff-index --cached --quiet HEAD --
+
+ # Make .vcxproj files and add them
+ unset QUIET_GEN QUIET_BUILT_IN; \
+ perl contrib/buildsystems/generate -g Vcxproj
+ git add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj
+
+ # Generate the LinkOrCopyBuiltins.targets file
+ (echo '' && \
+ echo ' ' && \
+ for name in $(BUILT_INS);\
+ do \
+ echo ' '; \
+ done && \
+ for name in $(REMOTE_CURL_ALIASES); \
+ do \
+ echo ' '; \
+ done && \
+ echo ' ' && \
+ echo '') >git/LinkOrCopyBuiltins.targets
+ git add -f git/LinkOrCopyBuiltins.targets
+
+ # Add command-list.h
+ $(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 command-list.h
+ git add -f command-list.h
+
+ # Add scripts
+ rm -f perl/perl.mak
+ $(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 \
+ $(SCRIPT_LIB) $(SCRIPT_SH_GEN) $(SCRIPT_PERL_GEN)
+ # Strip out the sane tool path, needed only for building
+ sed -i '/^git_broken_path_fix ".*/d' git-sh-setup
+ git add -f $(SCRIPT_LIB) $(SCRIPT_SH_GEN) $(SCRIPT_PERL_GEN)
+
+ # Add Perl module
+ $(MAKE) $(LIB_PERL_GEN)
+ git add -f perl/build
+
+ # Add bin-wrappers, for testing
+ rm -rf bin-wrappers/
+ $(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 $(test_bindir_programs)
+ # Ensure that the GIT_EXEC_PATH is a Unix-y one, and that the absolute
+ # path of the repository is not hard-coded (GIT_EXEC_PATH will be set
+ # by test-lib.sh according to the current setup)
+ sed -i -e 's/^\(GIT_EXEC_PATH\)=.*/test -n "$${\1##*:*}" ||\
+ \1="$$(cygpath -u "$$\1")"/' \
+ -e "s|'$$(pwd)|\"\$$GIT_EXEC_PATH\"'|g" bin-wrappers/*
+ # Ensure that test-* helpers find the .dll files copied to top-level
+ sed -i 's|^PATH=.*|&:"$$GIT_EXEC_PATH"|' bin-wrappers/test-*
+ # We do not want to force hard-linking builtins
+ sed -i 's|\(git\)-\([-a-z]*\)\.exe"|\1.exe" \2|g' \
+ bin-wrappers/git-{receive-pack,upload-archive}
+ git add -f $(test_bindir_programs)
+ # remote-ext is a builtin, but invoked as if it were external
+ sed 's|receive-pack|remote-ext|g' \
+ bin-wrappers/git-remote-ext
+ git add -f bin-wrappers/git-remote-ext
+
+ # Add templates
+ $(MAKE) -C templates
+ git add -f templates/boilerplates.made templates/blt/
+
+ # Add build options
+ $(MAKE) MSVC=1 SKIP_VCPKG=1 prefix=/mingw64 GIT-BUILD-OPTIONS
+ git add -f GIT-BUILD-OPTIONS
+
+ # Commit the whole shebang
+ git commit -m "Generate Visual Studio solution" \
+ -m "Auto-generated by \`$(MAKE)$(MAKEFLAGS) $@\`"
endif
ifeq ($(uname_S),Interix)
NO_INITGROUPS = YesPlease
diff --git a/contrib/buildsystems/Generators.pm b/contrib/buildsystems/Generators.pm
index 408ef714b8f0dc..aa4cbaa2adacb1 100644
--- a/contrib/buildsystems/Generators.pm
+++ b/contrib/buildsystems/Generators.pm
@@ -17,7 +17,7 @@ BEGIN {
$me = dirname($me);
if (opendir(D,"$me/Generators")) {
foreach my $gen (readdir(D)) {
- next if ($gen =~ /^\.\.?$/);
+ next unless ($gen =~ /\.pm$/);
require "${me}/Generators/$gen";
$gen =~ s,\.pm,,;
push(@AVAILABLE, $gen);
diff --git a/contrib/buildsystems/Generators/Vcproj.pm b/contrib/buildsystems/Generators/Vcproj.pm
index cfa74adcc23881..1c61ea6b938561 100644
--- a/contrib/buildsystems/Generators/Vcproj.pm
+++ b/contrib/buildsystems/Generators/Vcproj.pm
@@ -52,7 +52,6 @@ my @GUIDS = (
"{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}",
@@ -63,7 +62,14 @@ my @GUIDS = (
"{294BDC5A-F448-48B6-8110-DD0A81820F8C}",
"{4B9F66E9-FAC9-47AB-B1EF-C16756FBFD06}",
"{72EA49C6-2806-48BD-B81B-D4905102E19C}",
- "{5728EB7E-8929-486C-8CD5-3238D060E768}"
+ "{5728EB7E-8929-486C-8CD5-3238D060E768}",
+ "{A3E300FC-5630-4850-A470-E9F2C2EFA7E7}",
+ "{CEA071D4-D9F3-4250-98F7-44AFDC8ACAA1}",
+ "{3FD87BB4-2236-4A1B-ADD2-46211A302442}",
+ "{49B03F41-5157-4079-95A7-64D728BCF74F}",
+ "{95D5A28B-80E2-40A9-BEA3-C52B9CA488E3}",
+ "{B85E6545-D523-4323-9F29-45389D090343}",
+ "{06840CEF-746C-4B71-9442-C395DD6590A5}"
);
sub generate {
@@ -106,6 +112,8 @@ sub createLibProject {
my $includes= join(";", sort(map(""$rel_dir\\$_"", @{$$build_structure{"LIBS_${libname}_INCLUDES"}})));
my $cflags = join(" ", sort(@{$$build_structure{"LIBS_${libname}_CFLAGS"}}));
$cflags =~ s/\"/"/g;
+ $cflags =~ s/</g;
+ $cflags =~ s/>/>/g;
my $cflags_debug = $cflags;
$cflags_debug =~ s/-MT/-MTd/;
@@ -127,6 +135,8 @@ sub createLibProject {
$defines =~ s/-D//g;
$defines =~ s/\"/\\"/g;
+ $defines =~ s/</g;
+ $defines =~ s/>/>/g;
$defines =~ s/\'//g;
$includes =~ s/-I//g;
mkdir "$target" || die "Could not create the directory $target for lib project!\n";
@@ -162,9 +172,6 @@ sub createLibProject {
-
@@ -228,9 +235,6 @@ sub createLibProject {
-
@@ -325,6 +329,8 @@ sub createAppProject {
my $includes= join(";", sort(map(""$rel_dir\\$_"", @{$$build_structure{"APPS_${appname}_INCLUDES"}})));
my $cflags = join(" ", sort(@{$$build_structure{"APPS_${appname}_CFLAGS"}}));
$cflags =~ s/\"/"/g;
+ $cflags =~ s/</g;
+ $cflags =~ s/>/>/g;
my $cflags_debug = $cflags;
$cflags_debug =~ s/-MT/-MTd/;
@@ -351,6 +357,8 @@ sub createAppProject {
$defines =~ s/-D//g;
$defines =~ s/\"/\\"/g;
+ $defines =~ s/</g;
+ $defines =~ s/>/>/g;
$defines =~ s/\'//g;
$defines =~ s/\\\\/\\/g;
$includes =~ s/-I//g;
@@ -387,9 +395,6 @@ sub createAppProject {
-
@@ -458,9 +463,6 @@ sub createAppProject {
-
@@ -561,20 +563,18 @@ sub createGlueProject {
foreach (@apps) {
$_ =~ s/\//_/g;
$_ =~ s/\.exe//;
- push(@tmp, $_);
+ if ($_ eq "git" ) {
+ unshift(@tmp, $_);
+ } else {
+ 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) {
@@ -588,6 +588,13 @@ sub createGlueProject {
print F " EndProjectSection";
print F "$SLN_POST";
}
+ 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";
+ }
print F << "EOM";
Global
@@ -599,17 +606,17 @@ EOM
print F << "EOM";
GlobalSection(ProjectConfigurationPlatforms) = postSolution
EOM
- foreach (@libs) {
- my $libname = $_;
- my $uuid = $build_structure{"LIBS_${libname}_GUID"};
+ 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";
}
- foreach (@apps) {
- my $appname = $_;
- my $uuid = $build_structure{"APPS_${appname}_GUID"};
+ 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";
diff --git a/contrib/buildsystems/Generators/Vcxproj.pm b/contrib/buildsystems/Generators/Vcxproj.pm
new file mode 100644
index 00000000000000..bcbb71410b7ee9
--- /dev/null
+++ b/contrib/buildsystems/Generators/Vcxproj.pm
@@ -0,0 +1,447 @@
+package Generators::Vcxproj;
+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}",
+ "{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}",
+ "{A3E300FC-5630-4850-A470-E9F2C2EFA7E7}",
+ "{CEA071D4-D9F3-4250-98F7-44AFDC8ACAA1}",
+ "{3FD87BB4-2236-4A1B-ADD2-46211A302442}",
+ "{49B03F41-5157-4079-95A7-64D728BCF74F}",
+ "{95D5A28B-80E2-40A9-BEA3-C52B9CA488E3}",
+ "{B85E6545-D523-4323-9F29-45389D090343}",
+ "{06840CEF-746C-4B71-9442-C395DD6590A5}"
+);
+
+sub generate {
+ my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
+ my @libs = @{$build_structure{"LIBS"}};
+ foreach (@libs) {
+ createProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure, 1);
+ }
+
+ my @apps = @{$build_structure{"APPS"}};
+ foreach (@apps) {
+ createProject($_, $git_dir, $out_dir, $rel_dir, \%build_structure, 0);
+ }
+
+ createGlueProject($git_dir, $out_dir, $rel_dir, %build_structure);
+ return 0;
+}
+
+sub createProject {
+ my ($name, $git_dir, $out_dir, $rel_dir, $build_structure, $static_library) = @_;
+ my $label = $static_library ? "lib" : "app";
+ my $prefix = $static_library ? "LIBS_" : "APPS_";
+ my $config_type = $static_library ? "StaticLibrary" : "Application";
+ print "Generate $name vcxproj $label project\n";
+ my $cdup = $name;
+ $cdup =~ s/[^\/]+/../g;
+ $cdup =~ s/\//\\/g;
+ $rel_dir = $rel_dir eq "." ? $cdup : "$cdup\\$rel_dir";
+ $rel_dir =~ s/\//\\/g;
+
+ my $target = $name;
+ if ($static_library) {
+ $target =~ s/\.a//;
+ } else {
+ $target =~ s/\.exe//;
+ }
+
+ my $uuid = $GUIDS[$guid_index++];
+ $$build_structure{"$prefix${target}_GUID"} = $uuid;
+ my $vcxproj = $target;
+ $vcxproj =~ s/(.*\/)?(.*)/$&\/$2.vcxproj/;
+ $vcxproj =~ s/([^\/]*)(\/lib)\/(lib.vcxproj)/$1$2\/$1_$3/;
+ $$build_structure{"$prefix${target}_VCXPROJ"} = $vcxproj;
+
+ my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"$prefix${name}_SOURCES"}}));
+ my @sources;
+ foreach (@srcs) {
+ $_ =~ s/\//\\/g;
+ push(@sources, $_);
+ }
+ my $defines = join(";", sort(@{$$build_structure{"$prefix${name}_DEFINES"}}));
+ my $includes= join(";", sort(map { s/^-I//; s/\//\\/g; File::Spec->file_name_is_absolute($_) ? $_ : "$rel_dir\\$_" } @{$$build_structure{"$prefix${name}_INCLUDES"}}));
+ my $cflags = join(" ", sort(map { s/^-[GLMOZ].*//; s/.* .*/"$&"/; $_; } @{$$build_structure{"$prefix${name}_CFLAGS"}}));
+ $cflags =~ s/\"/"/g;
+ $cflags =~ s/</g;
+ $cflags =~ s/>/>/g;
+
+ my $libs = '';
+ if (!$static_library) {
+ $libs = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib|libcurl\.lib|libeay32\.lib|libiconv\.lib|ssleay32\.lib|zlib\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}}));
+ }
+
+ $defines =~ s/-D//g;
+ $defines =~ s/\"/"/g;
+ $defines =~ s/</g;
+ $defines =~ s/>/>/g;
+ $defines =~ s/\'//g;
+
+ die "Could not create the directory $target for $label project!\n" unless (-d "$target" || mkdir "$target");
+
+ use File::Copy;
+ copy("$git_dir/compat/vcbuild/packages.config", "$target/packages.config");
+
+ my $needsCurl = grep(/libcurl.lib/, @{$$build_structure{"$prefix${name}_LIBS"}});
+ my $targetsImport = '';
+ my $targetsErrors = '';
+ my $afterTargets = '';
+ open F, "<$git_dir/compat/vcbuild/packages.config";
+ while () {
+ if (/";
+ } elsif ($needsCurl && $1 eq 'curl') {
+ # libcurl is only available targeting v100 and v110
+ $libs .= ";$rel_dir\\compat\\vcbuild\\GEN.PKGS\\$1.$2\\build\\native\\lib\\v110\\\$(Platform)\\Release\\dynamic\\libcurl.lib";
+ $afterTargets .= "\n ";
+ } elsif ($needsCurl && $1 eq 'expat') {
+ # libexpat is only available targeting v100 and v110
+ $libs .= ";$rel_dir\\compat\\vcbuild\\GEN.PKGS\\$1.$2\\build\\native\\lib\\v110\\\$(Platform)\\Release\\dynamic\\utf8\\libexpat.lib";
+ }
+ next if ($1 =~ /^(zlib$|openssl(?!.*(x64|x86)$))/);
+ my $targetsFile = "$rel_dir\\compat\\vcbuild\\GEN.PKGS\\$1.$2\\build\\native\\$1.targets";
+ $targetsImport .= "\n ";
+ $targetsErrors .= "\n ";
+ }
+ }
+ close F;
+
+ open F, ">$vcxproj" or die "Could not open $vcxproj for writing!\n";
+ binmode F, ":crlf :utf8";
+ print F chr(0xFEFF);
+ print F << "EOM";
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ $uuid
+ Win32Proj
+
+
+
+ true
+ true
+
+
+ false
+ true
+
+
+ $config_type
+ v140
+
+ ..\\
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ true
+
+
+
+ $cflags %(AdditionalOptions)
+ $includes;%(AdditionalIncludeDirectories)
+
+ true
+ OnlyExplicitInline
+
+ ProgramDatabase
+
+
+ true
+
+
+ $libs;\$(AdditionalDependencies)
+ invalidcontinue.obj %(AdditionalOptions)
+ $cdup\\compat\\win32\\git.manifest
+ Console
+
+
+
+
+ MachineX86
+
+
+
+
+ Disabled
+ WIN32;_DEBUG;$defines;%(PreprocessorDefinitions)
+ MultiThreadedDebugDLL
+
+
+ true
+
+
+
+
+ MaxSpeed
+ true
+ WIN32;NDEBUG;$defines;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+ true
+ Speed
+
+
+ true
+ true
+ true
+
+
+
+EOM
+ foreach(@sources) {
+ print F << "EOM";
+
+EOM
+ }
+ print F << "EOM";
+
+EOM
+ if (!$static_library) {
+ my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"};
+ my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"};
+
+ print F << "EOM";
+
+
+ $uuid_libgit
+ false
+
+
+ $uuid_xdiff_lib
+ false
+
+EOM
+ if ($name =~ /(test-(line-buffer|svn-fe)|^git-remote-testsvn)\.exe$/) {
+ my $uuid_vcs_svn_lib = $$build_structure{"LIBS_vcs-svn/lib_GUID"};
+ print F << "EOM";
+
+ $uuid_vcs_svn_lib
+ false
+
+EOM
+ }
+ print F << "EOM";
+
+EOM
+ }
+ print F << "EOM";
+
+
+
+
+ $targetsImport
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+ $targetsErrors
+
+EOM
+ if (!$static_library && $afterTargets ne '') {
+ print F << "EOM";
+ $afterTargets
+
+EOM
+ }
+ print F << "EOM";
+
+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 11.00\n# Visual Studio 2010\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/\.a//;
+ push(@tmp, $_);
+ }
+ @libs = @tmp;
+
+ my @apps = @{$build_structure{"APPS"}};
+ @tmp = ();
+ foreach (@apps) {
+ $_ =~ s/\.exe//;
+ if ($_ eq "git" ) {
+ unshift(@tmp, $_);
+ } else {
+ push(@tmp, $_);
+ }
+ }
+ @apps = @tmp;
+
+ open F, ">git.sln" || die "Could not open git.sln for writing!\n";
+ binmode F, ":crlf :utf8";
+ print F chr(0xFEFF);
+ print F "$SLN_HEAD";
+
+ foreach (@apps) {
+ my $appname = $_;
+ my $uuid = $build_structure{"APPS_${appname}_GUID"};
+ print F "$SLN_PRE";
+ my $vcxproj = $build_structure{"APPS_${appname}_VCXPROJ"};
+ $vcxproj =~ s/\//\\/g;
+ $appname =~ s/.*\///;
+ print F "\"${appname}\", \"${vcxproj}\", \"${uuid}\"";
+ print F "$SLN_POST";
+ }
+ foreach (@libs) {
+ my $libname = $_;
+ my $uuid = $build_structure{"LIBS_${libname}_GUID"};
+ print F "$SLN_PRE";
+ my $vcxproj = $build_structure{"LIBS_${libname}_VCXPROJ"};
+ $vcxproj =~ s/\//\\/g;
+ $libname =~ s/\//_/g;
+ print F "\"${libname}\", \"${vcxproj}\", \"${uuid}\"";
+ print F "$SLN_POST";
+ }
+
+ print F << "EOM";
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+EOM
+ print F << "EOM";
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+EOM
+ foreach (@apps) {
+ my $appname = $_;
+ my $uuid = $build_structure{"APPS_${appname}_GUID"};
+ print F "\t\t${uuid}.Debug|x64.ActiveCfg = Debug|x64\n";
+ print F "\t\t${uuid}.Debug|x64.Build.0 = Debug|x64\n";
+ print F "\t\t${uuid}.Debug|x86.ActiveCfg = Debug|Win32\n";
+ print F "\t\t${uuid}.Debug|x86.Build.0 = Debug|Win32\n";
+ print F "\t\t${uuid}.Release|x64.ActiveCfg = Release|x64\n";
+ print F "\t\t${uuid}.Release|x64.Build.0 = Release|x64\n";
+ print F "\t\t${uuid}.Release|x86.ActiveCfg = Release|Win32\n";
+ print F "\t\t${uuid}.Release|x86.Build.0 = Release|Win32\n";
+ }
+ foreach (@libs) {
+ my $libname = $_;
+ my $uuid = $build_structure{"LIBS_${libname}_GUID"};
+ print F "\t\t${uuid}.Debug|x64.ActiveCfg = Debug|x64\n";
+ print F "\t\t${uuid}.Debug|x64.Build.0 = Debug|x64\n";
+ print F "\t\t${uuid}.Debug|x86.ActiveCfg = Debug|Win32\n";
+ print F "\t\t${uuid}.Debug|x86.Build.0 = Debug|Win32\n";
+ print F "\t\t${uuid}.Release|x64.ActiveCfg = Release|x64\n";
+ print F "\t\t${uuid}.Release|x64.Build.0 = Release|x64\n";
+ print F "\t\t${uuid}.Release|x86.ActiveCfg = Release|Win32\n";
+ print F "\t\t${uuid}.Release|x86.Build.0 = Release|Win32\n";
+ }
+
+ print F << "EOM";
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
+EOM
+ close F;
+}
+
+1;
diff --git a/contrib/buildsystems/engine.pl b/contrib/buildsystems/engine.pl
index 53e65d4db713c3..6cfaedb029364d 100755
--- a/contrib/buildsystems/engine.pl
+++ b/contrib/buildsystems/engine.pl
@@ -12,6 +12,7 @@
use File::Spec;
use Cwd;
use Generators;
+use Text::ParseWords;
my (%build_structure, %compile_options, @makedry);
my $out_dir = getcwd();
@@ -31,6 +32,7 @@ sub showUsage
-g --gen Specify the buildsystem generator (default: $gen)
Available: $genlist
-o --out Specify output directory generation (default: .)
+ --make-out Write the output of GNU Make into a file
-i --in Specify input file, instead of running GNU Make
-h,-? --help This help
EOM
@@ -38,6 +40,7 @@ sub showUsage
}
# Parse command-line options
+my $make_out;
while (@ARGV) {
my $arg = shift @ARGV;
if ("$arg" eq "-h" || "$arg" eq "--help" || "$arg" eq "-?") {
@@ -45,6 +48,8 @@ sub showUsage
exit(0);
} elsif("$arg" eq "--out" || "$arg" eq "-o") {
$out_dir = shift @ARGV;
+ } elsif("$arg" eq "--make-out") {
+ $make_out = shift @ARGV;
} elsif("$arg" eq "--gen" || "$arg" eq "-g") {
$gen = shift @ARGV;
} elsif("$arg" eq "--in" || "$arg" eq "-i") {
@@ -72,7 +77,18 @@ sub showUsage
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;
+# Capture the make dry stderr to file for review (will be empty for a release build).
+
+my $ErrsFile = "msvc-build-makedryerrors.txt";
+@makedry = `cd $git_dir && make -n MSVC=1 V=1 2>$ErrsFile` if !@makedry;
+# test for an empty Errors file and remove it
+unlink $ErrsFile if -f -z $ErrsFile;
+
+if (defined $make_out) {
+ open OUT, ">" . $make_out;
+ print OUT @makedry;
+ close OUT;
+}
# Parse the make output into usable info
parseMakeOutput();
@@ -140,6 +156,12 @@ sub parseMakeOutput
next;
}
+ if ($text =~ /^(mkdir|msgfmt) /) {
+ # options to the Portable Object translations
+ # the line "mkdir ... && msgfmt ..." contains no linker options
+ next;
+ }
+
if($text =~ / -c /) {
# compilation
handleCompileLine($text, $line);
@@ -231,7 +253,7 @@ sub removeDuplicates
sub handleCompileLine
{
my ($line, $lineno) = @_;
- my @parts = split(' ', $line);
+ my @parts = shellwords($line);
my $sourcefile;
shift(@parts); # ignore cmd
while (my $part = shift @parts) {
@@ -265,7 +287,7 @@ sub handleLibLine
my (@objfiles, @lflags, $libout, $part);
# kill cmd and rm 'prefix'
$line =~ s/^rm -f .* && .* rcs //;
- my @parts = split(' ', $line);
+ my @parts = shellwords($line);
while ($part = shift @parts) {
if ($part =~ /^-/) {
push(@lflags, $part);
@@ -306,7 +328,7 @@ sub handleLinkLine
{
my ($line, $lineno) = @_;
my (@objfiles, @lflags, @libs, $appout, $part);
- my @parts = split(' ', $line);
+ my @parts = shellwords($line);
shift(@parts); # ignore cmd
while ($part = shift @parts) {
if ($part =~ /^-IGNORE/) {
@@ -317,11 +339,15 @@ sub handleLinkLine
$appout = shift @parts;
} elsif ("$part" eq "-lz") {
push(@libs, "zlib.lib");
- } elsif ("$part" eq "-lcrypto") {
+ } elsif ("$part" eq "-lcrypto") {
push(@libs, "libeay32.lib");
} elsif ("$part" eq "-lssl") {
push(@libs, "ssleay32.lib");
- } elsif ($part =~ /^-/) {
+ } elsif ("$part" eq "-lcurl") {
+ push(@libs, "libcurl.lib");
+ } elsif ("$part" eq "-liconv") {
+ push(@libs, "libiconv.lib");
+ } elsif ($part =~ /^[-\/]/) {
push(@lflags, $part);
} elsif ($part =~ /\.(a|lib)$/) {
$part =~ s/\.a$/.lib/;
@@ -333,7 +359,7 @@ sub handleLinkLine
} elsif ($part =~ /\.obj$/) {
# do nothing, 'make' should not be producing .obj, only .o files
} else {
- die "Unhandled lib option @ line $lineno: $part";
+ die "Unhandled link option @ line $lineno: $part";
}
}
# print "AppOut: '$appout'\nLFlags: @lflags\nLibs : @libs\nOfiles: @objfiles\n";
diff --git a/git.c b/git.c
index a6f4b44af52062..4224bc0d9a2b6f 100644
--- a/git.c
+++ b/git.c
@@ -688,6 +688,31 @@ static int run_argv(int *argcp, const char ***argv)
*/
if (!done_alias)
handle_builtin(*argcp, *argv);
+ else if (get_builtin(**argv)) {
+ struct argv_array args = ARGV_ARRAY_INIT;
+ int i;
+
+ if (get_super_prefix())
+ die("%s doesn't support --super-prefix", **argv);
+
+ commit_pager_choice();
+
+ argv_array_push(&args, "git");
+ for (i = 0; i < *argcp; i++)
+ argv_array_push(&args, (*argv)[i]);
+
+ trace_argv_printf(args.argv, "trace: exec:");
+
+ /*
+ * if we fail because the command is not found, it is
+ * OK to return. Otherwise, we just pass along the status code.
+ */
+ i = run_command_v_opt(args.argv, RUN_SILENT_EXEC_FAILURE |
+ RUN_CLEAN_ON_EXIT);
+ if (i >= 0 || errno != ENOENT)
+ exit(i);
+ die("could not execute builtin %s", **argv);
+ }
/* .. then try the external ones */
execv_dashed_external(*argv);
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 241e6a319df4ce..e50a69bbdfaed3 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -824,6 +824,7 @@ test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' '
(
cd six &&
git remote rm origin &&
+ mkdir -p .git/branches &&
echo "$origin_url" >.git/branches/origin &&
git remote rename origin origin &&
test_path_is_missing .git/branches/origin &&
@@ -838,6 +839,7 @@ test_expect_success 'migrate a remote from named file in $GIT_DIR/branches (2)'
(
cd seven &&
git remote rm origin &&
+ mkdir -p .git/branches &&
echo "quux#foom" > .git/branches/origin &&
git remote rename origin origin &&
test_path_is_missing .git/branches/origin &&
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 539c25aadafdcf..f123f0e3d9d4f1 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -866,6 +866,7 @@ test_expect_success 'fetch with branches' '
mk_empty testrepo &&
git branch second $the_first_commit &&
git checkout second &&
+ mkdir -p testrepo/.git/branches &&
echo ".." > testrepo/.git/branches/branch1 &&
(
cd testrepo &&
@@ -879,6 +880,7 @@ test_expect_success 'fetch with branches' '
test_expect_success 'fetch with branches containing #' '
mk_empty testrepo &&
+ mkdir -p testrepo/.git/branches &&
echo "..#second" > testrepo/.git/branches/branch2 &&
(
cd testrepo &&
@@ -893,6 +895,7 @@ test_expect_success 'fetch with branches containing #' '
test_expect_success 'push with branches' '
mk_empty testrepo &&
git checkout second &&
+ mkdir -p .git/branches &&
echo "testrepo" > .git/branches/branch1 &&
git push branch1 &&
(
@@ -905,6 +908,7 @@ test_expect_success 'push with branches' '
test_expect_success 'push with branches containing #' '
mk_empty testrepo &&
+ mkdir -p .git/branches &&
echo "testrepo#branch3" > .git/branches/branch2 &&
git push branch2 &&
(
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index d82fac9d790b93..eeda970e121ef5 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -900,7 +900,7 @@ test_create_repo () {
mkdir -p "$repo"
(
cd "$repo" || error "Cannot setup test environment"
- "$GIT_EXEC_PATH/git-init" "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
+ "$GIT_EXEC_PATH/git$X" init "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
error "cannot run git init -- have you built things yet?"
mv .git/hooks .git/hooks-disabled
) || exit
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 6182d981456b70..23c41ff5b36c61 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -49,18 +49,26 @@ export ASAN_OPTIONS
: ${LSAN_OPTIONS=abort_on_error=1}
export LSAN_OPTIONS
+if test ! -f "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
+then
+ echo >&2 'error: GIT-BUILD-OPTIONS missing (has Git been built?).'
+ exit 1
+fi
+. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
+export PERL_PATH SHELL_PATH
+
+test -z "$MSVC_DEPS" ||
+PATH="$GIT_BUILD_DIR/$MSVC_DEPS/bin:$PATH"
+
################################################################
# It appears that people try to run tests without building...
-"$GIT_BUILD_DIR/git" >/dev/null
+"$GIT_BUILD_DIR/git$X" >/dev/null
if test $? != 1
then
echo >&2 'error: you do not seem to have built git yet.'
exit 1
fi
-. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
-export PERL_PATH SHELL_PATH
-
# if --tee was passed, write the output not only to the terminal, but
# additionally to the file test-results/$BASENAME.out, too.
case "$GIT_TEST_TEE_STARTED, $* " in