Skip to contentSkip to conversation

Reinstate support for Visual Studio

PATCH Superseded Johannes Schindelin via GitGitGadget 5 participants 63 messages Jul 18, 2019 – Aug 28, 2019 Kbuild

lore
Share & tools
lore
#0 lore raw

cover Reinstate support for Visual Studio

A long time ago, we added support to build .sln and .vcproj files for use within Visual Studio, so that Git could be built in that popular IDE.

This support languished for years and was finally brought back into Git for Windows partially through the jh/msvc branch that was just merged into master. With the tremendous help by Philip Oakley and Jeff Hostetler, this re-adds support for Visual Studio, focusing on VS 2015 and later (older versions are currently unsupported, even if we worked a bit on that front, too; If there are volunteers to add support for older versions, I would be delighted to review PRs to that end on
https://github.com/git-for-windows/git).

Note: the currently preferred way to contribute using Visual Studio is by using Git for Windows' vs/master branch (which is automatically generated using the make vcxproj build target that this patch series adds, updated every time Git for Windows' master advances). My plan is to provide a similar branch in GitGitGadget, based on top of git.git's master, once this patch series is integrated.

Johannes Schindelin (15):
Vcproj.pm: auto-generate GUIDs
Vcproj.pm: do not configure VCWebServiceProxyGeneratorTool Vcproj.pm: urlencode '<' and '>' when generating VC projects contrib/buildsystems: ignore irrelevant files in Generators/ contrib/buildsystems: error out on unknown option contrib/buildsystems: handle libiconv, too contrib/buildsystems: also handle -lexpat contrib/buildsystems: handle options starting with a slash contrib/buildsystems: add a backend for modern Visual Studio versions
msvc: add a Makefile target to pre-generate the Visual Studio solution
vcxproj: also link-or-copy builtins
.gitignore: ignore Visual Studio's temporary/generated files
bin-wrappers: append .exe to target paths if necessary t5505,t5516: create .git/branches/ when needed
git: avoid calling aliased builtins via their dashed form

Philip Oakley (9):
Vcproj.pm: list git.exe first to be startup project contrib/buildsystems: ignore invalidcontinue.obj contrib/buildsystems: fix misleading error message contrib/buildsystems: handle quoted spaces in filenames contrib/buildsystems: ignore gettext stuff contrib/buildsystems: redirect errors of the dry run into a log file contrib/buildsystems: optionally capture the dry-run in a file contrib/buildsystems: handle the curl library option .gitignore: touch up the entries regarding Visual Studio

 .gitignore                                 |   8 +-
 Makefile                                   |   2 +-
 compat/vcbuild/README                      |  23 ++
 config.mak.uname                           |  76 ++++
 contrib/buildsystems/Generators.pm         |   2 +-
 contrib/buildsystems/Generators/Vcproj.pm  | 119 ++-----
 contrib/buildsystems/Generators/Vcxproj.pm | 387 +++++++++++++++++++++
 contrib/buildsystems/engine.pl             |  55 ++-
 git.c                                      |   3 -
 t/t5505-remote.sh                          |   2 +
 t/t5516-fetch-push.sh                      |   4 +
 11 files changed, 581 insertions(+), 100 deletions(-)
 create mode 100644 contrib/buildsystems/Generators/Vcxproj.pm

base-commit: 9d418600f4d10dcbbfb0b5fdbc71d509e03ba719
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-287%2Fdscho%2Fvisual-studio-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-287/dscho/visual-studio-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/287

Signature · 1 line
gitgitgadget
#1 lore raw

PATCH 1/24 Vcproj.pm: auto-generate GUIDs

From: Johannes Schindelin <[email protected]>

We ran out GUIDs. Again. But there is no need to: we can generate them semi-randomly from the target file name of the project.

Note: the Vcproj generator is probably only interesting for historical reasons; nevertheless, the upcoming Vcxproj generator (to support modern Visual Studio versions) is based on the Vcproj generator and it is better to fix this here first.

---
 contrib/buildsystems/Generators/Vcproj.pm | 66 ++++-------------------
 1 file changed, 9 insertions(+), 57 deletions(-)
contrib/buildsystems/Generators/Vcproj.pm +9 -57
index cfa74adcc2..c79b706bc8 100644
@@ -3,6 +3,7 @@ package Generators::Vcproj;
 
 use strict;
 use vars qw($VERSION);
+use Digest::SHA qw(sha256_hex);
 
 our $VERSION = '1.00';
 our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
@@ -12,59 +13,12 @@ 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_guid ($) {
+    my $hex = sha256_hex($_[0]);
+    $hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*/{$1-$2-$3-$4-$5}/;
+    $hex =~ tr/a-z/A-Z/;
+    return $hex;
+}
 
 sub generate {
     my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
@@ -92,9 +46,8 @@ sub createLibProject {
     $target =~ s/\//_/g;
     $target =~ s/\.a//;
 
-    my $uuid = $GUIDS[$guid_index];
+    my $uuid = generate_guid($libname);
     $$build_structure{"LIBS_${target}_GUID"} = $uuid;
-    $guid_index += 1;
 
     my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"LIBS_${libname}_SOURCES"}}));
     my @sources;
@@ -311,9 +264,8 @@ sub createAppProject {
     $target =~ s/\//_/g;
     $target =~ s/\.exe//;
 
-    my $uuid = $GUIDS[$guid_index];
+    my $uuid = generate_guid($appname);
     $$build_structure{"APPS_${target}_GUID"} = $uuid;
-    $guid_index += 1;
 
     my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"APPS_${appname}_SOURCES"}}));
     my @sources;
Signature · 1 line
gitgitgadget
#2 lore raw

PATCH 2/24 Vcproj.pm: list git.exe first to be startup project

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Visual Studio takes the first listed application/library as the default startup project [1].

Detect the 'git' project and place it at the head of the project list, rather than at the tail.

Export the apps list before libs list for both the projects and global structures of the .sln file.

[1] http://stackoverflow.com/questions/1238553/
vs2008-where-is-the-startup-project-setting-stored-for-a-solution
"In the solution file, there are a list of pseudo-XML "Project" entries. It turns out that whatever is the first one ends up as the Startup Project, unless it’s overridden in the suo file. Argh. I just rearranged the order in the file and it’s good."

"just moving the pseudo-xml isn't enough. You also have to move the group of entries in the "GlobalSection(ProjectConfigurationPlatforms) = postSolution" group that has the GUID of the project you moved to the top. So there are two places to move lines."

---
 contrib/buildsystems/Generators/Vcproj.pm | 33 +++++++++++++----------
 1 file changed, 19 insertions(+), 14 deletions(-)
contrib/buildsystems/Generators/Vcproj.pm +19 -14
index c79b706bc8..d862cae503 100644
@@ -513,20 +513,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) {
@@ -540,6 +538,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
@@ -551,17 +556,17 @@ sub createGlueProject {
     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";
Signature · 1 line
gitgitgadget
#3 lore raw

PATCH 3/24 Vcproj.pm: do not configure VCWebServiceProxyGeneratorTool

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

It is not necessary, and Visual Studio 2015 no longer supports it, anyway.

---
 contrib/buildsystems/Generators/Vcproj.pm | 12 ------------
 1 file changed, 12 deletions(-)
contrib/buildsystems/Generators/Vcproj.pm +0 -12
index d862cae503..b17800184c 100644
@@ -115,9 +115,6 @@ sub createLibProject {
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
 			<Tool
 				Name="VCMIDLTool"
 			/>
@@ -181,9 +178,6 @@ sub createLibProject {
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
 			<Tool
 				Name="VCMIDLTool"
 			/>
@@ -339,9 +333,6 @@ sub createAppProject {
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
 			<Tool
 				Name="VCMIDLTool"
 			/>
@@ -410,9 +401,6 @@ sub createAppProject {
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
 			<Tool
 				Name="VCMIDLTool"
 			/>
Signature · 1 line
gitgitgadget
#4 lore raw

PATCH 4/24 Vcproj.pm: urlencode '<' and '>' when generating VC projects

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

---
 contrib/buildsystems/Generators/Vcproj.pm | 8 ++++++++
 1 file changed, 8 insertions(+)
contrib/buildsystems/Generators/Vcproj.pm +8 -0
index b17800184c..737647e76a 100644
@@ -59,6 +59,8 @@ sub createLibProject {
     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;
+    $cflags =~ s/</&lt;/g;
+    $cflags =~ s/>/&gt;/g;
 
     my $cflags_debug = $cflags;
     $cflags_debug =~ s/-MT/-MTd/;
@@ -80,6 +82,8 @@ sub createLibProject {
 
     $defines =~ s/-D//g;
     $defines =~ s/\"/\\&quot;/g;
+    $defines =~ s/</&lt;/g;
+    $defines =~ s/>/&gt;/g;
     $defines =~ s/\'//g;
     $includes =~ s/-I//g;
     mkdir "$target" || die "Could not create the directory $target for lib project!\n";
@@ -271,6 +275,8 @@ sub createAppProject {
     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;
+    $cflags =~ s/</&lt;/g;
+    $cflags =~ s/>/&gt;/g;
 
     my $cflags_debug = $cflags;
     $cflags_debug =~ s/-MT/-MTd/;
@@ -297,6 +303,8 @@ sub createAppProject {
 
     $defines =~ s/-D//g;
     $defines =~ s/\"/\\&quot;/g;
+    $defines =~ s/</&lt;/g;
+    $defines =~ s/>/&gt;/g;
     $defines =~ s/\'//g;
     $defines =~ s/\\\\/\\/g;
     $includes =~ s/-I//g;
Signature · 1 line
gitgitgadget
#5 lore raw

PATCH 5/24 contrib/buildsystems: ignore invalidcontinue.obj

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Since 4b623d8 (MSVC: link in invalidcontinue.obj for better POSIX compatibility, 2014-03-29), invalidcontinue.obj is linked in the MSVC build, but it was not parsed correctly by the buildsystem. Ignore it, as it is known to Visual Studio and will be handled elsewhere.

Also only substitute filenames ending with .o when generating the source .c filename, otherwise we would start to expect .cbj files to generate .obj files (which are not generated by our build)...

In the future there may be source files that produce .obj files so keep the two issues (.obj files with & without source files) separate.

---
 contrib/buildsystems/engine.pl | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
contrib/buildsystems/engine.pl +7 -3
index 23da787dc5..53e65d4db7 100755
@@ -282,7 +282,7 @@ sub handleLibLine
 #    exit(1);
     foreach (@objfiles) {
         my $sourcefile = $_;
-        $sourcefile =~ s/\.o/.c/;
+        $sourcefile =~ s/\.o$/.c/;
         push(@sources, $sourcefile);
         push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}});
         push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}});
@@ -326,8 +326,12 @@ sub handleLinkLine
         } elsif ($part =~ /\.(a|lib)$/) {
             $part =~ s/\.a$/.lib/;
             push(@libs, $part);
-        } elsif ($part =~ /\.(o|obj)$/) {
+        } elsif ($part eq 'invalidcontinue.obj') {
+            # ignore - known to MSVC
+        } elsif ($part =~ /\.o$/) {
             push(@objfiles, $part);
+        } elsif ($part =~ /\.obj$/) {
+            # do nothing, 'make' should not be producing .obj, only .o files
         } else {
             die "Unhandled lib option @ line $lineno: $part";
         }
@@ -336,7 +340,7 @@ sub handleLinkLine
 #    exit(1);
     foreach (@objfiles) {
         my $sourcefile = $_;
-        $sourcefile =~ s/\.o/.c/;
+        $sourcefile =~ s/\.o$/.c/;
         push(@sources, $sourcefile);
         push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}});
         push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}});
Signature · 1 line
gitgitgadget
#6 lore raw

PATCH 6/24 contrib/buildsystems: ignore irrelevant files in Generators/

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

The Generators/ directory can contain spurious files such as editors' backup files. Even worse, there could be .swp files which are not even valid Perl scripts.

Let's just ignore anything but .pm files in said directory.

---
 contrib/buildsystems/Generators.pm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/buildsystems/Generators.pm +1 -1
index 408ef714b8..aa4cbaa2ad 100644
@@ -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);
Signature · 1 line
gitgitgadget
#7 lore raw

PATCH 7/24 contrib/buildsystems: fix misleading error message

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

The error message talked about a "lib option", but it clearly referred to a link option.

---
 contrib/buildsystems/engine.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/buildsystems/engine.pl +1 -1
index 53e65d4db7..11f0e16dda 100755
@@ -333,7 +333,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";
Signature · 1 line
gitgitgadget
#8 lore raw

PATCH 8/24 contrib/buildsystems: handle quoted spaces in filenames

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

The engine.pl script expects file names not to contain spaces. However, paths with spaces are quite prevalent on Windows. Use shellwords() rather than split() to parse them correctly.

---
 contrib/buildsystems/engine.pl | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
contrib/buildsystems/engine.pl +4 -3
index 11f0e16dda..ad6a82c30c 100755
@@ -12,6 +12,7 @@
 use File::Spec;
 use Cwd;
 use Generators;
+use Text::ParseWords;
 
 my (%build_structure, %compile_options, @makedry);
 my $out_dir = getcwd();
@@ -231,7 +232,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 +266,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 +307,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/) {
Signature · 1 line
gitgitgadget
#9 lore raw

PATCH 9/24 contrib/buildsystems: ignore gettext stuff

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Git's build contains steps to handle internationalization. This caused hiccups in the parser used to generate QMake/Visual Studio project files.

As those steps are irrelevant in this context, let's just ignore them.

---
 contrib/buildsystems/engine.pl | 6 ++++++
 1 file changed, 6 insertions(+)
contrib/buildsystems/engine.pl +6 -0
index ad6a82c30c..9db3d43a1e 100755
@@ -141,6 +141,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);
Signature · 1 line
gitgitgadget
#10 lore raw

PATCH 10/24 contrib/buildsystems: redirect errors of the dry run into a log file

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Rather than swallowing the errors, it is better to have them in a file.

To make it obvious what this is about, use the file name 'msvc-build-makedryerrors.txt'.

Further, if the output is empty, simply delete that file. As we target Git for Windows' SDK (which, unlike its predecessor msysGit, offers Perl versions newer than 5.8), we can use the quite readable syntax if -f -z $ErrsFile (available in Perl >=5.10).

Note that the file will contain the new values of the GIT_VERSION and GITGUI_VERSION if they were generated by the make file. They are omitted if the release is tagged and indentically defined in their respective GIT_VERSION_GEN file DEF_VER variables.

---
 contrib/buildsystems/engine.pl | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
contrib/buildsystems/engine.pl +6 -1
index 9db3d43a1e..de5c0b6b25 100755
@@ -73,7 +73,12 @@ 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 = `make -C $git_dir -n MSVC=1 V=1 2>$ErrsFile` if !@makedry;
+# test for an empty Errors file and remove it
+unlink $ErrsFile if -f -z $ErrsFile;
 
 # Parse the make output into usable info
 parseMakeOutput();
Signature · 1 line
gitgitgadget
#11 lore raw

PATCH 11/24 contrib/buildsystems: optionally capture the dry-run in a file

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Add an option for capturing the output of the make dry-run used in determining the msvc-build structure for easy debugging.

You can use the output of --make-out <path> in subsequent runs via the --in <path> option.

---
 contrib/buildsystems/engine.pl | 10 ++++++++++
 1 file changed, 10 insertions(+)
contrib/buildsystems/engine.pl +10 -0
index de5c0b6b25..732239d817 100755
@@ -32,6 +32,7 @@ sub showUsage
   -g <GENERATOR>  --gen <GENERATOR> Specify the buildsystem generator    (default: $gen)
                                     Available: $genlist
   -o <PATH>       --out <PATH>      Specify output directory generation  (default: .)
+                  --make-out <PATH> Write the output of GNU Make into a file
   -i <FILE>       --in <FILE>       Specify input file, instead of running GNU Make
   -h,-?           --help            This help
 EOM
@@ -39,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 "-?") {
@@ -46,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") {
@@ -80,6 +84,12 @@ sub showUsage
 # 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();
 
Signature · 1 line
gitgitgadget
#12 lore raw

PATCH 12/24 contrib/buildsystems: error out on unknown option

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

One time too many did this developer call the generate script passing a --make-out=<PATH> option that was happily ignored (because there should be a space, not an equal sign, between --make-out and the path).

And one time too many, this script not only ignored it but did not even complain. Let's fix that.

---
 contrib/buildsystems/engine.pl | 2 ++
 1 file changed, 2 insertions(+)
contrib/buildsystems/engine.pl +2 -0
index 732239d817..1a12f4d556 100755
@@ -57,6 +57,8 @@ sub showUsage
         open(F, "<$infile") || die "Couldn't open file $infile";
         @makedry = <F>;
         close(F);
+    } else {
+        die "Unknown option: " . $arg;
     }
 }
 
Signature · 1 line
gitgitgadget
#13 lore raw

PATCH 13/24 contrib/buildsystems: handle the curl library option

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Upon seeing the '-lcurl' option, point to the libcurl.lib.

While there, fix the elsif indentation.

---
 contrib/buildsystems/engine.pl | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
contrib/buildsystems/engine.pl +3 -1
index 1a12f4d556..d613277595 100755
@@ -341,10 +341,12 @@ 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" eq "-lcurl") {
+            push(@libs, "libcurl.lib");
         } elsif ($part =~ /^-/) {
             push(@lflags, $part);
         } elsif ($part =~ /\.(a|lib)$/) {
Signature · 1 line
gitgitgadget
#14 lore raw

PATCH 14/24 contrib/buildsystems: handle libiconv, too

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

Git's test suite shows tons of breakages unless Git is compiled *without* NO_ICONV. That means, in turn, that we need to generate build definitions *with* libiconv, which in turn implies that we have to handle the -liconv option properly.

---
 contrib/buildsystems/engine.pl | 2 ++
 1 file changed, 2 insertions(+)
contrib/buildsystems/engine.pl +2 -0
index d613277595..c35844a0c7 100755
@@ -347,6 +347,8 @@ sub handleLinkLine
             push(@libs, "ssleay32.lib");
         } 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)$/) {
Signature · 1 line
gitgitgadget
#15 lore raw

PATCH 15/24 contrib/buildsystems: also handle -lexpat

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

This is a dependency required for the non-smart HTTP backend.

---
 contrib/buildsystems/engine.pl | 2 ++
 1 file changed, 2 insertions(+)
contrib/buildsystems/engine.pl +2 -0
index c35844a0c7..9bde7ae15b 100755
@@ -347,6 +347,8 @@ sub handleLinkLine
             push(@libs, "ssleay32.lib");
         } elsif ("$part" eq "-lcurl") {
             push(@libs, "libcurl.lib");
+        } elsif ("$part" eq "-lexpat") {
+            push(@libs, "expat.lib");
         } elsif ("$part" eq "-liconv") {
             push(@libs, "libiconv.lib");
         } elsif ($part =~ /^-/) {
Signature · 1 line
gitgitgadget
#16 lore raw

PATCH 16/24 contrib/buildsystems: handle options starting with a slash

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

With the recent changes to allow building with MSVC=1, we now pass the /OPT:REF option to the compiler. This confuses the parser that wants to turn the output of a dry run into project definitions for QMake and Visual Studio:

Unhandled link option @ line 213: /OPT:REF at [...]

Let's just extend the code that passes through options that start with a dash, so that it passes through options that start with a slash, too.

---
 contrib/buildsystems/engine.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/buildsystems/engine.pl +1 -1
index 9bde7ae15b..8bb07e8e25 100755
@@ -351,7 +351,7 @@ sub handleLinkLine
             push(@libs, "expat.lib");
         } elsif ("$part" eq "-liconv") {
             push(@libs, "libiconv.lib");
-        } elsif ($part =~ /^-/) {
+        } elsif ($part =~ /^[-\/]/) {
             push(@lflags, $part);
         } elsif ($part =~ /\.(a|lib)$/) {
             $part =~ s/\.a$/.lib/;
Signature · 1 line
gitgitgadget
#17 lore raw

PATCH 17/24 contrib/buildsystems: add a backend for modern Visual Studio versions

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

Based on the previous patches in this patch series that fixed the generator for .vcproj files (which were used by Visual Studio prior to 2015 to define projects), this patch offers to generate project definitions for neweer versions of Visual Studio (which use .vcxproj files).

To that end, this patch copy-edits the generator of the .vcproj.

In addition, we now use the vcpkg system which allows us to build Git's dependencies (e.g. curl, libexpat) conveniently. The support scripts were introduced in the jh/msvc patch series, and with this patch we initialize the vcpkg conditionally, in the libgit project's PreBuildEvent. To allow for parallel building of the projects, we therefore put libgit at the bottom of the project hierarchy.

---
 contrib/buildsystems/Generators/Vcxproj.pm | 384 +++++++++++++++++++++
 1 file changed, 384 insertions(+)
 create mode 100644 contrib/buildsystems/Generators/Vcxproj.pm
contrib/buildsystems/Generators/Vcxproj.pm new file +384 -0
new file mode 100644
index 0000000000..9e7ed24912
@@ -0,0 +1,384 @@
+package Generators::Vcxproj;
+require Exporter;
+
+use strict;
+use vars qw($VERSION);
+use Digest::SHA qw(sha256_hex);
+
+our $VERSION = '1.00';
+our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
+@ISA = qw(Exporter);
+
+BEGIN {
+    push @EXPORT_OK, qw(generate);
+}
+
+sub generate_guid ($) {
+	my $hex = sha256_hex($_[0]);
+	$hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*/{$1-$2-$3-$4-$5}/;
+	$hex =~ tr/a-z/A-Z/;
+	return $hex;
+}
+
+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 = generate_guid($name);
+    $$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/^-[GLMOWZ].*//; s/.* .*/"$&"/; $_; } @{$$build_structure{"$prefix${name}_CFLAGS"}}));
+    $cflags =~ s/</&lt;/g;
+    $cflags =~ s/>/&gt;/g;
+
+    my $libs_release = "\n    ";
+    my $libs_debug = "\n    ";
+    if (!$static_library) {
+      $libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}}));
+      $libs_debug = $libs_release;
+      $libs_debug =~ s/zlib\.lib/zlibd\.lib/;
+    }
+
+    $defines =~ s/-D//g;
+    $defines =~ s/</&lt;/g;
+    $defines =~ s/>/&gt;/g;
+    $defines =~ s/\'//g;
+
+    die "Could not create the directory $target for $label project!\n" unless (-d "$target" || mkdir "$target");
+
+    open F, ">$vcxproj" or die "Could not open $vcxproj for writing!\n";
+    binmode F, ":crlf :utf8";
+    print F chr(0xFEFF);
+    print F << "EOM";
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>$uuid</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <VCPKGArch Condition="'\$(Platform)'=='Win32'">x86-windows</VCPKGArch>
+    <VCPKGArch Condition="'\$(Platform)'!='Win32'">x64-windows</VCPKGArch>
+    <VCPKGArchDirectory>$cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)</VCPKGArchDirectory>
+    <VCPKGBinDirectory Condition="'\(Configuration)'=='Debug'">\$(VCPKGArchDirectory)\\debug\\bin</VCPKGBinDirectory>
+    <VCPKGLibDirectory Condition="'\(Configuration)'=='Debug'">\$(VCPKGArchDirectory)\\debug\\lib</VCPKGLibDirectory>
+    <VCPKGBinDirectory Condition="'\(Configuration)'!='Debug'">\$(VCPKGArchDirectory)\\bin</VCPKGBinDirectory>
+    <VCPKGLibDirectory Condition="'\(Configuration)'!='Debug'">\$(VCPKGArchDirectory)\\lib</VCPKGLibDirectory>
+    <VCPKGIncludeDirectory>\$(VCPKGArchDirectory)\\include</VCPKGIncludeDirectory>
+    <VCPKGLibs Condition="'\(Configuration)'=='Debug'">$libs_debug</VCPKGLibs>
+    <VCPKGLibs Condition="'\(Configuration)'!='Debug'">$libs_release</VCPKGLibs>
+  </PropertyGroup>
+  <Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'\$(Configuration)'=='Debug'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'\$(Configuration)'=='Release'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup>
+    <ConfigurationType>$config_type</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+    <!-- <CharacterSet>UTF-8</CharacterSet> -->
+    <OutDir>..\\</OutDir>
+    <!-- <IntDir>\$(ProjectDir)\$(Configuration)\\</IntDir> -->
+  </PropertyGroup>
+  <Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" Condition="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <GenerateManifest>false</GenerateManifest>
+    <EnableManagedIncrementalBuild>true</EnableManagedIncrementalBuild>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <AdditionalOptions>$cflags %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>$cdup;$cdup\\compat;$cdup\\compat\\regex;$cdup\\compat\\win32;$cdup\\compat\\poll;$cdup\\compat\\vcbuild\\include;\$(VCPKGIncludeDirectory);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <EnableParallelCodeGeneration />
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <PrecompiledHeader />
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+    <Link>
+      <AdditionalLibraryDirectories>\$(VCPKGLibDirectory);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>\$(VCPKGLibs);\$(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalOptions>invalidcontinue.obj %(AdditionalOptions)</AdditionalOptions>
+      <EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
+      <ManifestFile>$cdup\\compat\\win32\\git.manifest</ManifestFile>
+      <SubSystem>Console</SubSystem>
+    </Link>
+EOM
+    if ($target eq 'libgit') {
+        print F << "EOM";
+    <PreBuildEvent Condition="!Exists('$cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)\\include\\openssl\\ssl.h')">
+      <Message>Initialize VCPKG</Message>
+      <Command>del "$cdup\\compat\\vcbuild\\vcpkg"</Command>
+      <Command>call "$cdup\\compat\\vcbuild\\vcpkg_install.bat"</Command>
+    </PreBuildEvent>
+EOM
+    }
+    print F << "EOM";
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'\$(Platform)'=='Win32'">
+    <Link>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'\$(Configuration)'=='Debug'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;$defines;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'\$(Configuration)'=='Release'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;$defines;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+EOM
+    foreach(@sources) {
+        print F << "EOM";
+    <ClCompile Include="$_" />
+EOM
+    }
+    print F << "EOM";
+  </ItemGroup>
+EOM
+    if (!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') {
+      my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"};
+      my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"};
+
+      print F << "EOM";
+  <ItemGroup>
+    <ProjectReference Include="$cdup\\libgit\\libgit.vcxproj">
+      <Project>$uuid_libgit</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+EOM
+      if (!($name =~ 'xdiff')) {
+        print F << "EOM";
+    <ProjectReference Include="$cdup\\xdiff\\lib\\xdiff_lib.vcxproj">
+      <Project>$uuid_xdiff_lib</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+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";
+    <ProjectReference Include="$cdup\\vcs-svn\\lib\\vcs-svn_lib.vcxproj">
+      <Project>$uuid_vcs_svn_lib</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+EOM
+      }
+      print F << "EOM";
+  </ItemGroup>
+EOM
+    }
+    print F << "EOM";
+  <Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets" />
+EOM
+    if (!$static_library) {
+      print F << "EOM";
+  <Target Name="${target}_AfterBuild" AfterTargets="AfterBuild">
+    <ItemGroup>
+      <DLLsAndPDBs Include="\$(VCPKGBinDirectory)\\*.dll;\$(VCPKGBinDirectory)\\*.pdb" />
+    </ItemGroup>
+    <Copy SourceFiles="@(DLLsAndPDBs)" DestinationFolder="\$(OutDir)" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />
+  </Target>
+EOM
+    }
+    print F << "EOM";
+</Project>
+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;
Signature · 1 line
gitgitgadget
#18 lore raw

PATCH 18/24 msvc: add a Makefile target to pre-generate the Visual Studio solution

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

The entire idea of generating the VS solution makes only sense if we generate it via Continuous Integration; otherwise potential users would still have to download the entire Git for Windows SDK.

If we pre-generate the Visual Studio solution, Git can be built entirely within Visual Studio, and the test scripts can be run in a regular Git for Windows (e.g. the Portable Git flavor, which does not include a full GCC toolchain and therefore weighs only about a tenth of Git for Windows' SDK).

So let's just add a target in the Makefile that can be used to generate said solution; The generated files will then be committed so that they can be pushed to a branch ready to check out by Visual Studio users.

To make things even more useful, we also generate and commit other files that are required to run the test suite, such as templates and
bin-wrappers: with this, developers can run the test suite in a regular Git Bash after building the solution in Visual Studio.

Note: for this build target, we do not actually need to initialize the vcpkg system, so we don't.

---
 compat/vcbuild/README          | 23 +++++++++++++
 config.mak.uname               | 61 ++++++++++++++++++++++++++++++++++
 contrib/buildsystems/engine.pl |  3 +-
 3 files changed, 86 insertions(+), 1 deletion(-)
compat/vcbuild/README +23 -0
index b633e7db98..1b6dabf5a2 100644
@@ -37,6 +37,29 @@ The Steps to Build Git with VS2015 or VS2017 from the command line.
 
 ================================================================
 
+Alternatively, run `make vcxproj` and then load the generated `git.sln` in
+Visual Studio. The initial build will install the vcpkg system and build the
+dependencies automatically. This will take a while.
+
+Instead of generating the `git.sln` file yourself (which requires a full Git
+for Windows SDK), you may want to consider fetching the `vs/master` branch of
+https://github.com/git-for-windows/git instead (which is updated automatically
+via CI running `make vcxproj`). The `vs/master` branch does not require a Git
+for Windows to build, but you can run the test scripts in a regular Git Bash.
+
+Note that `make vcxproj` will automatically add and commit the generated `.sln`
+and `.vcxproj` files to the repo. This is necessary to allow building a
+fully-testable Git in Visual Studio, where a regular Git Bash can be used to
+run the test scripts (as opposed to a full Git for Windows SDK): a number of
+build targets, such as Git commands implemented as Unix shell scripts (where
+`@@SHELL_PATH@@` and other placeholders are interpolated) require a full-blown
+Git for Windows SDK (which is about 10x the size of a regular Git for Windows
+installation).
+
+If your plan is to open a Pull Request with Git for Windows, it is a good idea
+to drop this commit before submitting.
+
+================================================================
 The Steps of Build Git with VS2008
 
 1. You need the build environment, which contains the Git dependencies
config.mak.uname +61 -0

74 lines not on this page · raw message

contrib/buildsystems/engine.pl +2 -1
index 8bb07e8e25..fba8a3f056 100755
@@ -82,7 +82,8 @@ sub showUsage
 # Capture the make dry stderr to file for review (will be empty for a release build).
 
 my $ErrsFile = "msvc-build-makedryerrors.txt";
-@makedry = `make -C $git_dir -n MSVC=1 V=1 2>$ErrsFile` if !@makedry;
+@makedry = `make -C $git_dir -n MSVC=1 SKIP_VCPKG=1 V=1 2>$ErrsFile`
+if !@makedry;
 # test for an empty Errors file and remove it
 unlink $ErrsFile if -f -z $ErrsFile;
 
Signature · 1 line
gitgitgadget
#19 lore raw

PATCH 19/24 vcxproj: also link-or-copy builtins

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

The default location for .exe files linked by Visual Studio depends on the mode (debug vs release) and the architecture. Meaning: after a full build, there is a git.exe in the top-level directory, but none of the built-ins are linked..

When running a test script in Git Bash, it therefore would pick up the wrong, say, git-receive-pack.exe: the one installed at the same time as the Git Bash.

Absolutely not what we want. We want to have confidence that our test covers the MSVC-built Git executables, and not some random stuff.

---
 config.mak.uname                           | 15 +++++++++++++++
 contrib/buildsystems/Generators/Vcxproj.pm |  3 +++
 2 files changed, 18 insertions(+)
config.mak.uname +15 -0
index 6d0ed923b8..db7f06b95f 100644
@@ -703,6 +703,21 @@ vcxproj:
 	perl contrib/buildsystems/generate -g Vcxproj
 	git add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj
 
+	# Generate the LinkOrCopyBuiltins.targets file
+	(echo '<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">' && \
+	 echo '  <Target Name="CopyBuiltins_AfterBuild" AfterTargets="AfterBuild">' && \
+	 for name in $(BUILT_INS);\
+	 do \
+	   echo '    <Copy SourceFiles="$$(OutDir)\git.exe" DestinationFiles="$$(OutDir)\'"$$name"'" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />'; \
+	 done && \
+	 for name in $(REMOTE_CURL_ALIASES); \
+	 do \
+	   echo '    <Copy SourceFiles="$$(OutDir)\'"$(REMOTE_CURL_PRIMARY)"'" DestinationFiles="$$(OutDir)\'"$$name"'" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />'; \
+	 done && \
+	 echo '  </Target>' && \
+	 echo '</Project>') >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
contrib/buildsystems/Generators/Vcxproj.pm +3 -0
index 9e7ed24912..4b02524b10 100644
@@ -273,6 +273,9 @@ sub createProject {
   </Target>
 EOM
     }
+    if ($target eq 'git') {
+      print F "  <Import Project=\"LinkOrCopyBuiltins.targets\" />\n";
+    }
     print F << "EOM";
 </Project>
 EOM
Signature · 1 line
gitgitgadget
#20 lore raw

PATCH 20/24 .gitignore: touch up the entries regarding Visual Studio

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Add the Microsoft .manifest pattern, and do not anchor the 'Debug' and 'Release' entries at the top-level directory, to allow for multiple projects (one per target).

---
 .gitignore | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
.gitignore +3 -2
index e096e0a51c..e7bb15d301 100644
@@ -230,6 +230,7 @@
 *.ipdb
 *.dll
 .vs/
-/Debug/
-/Release/
+*.manifest
+Debug/
+Release/
 *.dSYM
Signature · 1 line
gitgitgadget
#21 lore raw

PATCH 21/24 .gitignore: ignore Visual Studio's temporary/generated files

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

---
 .gitignore | 3 +++
 1 file changed, 3 insertions(+)
.gitignore +3 -0
index e7bb15d301..fcfb708b9e 100644
@@ -233,4 +233,7 @@
 *.manifest
 Debug/
 Release/
+/UpgradeLog*.htm
+/git.VC.VC.opendb
+/git.VC.db
 *.dSYM
Signature · 1 line
gitgitgadget
#22 lore raw

PATCH 22/24 bin-wrappers: append `.exe` to target paths if necessary

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

When compiling with Visual Studio, the projects' names are identical to the executables modulo the extensions. Read: there will exist both a directory called git as well as an executable called git.exe in the end. Which means that the bin-wrappers *need* to target the .exe files lest they try to execute directories.

---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Makefile +1 -1
index 98a0588416..3716dadc08 100644
@@ -2717,7 +2717,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.
Signature · 1 line
gitgitgadget
#23 lore raw

PATCH 23/24 t5505,t5516: create .git/branches/ when needed

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

It is a real old anachronism from the Cogito days to have a .git/branches/ directory. And to have tests that ensure that Cogito users can migrate away from using that directory.

But so be it, let's continue testing it.

Let's make sure, however, that git init does not need to create that directory.

This bug was noticed when testing with templates that had been pre-committed, skipping the empty branches/ directory of course because Git does not track empty directories.

---
 t/t5505-remote.sh     | 2 ++
 t/t5516-fetch-push.sh | 4 ++++
 2 files changed, 6 insertions(+)
t/t5505-remote.sh +2 -0
index 883b32efa0..1132964044 100755
@@ -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 &&
t/t5516-fetch-push.sh +4 -0
index c81ca360ac..47c2959a90 100755
@@ -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 &&
 	(
Signature · 1 line
gitgitgadget
#24 lore raw

Re: [PATCH 23/24] t5505,t5516: create .git/branches/ when needed

"Johannes Schindelin via GitGitGadget" <[email protected]>

Quoted 6 lines · writes:

From: Johannes Schindelin <[email protected]>

It is a real old anachronism from the Cogito days to have a .git/branches/ directory. And to have tests that ensure that Cogito users can migrate away from using that directory.

Quoted 8 lines

But so be it, let's continue testing it.

Let's make sure, however, that git init does not need to create that directory.

This bug was noticed when testing with templates that had been pre-committed, skipping the empty branches/ directory of course because Git does not track empty directories.

Many tests assume that the .git/info/ directory exists, and the only reason why they can is because we have templates/info--exclude; the situation around .git/branches/ is exactly the same.

Deprecating .git/branches/ directory and dropping the parts of tests that wants to make sure the support still works (t5516 is not about migration but about working with .git/branches configuration) would be a different matter. Until that happens, let's not do this patch; otherwise it would force us to sprinkle "mkdir -p .git/info/" all over the place for the same rationale. A directory in .git/ created by hardcoded mkdir in "git init" (like .git/refs/) and created by copying templates by "git init" (like .git/info/ and .git/branches) are both "created by 'git init'". Special casing the latter is just silly.

#25 lore raw

Re: [PATCH 23/24] t5505,t5516: create .git/branches/ when needed

Hi Junio,

Quoted 14 lines · Junio C Hamano

"Johannes Schindelin via GitGitGadget" <[email protected]>

Quoted 11 lines · writes:

From: Johannes Schindelin <[email protected]>

It is a real old anachronism from the Cogito days to have a .git/branches/ directory. And to have tests that ensure that Cogito users can migrate away from using that directory.

But so be it, let's continue testing it.

Let's make sure, however, that git init does not need to create that directory.

Quoted 7 lines
Quoted 3 lines

This bug was noticed when testing with templates that had been pre-committed, skipping the empty branches/ directory of course because Git does not track empty directories.

Many tests assume that the .git/info/ directory exists, and the only reason why they can is because we have templates/info--exclude; the situation around .git/branches/ is exactly the same.

No, the situation with info/ is that it includes a file called exclude, which means that the templates/ directory can be "tracked". This is important because we want to commit all those generated files that cannot be generated inside Visual Studio without Git for Windows' SDK (which weighs in with several hundred megabytes to download, a gigabyte on disk).

The branches/ subdirectory, in contrast, is totally useless for at least 99.999% of the users, and hence it is understandable that it does not even contain a single file. Which means that it is *not* "tracked".

So when checking out, e.g. the vs/master branch at
https://github.com/git-for-windows/git, which is auto-generated using this here patch series from Git for Windows' master, to allow building in Visual Studio without having to download the full Git for Windows SDK, there will be the info/ directory (by virtue of containing a trackable file) exists, and the branches/ subdirectory won't exist.

As a consequence, the test scripts indicated in the commit message, which _can_ be run in a regular Git for Windows (no Git for Windows SDK required), will fail without this patch.

Quoted 4 lines

Deprecating .git/branches/ directory and dropping the parts of tests that wants to make sure the support still works (t5516 is not about migration but about working with .git/branches configuration) would be a different matter.

Indeed.

You probably forgot that I already proposed that, long time ago:
https://public-inbox.org/git/[email protected]/

I haven't forgotten, because you shot it down unceremoniously:

The last time I thought about trying this several years ago, I found that people who need to grab things from many places still do use .git/branches/ and their use case is hard to migrate to .git/config, primarily because the former is "one per file" and it is easy to add/remove/tweak without affecting others. Ask akpm@ if he still prefers to use .git/branches/ for example.

Of course, with such a kind of argument, there is no way how I could possibly prove that it is no longer advisable to have .git/branches/.

"Someone, somewhere _probably_ finds this still useful, so we won't remove it."

Quoted 1 line

Until that happens, let's not do this patch;

Well, that's another of these type of arguments.

Without this patch, and without removing support for .git/branches/, you force the Visual Studio build to _not_ pass the test suite. It's as simple as that.

So basically, by this statement you decided that there will not be a fully-functional way to build Git in Visual Studio and to pass the test suite with that.

Which is a shame.

Quoted 2 lines

otherwise it would force us to sprinkle "mkdir -p .git/info/" all over the place for the same rationale.

You may have assumed that I did not carefully verify that the test suite passes with these patches. But I did. And I would not have submitted this patch series if such a patch was necessary, at least not without said patch.

Quoted 4 lines

A directory in .git/ created by hardcoded mkdir in "git init" (like .git/refs/) and created by copying templates by "git init" (like .git/info/ and .git/branches) are both "created by 'git init'". Special casing the latter is just silly.

The thing that _really_ is silly is that we have that directory in Git's templates, still.

Git itself does not populate it. Git does not need it, ever. Git works Just Fine without it, and it is really by design that it does not require the presence of that subdirectory.

Only those two test cases insist, for some reason that escapes me, on the presence of those subdirectories.

As I said, Git does not populate that subdirectory. It even lacks all facilities to populate it. You have to write the files inside it yourself, you have to figure out the syntax of the files in that directory, and the only place where we document this is buried deeply in Documentation/gitrepository-layout.txt.

It is a bit silly, too, that we say there, in that very documentation for that very feature, that this feature is "slightly deprecated".

Either it is deprecated, or it isn't.

Further, it is a bit silly that this "slight deprecation" has been there since a1d4aa74241 (Add repository-layout document., 2005-09-01).

In other words, that feature was "slightly deprecated" already a mere five months after Git was made public. Yet we still shlep it around, fourteen (!) years later.

In yet other words, the support for .git/branches has been "slightly deprecated" more than 33x longer than it hasn't been.

I just wish that my patches to remove the support for .git/branches would have gone somewhere useful instead of into this ugly impasse.

Ciao,
Dscho

#26 lore raw

Re: [PATCH 23/24] t5505,t5516: create .git/branches/ when needed

Quoted 3 lines · Johannes Schindelin

Without this patch, and without removing support for .git/branches/, you force the Visual Studio build to _not_ pass the test suite. It's as simple as that.

I see it as deficiency of the build procedure. What makes it so different, compared to "make" we type on our boxes, where we do get the .git/branches/ directory anyway, even without having any file in it? The patch in question is to punt solving that and instead break the test suite.

#27 lore raw

Re: [PATCH 23/24] t5505,t5516: create .git/branches/ when needed

In reply to Johannes Schindelin
Quoted 2 lines · Johannes Schindelin

You probably forgot that I already proposed that, long time ago:
https://public-inbox.org/git/[email protected]/

No, I haven't. It was actually meant as an invitation to you to help us come up with a reasonable deprecation path.

I'd be super happy if we did not have to support 3 sources and instead just 2 sources of the remote information, but as I said number of times in the previous attempts' discussion, I think it is trickier than any of our past migration (like "push.default") to remove support for .git/branches, as I see no reasonably convenient alternative/workaround for those who do take advantage of the fact that .git/branches/ is "one liner, single file per remote source", which would make it convenient when you need to interact with dozens of sublevel integrators and the population of them changes regularly. "Run 'git remote add' with these options to limit its scope to a single branch" is easy to say but cumbersome to execute.

The best case scenario I came up with is to start giving a message when we read *and* *use* information from .git/branches/ hierarchy (i.e. when we know we found a potential user who will get affected by removal of .git/branches support), asking to tell us not to go forward with the removal if and only if an alternative we leave for them gives them unacceptably high cost (i.e. "we cannot afford to migrate our workflow not to use .git/branches/ because ..."), and after a few releases we do not hear anything from anybody. The second best would be to see responses that can serve as concrete examples to build our easy-to-use alternative after removing the support for .git/branches/. The alternative might end up not removing the support, but that is OK---we are in far better position than we currently are either way. The reason why we still have the support is mainly because we know there were users who took active advantage of that facility (again, not Cogito) several years ago, and we do not know if they moved on to update their workflows to use the config-based settings. After the above (or something similar) happens, we will know that nobody needs it and we can remove it with confidence.

#28 lore raw

Re: [PATCH 23/24] t5505,t5516: create .git/branches/ when needed

Quoted 7 lines · Junio C Hamano
Quoted 2 lines · Johannes Schindelin

You probably forgot that I already proposed that, long time ago:
https://public-inbox.org/git/[email protected]/

No, I haven't. It was actually meant as an invitation to you to help us come up with a reasonable deprecation path.

By the way, while the "deprecation plan" still has my attention ;-), there is another thing I've been wanting to see happen *without* burning me like the last time it was brought up [*1*], which is also hard to come up with a reasonable deprecation path.

A newer port like Git for Windows, where I suspect that most of the users are not even aware of the "git-foo" form, can probably get away by not shipping the libexec/git/git-foo without getting its users complaining (and as you repeatedly said, nobody on Windows write shell scripts, so lack of support for old scripts writtin in the days back when git-foo was a norm is perfectly fine there). But I am not sure about my tree where audiences are beyond Windows, and I certainly do not want to get burned again myself.

Somebody else volunteering to take both blame (and flame) and credit would be most welcomed ;-).

[Reference]

*1* https://public-inbox.org/git/[email protected]/

#29 lore raw

PATCH 24/24 git: avoid calling aliased builtins via their dashed form

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

This is one of the few places where Git violates its own deprecation of the dashed form. It is not necessary, either.

As of 595d59e2b53 (git.c: ignore pager.* when launching builtin as dashed external, 2017-08-02), Git wants to ignore the pager.* config setting when expanding aliases. So let's strip out the check_pager_config(<command-name>) call from the copy-edited code.

This code actually made it into upstream git.git already, but it was disabled in #if 0 ... #endif guards so far.

---
 git.c | 3 ---
 1 file changed, 3 deletions(-)
git.c +0 -3
index f4c0478f32..3049dae85b 100644
@@ -743,8 +743,6 @@ static int run_argv(int *argcp, const char ***argv)
 		 */
 		if (!done_alias)
 			handle_builtin(*argcp, *argv);
-
-#if 0 // TODO In GFW, need to amend a7924b655e940b06cb547c235d6bed9767929673 to include trace2_ and _tr2 lines.
 		else if (get_builtin(**argv)) {
 			struct argv_array args = ARGV_ARRAY_INIT;
 			int i;
@@ -779,7 +777,6 @@ static int run_argv(int *argcp, const char ***argv)
 				exit(i);
 			die("could not execute builtin %s", **argv);
 		}
-#endif // a7924b655e940b06cb547c235d6bed9767929673
 
 		/* .. then try the external ones */
 		execv_dashed_external(*argv);
Signature · 1 line
gitgitgadget
#30 lore raw

v2 cover Reinstate support for Visual Studio

In reply to Johannes Schindelin via GitGitGadget

A long time ago, we added support to build .sln and .vcproj files for use within Visual Studio, so that Git could be built in that popular IDE.

This support languished for years and was finally brought back into Git for Windows partially through the jh/msvc branch that was just merged into master. With the tremendous help by Philip Oakley and Jeff Hostetler, this re-adds support for Visual Studio, focusing on VS 2015 and later (older versions are currently unsupported, even if we worked a bit on that front, too; If there are volunteers to add support for older versions, I would be delighted to review PRs to that end on
https://github.com/git-for-windows/git).

Note: the currently preferred way to contribute using Visual Studio is by using Git for Windows' vs/master branch (which is automatically generated using the make vcxproj build target that this patch series adds, updated every time Git for Windows' master advances). My plan is to provide a similar branch in GitGitGadget, based on top of git.git's master, once this patch series is integrated.

Changes since v1:

* The empty directory templates/blt/branches/ is now created as part of the build.

Johannes Schindelin (14):
Vcproj.pm: auto-generate GUIDs
Vcproj.pm: do not configure VCWebServiceProxyGeneratorTool Vcproj.pm: urlencode '<' and '>' when generating VC projects contrib/buildsystems: ignore irrelevant files in Generators/ contrib/buildsystems: error out on unknown option contrib/buildsystems: handle libiconv, too contrib/buildsystems: also handle -lexpat contrib/buildsystems: handle options starting with a slash contrib/buildsystems: add a backend for modern Visual Studio versions
msvc: add a Makefile target to pre-generate the Visual Studio solution
vcxproj: also link-or-copy builtins
.gitignore: ignore Visual Studio's temporary/generated files
bin-wrappers: append .exe to target paths if necessary
git: avoid calling aliased builtins via their dashed form

Philip Oakley (9):
Vcproj.pm: list git.exe first to be startup project contrib/buildsystems: ignore invalidcontinue.obj contrib/buildsystems: fix misleading error message contrib/buildsystems: handle quoted spaces in filenames contrib/buildsystems: ignore gettext stuff contrib/buildsystems: redirect errors of the dry run into a log file contrib/buildsystems: optionally capture the dry-run in a file contrib/buildsystems: handle the curl library option .gitignore: touch up the entries regarding Visual Studio

 .gitignore                                 |   8 +-
 Makefile                                   |   2 +-
 compat/vcbuild/README                      |  23 ++
 config.mak.uname                           |  76 ++++
 contrib/buildsystems/Generators.pm         |   2 +-
 contrib/buildsystems/Generators/Vcproj.pm  | 119 ++-----
 contrib/buildsystems/Generators/Vcxproj.pm | 388 +++++++++++++++++++++
 contrib/buildsystems/engine.pl             |  55 ++-
 git.c                                      |   3 -
 9 files changed, 576 insertions(+), 100 deletions(-)
 create mode 100644 contrib/buildsystems/Generators/Vcxproj.pm

base-commit: 9d418600f4d10dcbbfb0b5fdbc71d509e03ba719
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-287%2Fdscho%2Fvisual-studio-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-287/dscho/visual-studio-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/287

Range-diff vs v1:

  1:  240ff42517 =  1:  240ff42517 Vcproj.pm: auto-generate GUIDs
  2:  a7898b0025 =  2:  a7898b0025 Vcproj.pm: list git.exe first to be startup project
  3:  d42fd0fe2e =  3:  d42fd0fe2e Vcproj.pm: do not configure VCWebServiceProxyGeneratorTool
  4:  f4d41c65e9 =  4:  f4d41c65e9 Vcproj.pm: urlencode '<' and '>' when generating VC projects
  5:  82e820017b =  5:  82e820017b contrib/buildsystems: ignore invalidcontinue.obj
  6:  60a45f2694 =  6:  60a45f2694 contrib/buildsystems: ignore irrelevant files in Generators/
  7:  b8eb868316 =  7:  b8eb868316 contrib/buildsystems: fix misleading error message
  8:  c10fd668ef =  8:  c10fd668ef contrib/buildsystems: handle quoted spaces in filenames
  9:  e908d01f07 =  9:  e908d01f07 contrib/buildsystems: ignore gettext stuff
 10:  3cfbb7843a = 10:  3cfbb7843a contrib/buildsystems: redirect errors of the dry run into a log file
 11:  eaf1dd449d = 11:  eaf1dd449d contrib/buildsystems: optionally capture the dry-run in a file
 12:  c696152c7f = 12:  c696152c7f contrib/buildsystems: error out on unknown option
 13:  b07e83440d = 13:  b07e83440d contrib/buildsystems: handle the curl library option
 14:  052a98b8bb = 14:  052a98b8bb contrib/buildsystems: handle libiconv, too
 15:  5c9702ea50 = 15:  5c9702ea50 contrib/buildsystems: also handle -lexpat
 16:  1d4c5539ef = 16:  1d4c5539ef contrib/buildsystems: handle options starting with a slash
 17:  59c50989ea ! 17:  bc6a10ba47 contrib/buildsystems: add a backend for modern Visual Studio versions
     @@ -296,6 +296,7 @@
      +      <DLLsAndPDBs Include="\$(VCPKGBinDirectory)\\*.dll;\$(VCPKGBinDirectory)\\*.pdb" />
      +    </ItemGroup>
      +    <Copy SourceFiles="@(DLLsAndPDBs)" DestinationFolder="\$(OutDir)" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />
     ++    <MakeDir Directories="..\\templates\\blt\\branches" />
      +  </Target>
      +EOM
      +    }
 18:  23615bc8cf = 18:  2a3379d721 msvc: add a Makefile target to pre-generate the Visual Studio solution
 19:  33bed9a7a6 = 19:  4dbbe3f4a2 vcxproj: also link-or-copy builtins
 20:  44f0f3235e = 20:  dc4a9cc620 .gitignore: touch up the entries regarding Visual Studio
 21:  8f19bb5a8c = 21:  3f862bf878 .gitignore: ignore Visual Studio's temporary/generated files
 22:  971247e320 = 22:  a81cc2ccce bin-wrappers: append `.exe` to target paths if necessary
 23:  db69b33ff4 <  -:  ---------- t5505,t5516: create .git/branches/ when needed
 24:  151b9921d0 = 23:  6452dc11bc git: avoid calling aliased builtins via their dashed form
Signature · 1 line
gitgitgadget
#31 lore raw

PATCH v2 1/23 Vcproj.pm: auto-generate GUIDs

From: Johannes Schindelin <[email protected]>

We ran out GUIDs. Again. But there is no need to: we can generate them semi-randomly from the target file name of the project.

Note: the Vcproj generator is probably only interesting for historical reasons; nevertheless, the upcoming Vcxproj generator (to support modern Visual Studio versions) is based on the Vcproj generator and it is better to fix this here first.

---
 contrib/buildsystems/Generators/Vcproj.pm | 66 ++++-------------------
 1 file changed, 9 insertions(+), 57 deletions(-)
contrib/buildsystems/Generators/Vcproj.pm +9 -57
index cfa74adcc2..c79b706bc8 100644
@@ -3,6 +3,7 @@ package Generators::Vcproj;
 
 use strict;
 use vars qw($VERSION);
+use Digest::SHA qw(sha256_hex);
 
 our $VERSION = '1.00';
 our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
@@ -12,59 +13,12 @@ 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_guid ($) {
+    my $hex = sha256_hex($_[0]);
+    $hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*/{$1-$2-$3-$4-$5}/;
+    $hex =~ tr/a-z/A-Z/;
+    return $hex;
+}
 
 sub generate {
     my ($git_dir, $out_dir, $rel_dir, %build_structure) = @_;
@@ -92,9 +46,8 @@ sub createLibProject {
     $target =~ s/\//_/g;
     $target =~ s/\.a//;
 
-    my $uuid = $GUIDS[$guid_index];
+    my $uuid = generate_guid($libname);
     $$build_structure{"LIBS_${target}_GUID"} = $uuid;
-    $guid_index += 1;
 
     my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"LIBS_${libname}_SOURCES"}}));
     my @sources;
@@ -311,9 +264,8 @@ sub createAppProject {
     $target =~ s/\//_/g;
     $target =~ s/\.exe//;
 
-    my $uuid = $GUIDS[$guid_index];
+    my $uuid = generate_guid($appname);
     $$build_structure{"APPS_${target}_GUID"} = $uuid;
-    $guid_index += 1;
 
     my @srcs = sort(map("$rel_dir\\$_", @{$$build_structure{"APPS_${appname}_SOURCES"}}));
     my @sources;
Signature · 1 line
gitgitgadget
#32 lore raw

PATCH v2 2/23 Vcproj.pm: list git.exe first to be startup project

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Visual Studio takes the first listed application/library as the default startup project [1].

Detect the 'git' project and place it at the head of the project list, rather than at the tail.

Export the apps list before libs list for both the projects and global structures of the .sln file.

[1] http://stackoverflow.com/questions/1238553/
vs2008-where-is-the-startup-project-setting-stored-for-a-solution
"In the solution file, there are a list of pseudo-XML "Project" entries. It turns out that whatever is the first one ends up as the Startup Project, unless it’s overridden in the suo file. Argh. I just rearranged the order in the file and it’s good."

"just moving the pseudo-xml isn't enough. You also have to move the group of entries in the "GlobalSection(ProjectConfigurationPlatforms) = postSolution" group that has the GUID of the project you moved to the top. So there are two places to move lines."

---
 contrib/buildsystems/Generators/Vcproj.pm | 33 +++++++++++++----------
 1 file changed, 19 insertions(+), 14 deletions(-)
contrib/buildsystems/Generators/Vcproj.pm +19 -14
index c79b706bc8..d862cae503 100644
@@ -513,20 +513,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) {
@@ -540,6 +538,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
@@ -551,17 +556,17 @@ sub createGlueProject {
     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";
Signature · 1 line
gitgitgadget
#33 lore raw

PATCH v2 3/23 Vcproj.pm: do not configure VCWebServiceProxyGeneratorTool

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

It is not necessary, and Visual Studio 2015 no longer supports it, anyway.

---
 contrib/buildsystems/Generators/Vcproj.pm | 12 ------------
 1 file changed, 12 deletions(-)
contrib/buildsystems/Generators/Vcproj.pm +0 -12
index d862cae503..b17800184c 100644
@@ -115,9 +115,6 @@ sub createLibProject {
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
 			<Tool
 				Name="VCMIDLTool"
 			/>
@@ -181,9 +178,6 @@ sub createLibProject {
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
 			<Tool
 				Name="VCMIDLTool"
 			/>
@@ -339,9 +333,6 @@ sub createAppProject {
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
 			<Tool
 				Name="VCMIDLTool"
 			/>
@@ -410,9 +401,6 @@ sub createAppProject {
 			<Tool
 				Name="VCXMLDataGeneratorTool"
 			/>
-			<Tool
-				Name="VCWebServiceProxyGeneratorTool"
-			/>
 			<Tool
 				Name="VCMIDLTool"
 			/>
Signature · 1 line
gitgitgadget
#34 lore raw

PATCH v2 4/23 Vcproj.pm: urlencode '<' and '>' when generating VC projects

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

---
 contrib/buildsystems/Generators/Vcproj.pm | 8 ++++++++
 1 file changed, 8 insertions(+)
contrib/buildsystems/Generators/Vcproj.pm +8 -0
index b17800184c..737647e76a 100644
@@ -59,6 +59,8 @@ sub createLibProject {
     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;
+    $cflags =~ s/</&lt;/g;
+    $cflags =~ s/>/&gt;/g;
 
     my $cflags_debug = $cflags;
     $cflags_debug =~ s/-MT/-MTd/;
@@ -80,6 +82,8 @@ sub createLibProject {
 
     $defines =~ s/-D//g;
     $defines =~ s/\"/\\&quot;/g;
+    $defines =~ s/</&lt;/g;
+    $defines =~ s/>/&gt;/g;
     $defines =~ s/\'//g;
     $includes =~ s/-I//g;
     mkdir "$target" || die "Could not create the directory $target for lib project!\n";
@@ -271,6 +275,8 @@ sub createAppProject {
     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;
+    $cflags =~ s/</&lt;/g;
+    $cflags =~ s/>/&gt;/g;
 
     my $cflags_debug = $cflags;
     $cflags_debug =~ s/-MT/-MTd/;
@@ -297,6 +303,8 @@ sub createAppProject {
 
     $defines =~ s/-D//g;
     $defines =~ s/\"/\\&quot;/g;
+    $defines =~ s/</&lt;/g;
+    $defines =~ s/>/&gt;/g;
     $defines =~ s/\'//g;
     $defines =~ s/\\\\/\\/g;
     $includes =~ s/-I//g;
Signature · 1 line
gitgitgadget
#35 lore raw

PATCH v2 5/23 contrib/buildsystems: ignore invalidcontinue.obj

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Since 4b623d8 (MSVC: link in invalidcontinue.obj for better POSIX compatibility, 2014-03-29), invalidcontinue.obj is linked in the MSVC build, but it was not parsed correctly by the buildsystem. Ignore it, as it is known to Visual Studio and will be handled elsewhere.

Also only substitute filenames ending with .o when generating the source .c filename, otherwise we would start to expect .cbj files to generate .obj files (which are not generated by our build)...

In the future there may be source files that produce .obj files so keep the two issues (.obj files with & without source files) separate.

---
 contrib/buildsystems/engine.pl | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
contrib/buildsystems/engine.pl +7 -3
index 23da787dc5..53e65d4db7 100755
@@ -282,7 +282,7 @@ sub handleLibLine
 #    exit(1);
     foreach (@objfiles) {
         my $sourcefile = $_;
-        $sourcefile =~ s/\.o/.c/;
+        $sourcefile =~ s/\.o$/.c/;
         push(@sources, $sourcefile);
         push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}});
         push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}});
@@ -326,8 +326,12 @@ sub handleLinkLine
         } elsif ($part =~ /\.(a|lib)$/) {
             $part =~ s/\.a$/.lib/;
             push(@libs, $part);
-        } elsif ($part =~ /\.(o|obj)$/) {
+        } elsif ($part eq 'invalidcontinue.obj') {
+            # ignore - known to MSVC
+        } elsif ($part =~ /\.o$/) {
             push(@objfiles, $part);
+        } elsif ($part =~ /\.obj$/) {
+            # do nothing, 'make' should not be producing .obj, only .o files
         } else {
             die "Unhandled lib option @ line $lineno: $part";
         }
@@ -336,7 +340,7 @@ sub handleLinkLine
 #    exit(1);
     foreach (@objfiles) {
         my $sourcefile = $_;
-        $sourcefile =~ s/\.o/.c/;
+        $sourcefile =~ s/\.o$/.c/;
         push(@sources, $sourcefile);
         push(@cflags, @{$compile_options{"${sourcefile}_CFLAGS"}});
         push(@defines, @{$compile_options{"${sourcefile}_DEFINES"}});
Signature · 1 line
gitgitgadget
#36 lore raw

PATCH v2 6/23 contrib/buildsystems: ignore irrelevant files in Generators/

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

The Generators/ directory can contain spurious files such as editors' backup files. Even worse, there could be .swp files which are not even valid Perl scripts.

Let's just ignore anything but .pm files in said directory.

---
 contrib/buildsystems/Generators.pm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/buildsystems/Generators.pm +1 -1
index 408ef714b8..aa4cbaa2ad 100644
@@ -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);
Signature · 1 line
gitgitgadget
#37 lore raw

PATCH v2 7/23 contrib/buildsystems: fix misleading error message

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

The error message talked about a "lib option", but it clearly referred to a link option.

---
 contrib/buildsystems/engine.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/buildsystems/engine.pl +1 -1
index 53e65d4db7..11f0e16dda 100755
@@ -333,7 +333,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";
Signature · 1 line
gitgitgadget
#38 lore raw

PATCH v2 8/23 contrib/buildsystems: handle quoted spaces in filenames

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

The engine.pl script expects file names not to contain spaces. However, paths with spaces are quite prevalent on Windows. Use shellwords() rather than split() to parse them correctly.

---
 contrib/buildsystems/engine.pl | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
contrib/buildsystems/engine.pl +4 -3
index 11f0e16dda..ad6a82c30c 100755
@@ -12,6 +12,7 @@
 use File::Spec;
 use Cwd;
 use Generators;
+use Text::ParseWords;
 
 my (%build_structure, %compile_options, @makedry);
 my $out_dir = getcwd();
@@ -231,7 +232,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 +266,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 +307,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/) {
Signature · 1 line
gitgitgadget
#39 lore raw

PATCH v2 9/23 contrib/buildsystems: ignore gettext stuff

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Git's build contains steps to handle internationalization. This caused hiccups in the parser used to generate QMake/Visual Studio project files.

As those steps are irrelevant in this context, let's just ignore them.

---
 contrib/buildsystems/engine.pl | 6 ++++++
 1 file changed, 6 insertions(+)
contrib/buildsystems/engine.pl +6 -0
index ad6a82c30c..9db3d43a1e 100755
@@ -141,6 +141,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);
Signature · 1 line
gitgitgadget
#40 lore raw

PATCH v2 10/23 contrib/buildsystems: redirect errors of the dry run into a log file

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Rather than swallowing the errors, it is better to have them in a file.

To make it obvious what this is about, use the file name 'msvc-build-makedryerrors.txt'.

Further, if the output is empty, simply delete that file. As we target Git for Windows' SDK (which, unlike its predecessor msysGit, offers Perl versions newer than 5.8), we can use the quite readable syntax if -f -z $ErrsFile (available in Perl >=5.10).

Note that the file will contain the new values of the GIT_VERSION and GITGUI_VERSION if they were generated by the make file. They are omitted if the release is tagged and indentically defined in their respective GIT_VERSION_GEN file DEF_VER variables.

---
 contrib/buildsystems/engine.pl | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
contrib/buildsystems/engine.pl +6 -1
index 9db3d43a1e..de5c0b6b25 100755
@@ -73,7 +73,12 @@ 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 = `make -C $git_dir -n MSVC=1 V=1 2>$ErrsFile` if !@makedry;
+# test for an empty Errors file and remove it
+unlink $ErrsFile if -f -z $ErrsFile;
 
 # Parse the make output into usable info
 parseMakeOutput();
Signature · 1 line
gitgitgadget
#41 lore raw

PATCH v2 11/23 contrib/buildsystems: optionally capture the dry-run in a file

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Add an option for capturing the output of the make dry-run used in determining the msvc-build structure for easy debugging.

You can use the output of --make-out <path> in subsequent runs via the --in <path> option.

---
 contrib/buildsystems/engine.pl | 10 ++++++++++
 1 file changed, 10 insertions(+)
contrib/buildsystems/engine.pl +10 -0
index de5c0b6b25..732239d817 100755
@@ -32,6 +32,7 @@ sub showUsage
   -g <GENERATOR>  --gen <GENERATOR> Specify the buildsystem generator    (default: $gen)
                                     Available: $genlist
   -o <PATH>       --out <PATH>      Specify output directory generation  (default: .)
+                  --make-out <PATH> Write the output of GNU Make into a file
   -i <FILE>       --in <FILE>       Specify input file, instead of running GNU Make
   -h,-?           --help            This help
 EOM
@@ -39,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 "-?") {
@@ -46,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") {
@@ -80,6 +84,12 @@ sub showUsage
 # 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();
 
Signature · 1 line
gitgitgadget
#42 lore raw

PATCH v2 12/23 contrib/buildsystems: error out on unknown option

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

One time too many did this developer call the generate script passing a --make-out=<PATH> option that was happily ignored (because there should be a space, not an equal sign, between --make-out and the path).

And one time too many, this script not only ignored it but did not even complain. Let's fix that.

---
 contrib/buildsystems/engine.pl | 2 ++
 1 file changed, 2 insertions(+)
contrib/buildsystems/engine.pl +2 -0
index 732239d817..1a12f4d556 100755
@@ -57,6 +57,8 @@ sub showUsage
         open(F, "<$infile") || die "Couldn't open file $infile";
         @makedry = <F>;
         close(F);
+    } else {
+        die "Unknown option: " . $arg;
     }
 }
 
Signature · 1 line
gitgitgadget
#43 lore raw

PATCH v2 13/23 contrib/buildsystems: handle the curl library option

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Upon seeing the '-lcurl' option, point to the libcurl.lib.

While there, fix the elsif indentation.

---
 contrib/buildsystems/engine.pl | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
contrib/buildsystems/engine.pl +3 -1
index 1a12f4d556..d613277595 100755
@@ -341,10 +341,12 @@ 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" eq "-lcurl") {
+            push(@libs, "libcurl.lib");
         } elsif ($part =~ /^-/) {
             push(@lflags, $part);
         } elsif ($part =~ /\.(a|lib)$/) {
Signature · 1 line
gitgitgadget
#44 lore raw

PATCH v2 14/23 contrib/buildsystems: handle libiconv, too

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

Git's test suite shows tons of breakages unless Git is compiled *without* NO_ICONV. That means, in turn, that we need to generate build definitions *with* libiconv, which in turn implies that we have to handle the -liconv option properly.

---
 contrib/buildsystems/engine.pl | 2 ++
 1 file changed, 2 insertions(+)
contrib/buildsystems/engine.pl +2 -0
index d613277595..c35844a0c7 100755
@@ -347,6 +347,8 @@ sub handleLinkLine
             push(@libs, "ssleay32.lib");
         } 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)$/) {
Signature · 1 line
gitgitgadget
#45 lore raw

PATCH v2 15/23 contrib/buildsystems: also handle -lexpat

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

This is a dependency required for the non-smart HTTP backend.

---
 contrib/buildsystems/engine.pl | 2 ++
 1 file changed, 2 insertions(+)
contrib/buildsystems/engine.pl +2 -0
index c35844a0c7..9bde7ae15b 100755
@@ -347,6 +347,8 @@ sub handleLinkLine
             push(@libs, "ssleay32.lib");
         } elsif ("$part" eq "-lcurl") {
             push(@libs, "libcurl.lib");
+        } elsif ("$part" eq "-lexpat") {
+            push(@libs, "expat.lib");
         } elsif ("$part" eq "-liconv") {
             push(@libs, "libiconv.lib");
         } elsif ($part =~ /^-/) {
Signature · 1 line
gitgitgadget
#46 lore raw

PATCH v2 16/23 contrib/buildsystems: handle options starting with a slash

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

With the recent changes to allow building with MSVC=1, we now pass the /OPT:REF option to the compiler. This confuses the parser that wants to turn the output of a dry run into project definitions for QMake and Visual Studio:

Unhandled link option @ line 213: /OPT:REF at [...]

Let's just extend the code that passes through options that start with a dash, so that it passes through options that start with a slash, too.

---
 contrib/buildsystems/engine.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
contrib/buildsystems/engine.pl +1 -1
index 9bde7ae15b..8bb07e8e25 100755
@@ -351,7 +351,7 @@ sub handleLinkLine
             push(@libs, "expat.lib");
         } elsif ("$part" eq "-liconv") {
             push(@libs, "libiconv.lib");
-        } elsif ($part =~ /^-/) {
+        } elsif ($part =~ /^[-\/]/) {
             push(@lflags, $part);
         } elsif ($part =~ /\.(a|lib)$/) {
             $part =~ s/\.a$/.lib/;
Signature · 1 line
gitgitgadget
#47 lore raw

PATCH v2 17/23 contrib/buildsystems: add a backend for modern Visual Studio versions

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

Based on the previous patches in this patch series that fixed the generator for .vcproj files (which were used by Visual Studio prior to 2015 to define projects), this patch offers to generate project definitions for neweer versions of Visual Studio (which use .vcxproj files).

To that end, this patch copy-edits the generator of the .vcproj.

In addition, we now use the vcpkg system which allows us to build Git's dependencies (e.g. curl, libexpat) conveniently. The support scripts were introduced in the jh/msvc patch series, and with this patch we initialize the vcpkg conditionally, in the libgit project's PreBuildEvent. To allow for parallel building of the projects, we therefore put libgit at the bottom of the project hierarchy.

---
 contrib/buildsystems/Generators/Vcxproj.pm | 385 +++++++++++++++++++++
 1 file changed, 385 insertions(+)
 create mode 100644 contrib/buildsystems/Generators/Vcxproj.pm
contrib/buildsystems/Generators/Vcxproj.pm new file +385 -0
new file mode 100644
index 0000000000..e65d78e16d
@@ -0,0 +1,385 @@
+package Generators::Vcxproj;
+require Exporter;
+
+use strict;
+use vars qw($VERSION);
+use Digest::SHA qw(sha256_hex);
+
+our $VERSION = '1.00';
+our(@ISA, @EXPORT, @EXPORT_OK, @AVAILABLE);
+@ISA = qw(Exporter);
+
+BEGIN {
+    push @EXPORT_OK, qw(generate);
+}
+
+sub generate_guid ($) {
+	my $hex = sha256_hex($_[0]);
+	$hex =~ s/^(.{8})(.{4})(.{4})(.{4})(.{12}).*/{$1-$2-$3-$4-$5}/;
+	$hex =~ tr/a-z/A-Z/;
+	return $hex;
+}
+
+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 = generate_guid($name);
+    $$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/^-[GLMOWZ].*//; s/.* .*/"$&"/; $_; } @{$$build_structure{"$prefix${name}_CFLAGS"}}));
+    $cflags =~ s/</&lt;/g;
+    $cflags =~ s/>/&gt;/g;
+
+    my $libs_release = "\n    ";
+    my $libs_debug = "\n    ";
+    if (!$static_library) {
+      $libs_release = join(";", sort(grep /^(?!libgit\.lib|xdiff\/lib\.lib|vcs-svn\/lib\.lib)/, @{$$build_structure{"$prefix${name}_LIBS"}}));
+      $libs_debug = $libs_release;
+      $libs_debug =~ s/zlib\.lib/zlibd\.lib/;
+    }
+
+    $defines =~ s/-D//g;
+    $defines =~ s/</&lt;/g;
+    $defines =~ s/>/&gt;/g;
+    $defines =~ s/\'//g;
+
+    die "Could not create the directory $target for $label project!\n" unless (-d "$target" || mkdir "$target");
+
+    open F, ">$vcxproj" or die "Could not open $vcxproj for writing!\n";
+    binmode F, ":crlf :utf8";
+    print F chr(0xFEFF);
+    print F << "EOM";
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>$uuid</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <VCPKGArch Condition="'\$(Platform)'=='Win32'">x86-windows</VCPKGArch>
+    <VCPKGArch Condition="'\$(Platform)'!='Win32'">x64-windows</VCPKGArch>
+    <VCPKGArchDirectory>$cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)</VCPKGArchDirectory>
+    <VCPKGBinDirectory Condition="'\(Configuration)'=='Debug'">\$(VCPKGArchDirectory)\\debug\\bin</VCPKGBinDirectory>
+    <VCPKGLibDirectory Condition="'\(Configuration)'=='Debug'">\$(VCPKGArchDirectory)\\debug\\lib</VCPKGLibDirectory>
+    <VCPKGBinDirectory Condition="'\(Configuration)'!='Debug'">\$(VCPKGArchDirectory)\\bin</VCPKGBinDirectory>
+    <VCPKGLibDirectory Condition="'\(Configuration)'!='Debug'">\$(VCPKGArchDirectory)\\lib</VCPKGLibDirectory>
+    <VCPKGIncludeDirectory>\$(VCPKGArchDirectory)\\include</VCPKGIncludeDirectory>
+    <VCPKGLibs Condition="'\(Configuration)'=='Debug'">$libs_debug</VCPKGLibs>
+    <VCPKGLibs Condition="'\(Configuration)'!='Debug'">$libs_release</VCPKGLibs>
+  </PropertyGroup>
+  <Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'\$(Configuration)'=='Debug'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'\$(Configuration)'=='Release'" Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup>
+    <ConfigurationType>$config_type</ConfigurationType>
+    <PlatformToolset>v140</PlatformToolset>
+    <!-- <CharacterSet>UTF-8</CharacterSet> -->
+    <OutDir>..\\</OutDir>
+    <!-- <IntDir>\$(ProjectDir)\$(Configuration)\\</IntDir> -->
+  </PropertyGroup>
+  <Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props" Condition="exists('\$(UserRootDir)\\Microsoft.Cpp.\$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <GenerateManifest>false</GenerateManifest>
+    <EnableManagedIncrementalBuild>true</EnableManagedIncrementalBuild>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <AdditionalOptions>$cflags %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalIncludeDirectories>$cdup;$cdup\\compat;$cdup\\compat\\regex;$cdup\\compat\\win32;$cdup\\compat\\poll;$cdup\\compat\\vcbuild\\include;\$(VCPKGIncludeDirectory);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <EnableParallelCodeGeneration />
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <PrecompiledHeader />
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Lib>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+    <Link>
+      <AdditionalLibraryDirectories>\$(VCPKGLibDirectory);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+      <AdditionalDependencies>\$(VCPKGLibs);\$(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalOptions>invalidcontinue.obj %(AdditionalOptions)</AdditionalOptions>
+      <EntryPointSymbol>wmainCRTStartup</EntryPointSymbol>
+      <ManifestFile>$cdup\\compat\\win32\\git.manifest</ManifestFile>
+      <SubSystem>Console</SubSystem>
+    </Link>
+EOM
+    if ($target eq 'libgit') {
+        print F << "EOM";
+    <PreBuildEvent Condition="!Exists('$cdup\\compat\\vcbuild\\vcpkg\\installed\\\$(VCPKGArch)\\include\\openssl\\ssl.h')">
+      <Message>Initialize VCPKG</Message>
+      <Command>del "$cdup\\compat\\vcbuild\\vcpkg"</Command>
+      <Command>call "$cdup\\compat\\vcbuild\\vcpkg_install.bat"</Command>
+    </PreBuildEvent>
+EOM
+    }
+    print F << "EOM";
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'\$(Platform)'=='Win32'">
+    <Link>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'\$(Configuration)'=='Debug'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;$defines;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'\$(Configuration)'=='Release'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;$defines;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+EOM
+    foreach(@sources) {
+        print F << "EOM";
+    <ClCompile Include="$_" />
+EOM
+    }
+    print F << "EOM";
+  </ItemGroup>
+EOM
+    if (!$static_library || $target =~ 'vcs-svn' || $target =~ 'xdiff') {
+      my $uuid_libgit = $$build_structure{"LIBS_libgit_GUID"};
+      my $uuid_xdiff_lib = $$build_structure{"LIBS_xdiff/lib_GUID"};
+
+      print F << "EOM";
+  <ItemGroup>
+    <ProjectReference Include="$cdup\\libgit\\libgit.vcxproj">
+      <Project>$uuid_libgit</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+EOM
+      if (!($name =~ 'xdiff')) {
+        print F << "EOM";
+    <ProjectReference Include="$cdup\\xdiff\\lib\\xdiff_lib.vcxproj">
+      <Project>$uuid_xdiff_lib</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+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";
+    <ProjectReference Include="$cdup\\vcs-svn\\lib\\vcs-svn_lib.vcxproj">
+      <Project>$uuid_vcs_svn_lib</Project>
+      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
+    </ProjectReference>
+EOM
+      }
+      print F << "EOM";
+  </ItemGroup>
+EOM
+    }
+    print F << "EOM";
+  <Import Project="\$(VCTargetsPath)\\Microsoft.Cpp.targets" />
+EOM
+    if (!$static_library) {
+      print F << "EOM";
+  <Target Name="${target}_AfterBuild" AfterTargets="AfterBuild">
+    <ItemGroup>
+      <DLLsAndPDBs Include="\$(VCPKGBinDirectory)\\*.dll;\$(VCPKGBinDirectory)\\*.pdb" />
+    </ItemGroup>
+    <Copy SourceFiles="@(DLLsAndPDBs)" DestinationFolder="\$(OutDir)" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />
+    <MakeDir Directories="..\\templates\\blt\\branches" />
+  </Target>
+EOM
+    }
+    print F << "EOM";
+</Project>
+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;
Signature · 1 line
gitgitgadget
#48 lore raw

PATCH v2 18/23 msvc: add a Makefile target to pre-generate the Visual Studio solution

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

The entire idea of generating the VS solution makes only sense if we generate it via Continuous Integration; otherwise potential users would still have to download the entire Git for Windows SDK.

If we pre-generate the Visual Studio solution, Git can be built entirely within Visual Studio, and the test scripts can be run in a regular Git for Windows (e.g. the Portable Git flavor, which does not include a full GCC toolchain and therefore weighs only about a tenth of Git for Windows' SDK).

So let's just add a target in the Makefile that can be used to generate said solution; The generated files will then be committed so that they can be pushed to a branch ready to check out by Visual Studio users.

To make things even more useful, we also generate and commit other files that are required to run the test suite, such as templates and
bin-wrappers: with this, developers can run the test suite in a regular Git Bash after building the solution in Visual Studio.

Note: for this build target, we do not actually need to initialize the vcpkg system, so we don't.

---
 compat/vcbuild/README          | 23 +++++++++++++
 config.mak.uname               | 61 ++++++++++++++++++++++++++++++++++
 contrib/buildsystems/engine.pl |  3 +-
 3 files changed, 86 insertions(+), 1 deletion(-)
compat/vcbuild/README +23 -0
index b633e7db98..1b6dabf5a2 100644
@@ -37,6 +37,29 @@ The Steps to Build Git with VS2015 or VS2017 from the command line.
 
 ================================================================
 
+Alternatively, run `make vcxproj` and then load the generated `git.sln` in
+Visual Studio. The initial build will install the vcpkg system and build the
+dependencies automatically. This will take a while.
+
+Instead of generating the `git.sln` file yourself (which requires a full Git
+for Windows SDK), you may want to consider fetching the `vs/master` branch of
+https://github.com/git-for-windows/git instead (which is updated automatically
+via CI running `make vcxproj`). The `vs/master` branch does not require a Git
+for Windows to build, but you can run the test scripts in a regular Git Bash.
+
+Note that `make vcxproj` will automatically add and commit the generated `.sln`
+and `.vcxproj` files to the repo. This is necessary to allow building a
+fully-testable Git in Visual Studio, where a regular Git Bash can be used to
+run the test scripts (as opposed to a full Git for Windows SDK): a number of
+build targets, such as Git commands implemented as Unix shell scripts (where
+`@@SHELL_PATH@@` and other placeholders are interpolated) require a full-blown
+Git for Windows SDK (which is about 10x the size of a regular Git for Windows
+installation).
+
+If your plan is to open a Pull Request with Git for Windows, it is a good idea
+to drop this commit before submitting.
+
+================================================================
 The Steps of Build Git with VS2008
 
 1. You need the build environment, which contains the Git dependencies
config.mak.uname +61 -0

74 lines not on this page · raw message

contrib/buildsystems/engine.pl +2 -1
index 8bb07e8e25..fba8a3f056 100755
@@ -82,7 +82,8 @@ sub showUsage
 # Capture the make dry stderr to file for review (will be empty for a release build).
 
 my $ErrsFile = "msvc-build-makedryerrors.txt";
-@makedry = `make -C $git_dir -n MSVC=1 V=1 2>$ErrsFile` if !@makedry;
+@makedry = `make -C $git_dir -n MSVC=1 SKIP_VCPKG=1 V=1 2>$ErrsFile`
+if !@makedry;
 # test for an empty Errors file and remove it
 unlink $ErrsFile if -f -z $ErrsFile;
 
Signature · 1 line
gitgitgadget
#49 lore raw

PATCH v2 19/23 vcxproj: also link-or-copy builtins

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

The default location for .exe files linked by Visual Studio depends on the mode (debug vs release) and the architecture. Meaning: after a full build, there is a git.exe in the top-level directory, but none of the built-ins are linked..

When running a test script in Git Bash, it therefore would pick up the wrong, say, git-receive-pack.exe: the one installed at the same time as the Git Bash.

Absolutely not what we want. We want to have confidence that our test covers the MSVC-built Git executables, and not some random stuff.

---
 config.mak.uname                           | 15 +++++++++++++++
 contrib/buildsystems/Generators/Vcxproj.pm |  3 +++
 2 files changed, 18 insertions(+)
config.mak.uname +15 -0
index 6d0ed923b8..db7f06b95f 100644
@@ -703,6 +703,21 @@ vcxproj:
 	perl contrib/buildsystems/generate -g Vcxproj
 	git add -f git.sln {*,*/lib,t/helper/*}/*.vcxproj
 
+	# Generate the LinkOrCopyBuiltins.targets file
+	(echo '<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">' && \
+	 echo '  <Target Name="CopyBuiltins_AfterBuild" AfterTargets="AfterBuild">' && \
+	 for name in $(BUILT_INS);\
+	 do \
+	   echo '    <Copy SourceFiles="$$(OutDir)\git.exe" DestinationFiles="$$(OutDir)\'"$$name"'" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />'; \
+	 done && \
+	 for name in $(REMOTE_CURL_ALIASES); \
+	 do \
+	   echo '    <Copy SourceFiles="$$(OutDir)\'"$(REMOTE_CURL_PRIMARY)"'" DestinationFiles="$$(OutDir)\'"$$name"'" SkipUnchangedFiles="true" UseHardlinksIfPossible="true" />'; \
+	 done && \
+	 echo '  </Target>' && \
+	 echo '</Project>') >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
contrib/buildsystems/Generators/Vcxproj.pm +3 -0
index e65d78e16d..576ccabe1d 100644
@@ -274,6 +274,9 @@ sub createProject {
   </Target>
 EOM
     }
+    if ($target eq 'git') {
+      print F "  <Import Project=\"LinkOrCopyBuiltins.targets\" />\n";
+    }
     print F << "EOM";
 </Project>
 EOM
Signature · 1 line
gitgitgadget
#50 lore raw

PATCH v2 20/23 .gitignore: touch up the entries regarding Visual Studio

In reply to Johannes Schindelin via GitGitGadget

From: Philip Oakley <[email protected]>

Add the Microsoft .manifest pattern, and do not anchor the 'Debug' and 'Release' entries at the top-level directory, to allow for multiple projects (one per target).

---
 .gitignore | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
.gitignore +3 -2
index e096e0a51c..e7bb15d301 100644
@@ -230,6 +230,7 @@
 *.ipdb
 *.dll
 .vs/
-/Debug/
-/Release/
+*.manifest
+Debug/
+Release/
 *.dSYM
Signature · 1 line
gitgitgadget
#51 lore raw

Re: [PATCH v2 20/23] .gitignore: touch up the entries regarding Visual Studio

Quoted 15 lines · Philip Oakley via GitGitGadget

Add the Microsoft .manifest pattern, and do not anchor the 'Debug' and 'Release' entries at the top-level directory, to allow for multiple projects (one per target).

---
 .gitignore | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
.gitignore +0 -0
index e096e0a51c..e7bb15d301 100644

.gitignore line 233

Quoted 6 lines
.gitignore +1 -2
@@ -230,6 +230,7 @@
 *.ipdb
 *.dll
 .vs/
-/Debug/
-/Release/
+*.manifest

This new line ignores the tracked file 'compat/win32/git.manifest' that was added fairly recently in fe90397604 (mingw: embed a manifest to trick UAC into Doing The Right Thing, 2019-06-27).

I wonder whether that's intentional or accidental.

I'm inclined to think that it's merely accidental, because, as far as I understand, this is an old-ish patch from times when there wasn't any 'git.manifest' file in tree, and simply noone noticed that in the meantime we got one. But I have no idea about how a Git build with Visual Studio is supposed to work, so it doesn't really matter what I'm inclined to think :)

#52 lore raw

Re: [PATCH v2 20/23] .gitignore: touch up the entries regarding Visual Studio

Hi Szeder,

Quoted 26 lines · SZEDER Gábor
Quoted 15 lines · Philip Oakley via GitGitGadget

Add the Microsoft .manifest pattern, and do not anchor the 'Debug' and 'Release' entries at the top-level directory, to allow for multiple projects (one per target).

---
  .gitignore | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)
.gitignore +0 -0
index e096e0a51c..e7bb15d301 100644

.gitignore line 233

Quoted 6 lines
.gitignore +1 -2
@@ -230,6 +230,7 @@
  *.ipdb
  *.dll
  .vs/
-/Debug/
-/Release/
+*.manifest

This new line ignores the tracked file 'compat/win32/git.manifest' that was added fairly recently in fe90397604 (mingw: embed a manifest to trick UAC into Doing The Right Thing, 2019-06-27).

Quoted 9 lines

I wonder whether that's intentional or accidental.

I'm inclined to think that it's merely accidental, because, as far as I understand, this is an old-ish patch from times when there wasn't any 'git.manifest' file in tree, and simply noone noticed that in the meantime we got one. But I have no idea about how a Git build with Visual Studio is supposed to work, so it doesn't really matter what I'm inclined to think :)

At the time, it was just one of the many non-source files that were generated by Visual Studio that cluttered the status list and also could accidentally added to the tracked files.

The newly added .manifest file does appear to be there to 'trick' the Windows User Access Control (UAC) which otherwise can be an annoyance to 'regular' users. Philip

#53 lore raw

Re: [PATCH v2 20/23] .gitignore: touch up the entries regarding Visual Studio

Quoted 38 lines · Philip Oakley

Hi Szeder,

Quoted 26 lines · SZEDER Gábor
Quoted 15 lines · Philip Oakley via GitGitGadget

Add the Microsoft .manifest pattern, and do not anchor the 'Debug' and 'Release' entries at the top-level directory, to allow for multiple projects (one per target).

---
 .gitignore | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
.gitignore +0 -0
index e096e0a51c..e7bb15d301 100644

.gitignore line 233

Quoted 6 lines
.gitignore +1 -2
@@ -230,6 +230,7 @@
 *.ipdb
 *.dll
 .vs/
-/Debug/
-/Release/
+*.manifest

This new line ignores the tracked file 'compat/win32/git.manifest' that was added fairly recently in fe90397604 (mingw: embed a manifest to trick UAC into Doing The Right Thing, 2019-06-27).

Quoted 9 lines

I wonder whether that's intentional or accidental.

I'm inclined to think that it's merely accidental, because, as far as I understand, this is an old-ish patch from times when there wasn't any 'git.manifest' file in tree, and simply noone noticed that in the meantime we got one. But I have no idea about how a Git build with Visual Studio is supposed to work, so it doesn't really matter what I'm inclined to think :)

Quoted 7 lines

At the time, it was just one of the many non-source files that were generated by Visual Studio that cluttered the status list and also could accidentally added to the tracked files.

The newly added .manifest file does appear to be there to 'trick' the Windows User Access Control (UAC) which otherwise can be an annoyance to 'regular' users.

Sorry, I'm not sure how to interpret your reply, and can't decide whether it tries to justify why that tracked file should be ignored, or explains that ignoring it was accidental.

Anyway, ignoring that tracked file apparently triggered a nested worktree-related bug in 'git clean', which can lead to data loss:

https://public-inbox.org/git/[email protected]/

#54 lore raw

Re: [PATCH v2 20/23] .gitignore: touch up the entries regarding Visual Studio

Hi Szeder,

Quoted 46 lines · SZEDER Gábor
Quoted 38 lines · Philip Oakley

Hi Szeder,

Quoted 26 lines · SZEDER Gábor
Quoted 15 lines · Philip Oakley via GitGitGadget

Add the Microsoft .manifest pattern, and do not anchor the 'Debug' and 'Release' entries at the top-level directory, to allow for multiple projects (one per target).

---
  .gitignore | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)
.gitignore +0 -0
index e096e0a51c..e7bb15d301 100644

.gitignore line 233

Quoted 6 lines
.gitignore +1 -2
@@ -230,6 +230,7 @@
  *.ipdb
  *.dll
  .vs/
-/Debug/
-/Release/
+*.manifest

This new line ignores the tracked file 'compat/win32/git.manifest' that was added fairly recently in fe90397604 (mingw: embed a manifest to trick UAC into Doing The Right Thing, 2019-06-27).

Quoted 9 lines

I wonder whether that's intentional or accidental.

I'm inclined to think that it's merely accidental, because, as far as I understand, this is an old-ish patch from times when there wasn't any 'git.manifest' file in tree, and simply noone noticed that in the meantime we got one. But I have no idea about how a Git build with Visual Studio is supposed to work, so it doesn't really matter what I'm inclined to think :)

Quoted 7 lines

At the time, it was just one of the many non-source files that were generated by Visual Studio that cluttered the status list and also could accidentally added to the tracked files.

The newly added .manifest file does appear to be there to 'trick' the Windows User Access Control (UAC) which otherwise can be an annoyance to 'regular' users.

Quoted 9 lines

Sorry, I'm not sure how to interpret your reply, and can't decide whether it tries to justify why that tracked file should be ignored, or explains that ignoring it was accidental.

Anyway, ignoring that tracked file apparently triggered a nested worktree-related bug in 'git clean', which can lead to data loss:

https://public-inbox.org/git/[email protected]/

Basically manifests are a build artefact from Visual Studio [1], so it was just another file to be ignored, from a _source_ control control viewpoint.

I hadn't fully appreciated the reason for your question, but I can now see how the general 'ignore most, but keep an occasional' file type can be a problem for the git clean filter, along with sub-module repos in sub-directories. It probably extends beyond this special case .manifest file.

I doubt that dscho wants to also do file renaming to achieve the trick that added that file to avoid this. the clean command should never be ignoring (and possibly deleting) tracked files.

When clean hits a nested repo (maybe with .git directory - not sure of some of the sub-module changes) then it should stop referring to that top level gitignore, at least that's my expectation. The commit description in the referenced patch appears to get the two parts inter-twined.

Philip
[1] https://docs.microsoft.com/en-us/cpp/build/manifest-generation-in-visual-studio?view=vs-2019

#55 lore raw

Re: [PATCH v2 20/23] .gitignore: touch up the entries regarding Visual Studio

Quoted 35 lines · Philip Oakley
Quoted 35 lines
Quoted 24 lines
Quoted 15 lines

.gitignore line 233

Quoted 11 lines
.gitignore +1 -2
index e096e0a51c..e7bb15d301 100644
@@ -230,6 +230,7 @@
 *.ipdb
 *.dll
 .vs/
-/Debug/
-/Release/
+*.manifest

This new line ignores the tracked file 'compat/win32/git.manifest' that was added fairly recently in fe90397604 (mingw: embed a manifest to trick UAC into Doing The Right Thing, 2019-06-27).

Quoted 9 lines

I wonder whether that's intentional or accidental.

I'm inclined to think that it's merely accidental, because, as far as I understand, this is an old-ish patch from times when there wasn't any 'git.manifest' file in tree, and simply noone noticed that in the meantime we got one. But I have no idea about how a Git build with Visual Studio is supposed to work, so it doesn't really matter what I'm inclined to think :)

Quoted 7 lines

At the time, it was just one of the many non-source files that were generated by Visual Studio that cluttered the status list and also could accidentally added to the tracked files.

The newly added .manifest file does appear to be there to 'trick' the Windows User Access Control (UAC) which otherwise can be an annoyance to 'regular' users.

Sorry, I'm not sure how to interpret your reply, and can't decide whether it tries to justify why that tracked file should be ignored, or explains that ignoring it was accidental.

Quoted 7 lines
Quoted 5 lines

Anyway, ignoring that tracked file apparently triggered a nested worktree-related bug in 'git clean', which can lead to data loss:

https://public-inbox.org/git/[email protected]/

Basically manifests are a build artefact from Visual Studio [1], so it was just another file to be ignored, from a _source_ control control viewpoint.

I understand that manifest files, in general, are build artifacts. But does Visual Studio overwrite the existing 'compat/win32/git.manifest' file in particular? Yes or no? :)

#56 lore raw

Re: [PATCH v2 20/23] .gitignore: touch up the entries regarding Visual Studio

Hi Gábor,

Quoted 39 lines · SZEDER Gábor
Quoted 38 lines · Philip Oakley
Quoted 38 lines
Quoted 24 lines
Quoted 15 lines

.gitignore line 233

Quoted 11 lines
.gitignore +1 -2
index e096e0a51c..e7bb15d301 100644
@@ -230,6 +230,7 @@
 *.ipdb
 *.dll
 .vs/
-/Debug/
-/Release/
+*.manifest

This new line ignores the tracked file 'compat/win32/git.manifest' that was added fairly recently in fe90397604 (mingw: embed a manifest to trick UAC into Doing The Right Thing, 2019-06-27).

Quoted 9 lines

I wonder whether that's intentional or accidental.

I'm inclined to think that it's merely accidental, because, as far as I understand, this is an old-ish patch from times when there wasn't any 'git.manifest' file in tree, and simply noone noticed that in the meantime we got one. But I have no idea about how a Git build with Visual Studio is supposed to work, so it doesn't really matter what I'm inclined to think :)

Quoted 7 lines

At the time, it was just one of the many non-source files that were generated by Visual Studio that cluttered the status list and also could accidentally added to the tracked files.

The newly added .manifest file does appear to be there to 'trick' the Windows User Access Control (UAC) which otherwise can be an annoyance to 'regular' users.

Sorry, I'm not sure how to interpret your reply, and can't decide whether it tries to justify why that tracked file should be ignored, or explains that ignoring it was accidental.

Anyway, ignoring that tracked file apparently triggered a nested worktree-related bug in 'git clean', which can lead to data loss:

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

https://public-inbox.org/git/[email protected]/

Basically manifests are a build artefact from Visual Studio [1], so it was just another file to be ignored, from a _source_ control control viewpoint.

I understand that manifest files, in general, are build artifacts. But does Visual Studio overwrite the existing 'compat/win32/git.manifest' file in particular? Yes or no? :)

No.

The reason this entry was there: at least _some_ Visual Studio versions (IIRC), auto-generates .manifest files when the project does not have any. But now we do. So this line's gotta go.

#leftoverbits ?

Ciao,
Dscho

#57 lore raw

Re: [PATCH v2 20/23] .gitignore: touch up the entries regarding Visual Studio

In reply to Philip Oakley

Hi,

Quoted 31 lines · Philip Oakley
Quoted 30 lines · SZEDER Gábor
Quoted 29 lines · Philip Oakley
Quoted 27 lines · SZEDER Gábor
Quoted 15 lines · Philip Oakley via GitGitGadget

Add the Microsoft .manifest pattern, and do not anchor the 'Debug' and 'Release' entries at the top-level directory, to allow for multiple projects (one per target).

---
  .gitignore | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)
.gitignore +0 -0
index e096e0a51c..e7bb15d301 100644

.gitignore line 233

Quoted 6 lines
.gitignore +1 -2
@@ -230,6 +230,7 @@
  *.ipdb
  *.dll
  .vs/
-/Debug/
-/Release/
+*.manifest

This new line ignores the tracked file 'compat/win32/git.manifest' that was added fairly recently in fe90397604 (mingw: embed a manifest to trick UAC into Doing The Right Thing, 2019-06-27).

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

I wonder whether that's intentional or accidental.

This was an oversight of mine, my apologies. That line should go.

Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Quoted 7 lines

I'm inclined to think that it's merely accidental, because, as far as I understand, this is an old-ish patch from times when there wasn't any 'git.manifest' file in tree, and simply noone noticed that in the meantime we got one. But I have no idea about how a Git build with Visual Studio is supposed to work, so it doesn't really matter what I'm inclined to think :)

At the time, it was just one of the many non-source files that were generated by Visual Studio that cluttered the status list and also could accidentally added to the tracked files.

The newly added .manifest file does appear to be there to 'trick' the Windows User Access Control (UAC) which otherwise can be an annoyance to 'regular' users.

Quoted 8 lines
Quoted 8 lines

Sorry, I'm not sure how to interpret your reply, and can't decide whether it tries to justify why that tracked file should be ignored, or explains that ignoring it was accidental.

Anyway, ignoring that tracked file apparently triggered a nested worktree-related bug in 'git clean', which can lead to data loss:

https://public-inbox.org/git/[email protected]/

Whoa. At least we found a bug via my oversight ;-)

Quoted 2 lines

Basically manifests are a build artefact from Visual Studio [1], so it was just another file to be ignored, from a _source_ control control viewpoint.

More precisely, manifest files are something specific to Windows, where you can embed metadata in an executable. Visual Studio auto-generated it under certain circumstances, but recent versions seem not to do that anymore.

Ciao,
Dscho

Quoted 18 lines

I hadn't fully appreciated the reason for your question, but I can now see how the general 'ignore most, but keep an occasional' file type can be a problem for the git clean filter, along with sub-module repos in sub-directories. It probably extends beyond this special case .manifest file.

I doubt that dscho wants to also do file renaming to achieve the trick that added that file to avoid this. the clean command should never be ignoring (and possibly deleting) tracked files.

When clean hits a nested repo (maybe with .git directory - not sure of some of the sub-module changes) then it should stop referring to that top level gitignore, at least that's my expectation. The commit description in the referenced patch appears to get the two parts inter-twined.

Philip
[1]
https://docs.microsoft.com/en-us/cpp/build/manifest-generation-in-visual-studio?view=vs-2019

#58 lore raw

Re: [PATCH v2 20/23] .gitignore: touch up the entries regarding Visual Studio

Quoted 13 lines · Johannes Schindelin
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines

.gitignore line 233

Quoted 9 lines
.gitignore +1 -2
@@ -230,6 +230,7 @@
  *.ipdb
  *.dll
  .vs/
-/Debug/
-/Release/
+*.manifest

This new line ignores the tracked file 'compat/win32/git.manifest' that was added fairly recently in fe90397604 (mingw: embed a manifest to trick UAC into Doing The Right Thing, 2019-06-27).

Quoted 3 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

I wonder whether that's intentional or accidental.

This was an oversight of mine, my apologies. That line should go.

Good to see people finding glitches in topics that have graduated to 'master' not so long ago. It would have been even nicer if we found them while in 'next', but we are all human ;-)

Quoted 4 lines

More precisely, manifest files are something specific to Windows, where you can embed metadata in an executable. Visual Studio auto-generated it under certain circumstances, but recent versions seem not to do that anymore.

I expect somebody who knows Windows .manifest better than I do to come up with a one-liner patch with a single paragraph log message. Or it can just be a part of a larger series that is the next batch of Windows updates.

Thanks.

#59 lore raw

PATCH v2 21/23 .gitignore: ignore Visual Studio's temporary/generated files

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

---
 .gitignore | 3 +++
 1 file changed, 3 insertions(+)
.gitignore +3 -0
index e7bb15d301..fcfb708b9e 100644
@@ -233,4 +233,7 @@
 *.manifest
 Debug/
 Release/
+/UpgradeLog*.htm
+/git.VC.VC.opendb
+/git.VC.db
 *.dSYM
Signature · 1 line
gitgitgadget
#60 lore raw

PATCH v2 22/23 bin-wrappers: append `.exe` to target paths if necessary

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

When compiling with Visual Studio, the projects' names are identical to the executables modulo the extensions. Read: there will exist both a directory called git as well as an executable called git.exe in the end. Which means that the bin-wrappers *need* to target the .exe files lest they try to execute directories.

---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Makefile +1 -1
index 98a0588416..3716dadc08 100644
@@ -2717,7 +2717,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.
Signature · 1 line
gitgitgadget
#61 lore raw

PATCH v2 23/23 git: avoid calling aliased builtins via their dashed form

In reply to Johannes Schindelin via GitGitGadget

From: Johannes Schindelin <[email protected]>

This is one of the few places where Git violates its own deprecation of the dashed form. It is not necessary, either.

As of 595d59e2b53 (git.c: ignore pager.* when launching builtin as dashed external, 2017-08-02), Git wants to ignore the pager.* config setting when expanding aliases. So let's strip out the check_pager_config(<command-name>) call from the copy-edited code.

This code actually made it into upstream git.git already, but it was disabled in #if 0 ... #endif guards so far.

---
 git.c | 3 ---
 1 file changed, 3 deletions(-)
git.c +0 -3
index f4c0478f32..3049dae85b 100644
@@ -743,8 +743,6 @@ static int run_argv(int *argcp, const char ***argv)
 		 */
 		if (!done_alias)
 			handle_builtin(*argcp, *argv);
-
-#if 0 // TODO In GFW, need to amend a7924b655e940b06cb547c235d6bed9767929673 to include trace2_ and _tr2 lines.
 		else if (get_builtin(**argv)) {
 			struct argv_array args = ARGV_ARRAY_INIT;
 			int i;
@@ -779,7 +777,6 @@ static int run_argv(int *argcp, const char ***argv)
 				exit(i);
 			die("could not execute builtin %s", **argv);
 		}
-#endif // a7924b655e940b06cb547c235d6bed9767929673
 
 		/* .. then try the external ones */
 		execv_dashed_external(*argv);
Signature · 1 line
gitgitgadget
#62 lore raw
In reply to Johannes Schindelin via GitGitGadget

"Johannes Schindelin via GitGitGadget" <[email protected]>

Quoted 7 lines · writes:

A long time ago, we added support to build .sln and .vcproj files for use within Visual Studio, so that Git could be built in that popular IDE.
...
Changes since v1:

* The empty directory templates/blt/branches/ is now created as part of the build.

This did not cut today's pushout, but replacing the topic branch and rebuilding 'pu' was quite straight-forward with just a single liner change ;-)

It will appear in 'next' sometime tomorrow.

Thanks.