diff --git a/Makefile b/Makefile index 3404a091c8120e..fbb71a28e81828 100644 --- a/Makefile +++ b/Makefile @@ -3000,6 +3000,10 @@ rpm:: @false .PHONY: rpm +ifneq ($(INCLUDE_DLLS_IN_ARTIFACTS),) +OTHER_PROGRAMS += $(shell echo *.dll t/helper/*.dll) +endif + artifacts-tar:: $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) $(OTHER_PROGRAMS) \ GIT-BUILD-OPTIONS $(TEST_PROGRAMS) $(test_bindir_programs) \ $(NO_INSTALL) $(MOFILES) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c329b7218bb361..fe587ebd8d42d9 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,6 +1,5 @@ -resources: -- repo: self - fetchDepth: 1 +variables: + Agent.Source.Git.ShallowFetchDepth: 1 jobs: - job: windows_build @@ -131,6 +130,147 @@ jobs: PathtoPublish: t/failed-test-artifacts ArtifactName: failed-test-artifacts +- job: msvc_build + displayName: Windows (MSVC) Build + condition: succeeded() + pool: Hosted VS2017 + timeoutInMinutes: 240 + steps: + - powershell: | + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no + cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\ + } + displayName: 'Mount test-cache' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - powershell: | + $urlbase = "https://dev.azure.com/git/git/_apis/build/builds" + $id = ((Invoke-WebRequest -UseBasicParsing "${urlbase}?definitions=9&statusFilter=completed&resultFilter=succeeded&`$top=1").content | ConvertFrom-JSON).value[0].id + $downloadUrl = ((Invoke-WebRequest -UseBasicParsing "${urlbase}/$id/artifacts").content | ConvertFrom-JSON).value[0].resource.downloadUrl + (New-Object Net.WebClient).DownloadFile($downloadUrl, "compat.zip") + Expand-Archive compat.zip -DestinationPath . -Force + Remove-Item compat.zip + displayName: 'Download vcpkg artifacts' + - powershell: | + $urlbase = "https://dev.azure.com/git-for-windows/git/_apis/build/builds" + $id = ((Invoke-WebRequest -UseBasicParsing "${urlbase}?definitions=22&statusFilter=completed&resultFilter=succeeded&`$top=1").content | ConvertFrom-JSON).value[0].id + $downloadUrl = ((Invoke-WebRequest -UseBasicParsing "${urlbase}/$id/artifacts").content | ConvertFrom-JSON).value[1].resource.downloadUrl + (New-Object Net.WebClient).DownloadFile($downloadUrl, "git-sdk-64-minimal.zip") + Expand-Archive git-sdk-64-minimal.zip -DestinationPath . -Force + Remove-Item git-sdk-64-minimal.zip + + # Let Git ignore the SDK and the test-cache + "/git-sdk-64-minimal/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude" + displayName: 'Download git-sdk-64-minimal' + - powershell: | + & compat\vcbuild\vcpkg_copy_dlls.bat release + if (!$?) { exit(1) } + & git-sdk-64-minimal\usr\bin\bash.exe -lc @" + INCLUDE_DLLS_IN_ARTIFACTS=YesPlease \ + ci/make-test-artifacts.sh artifacts + "@ + if (!$?) { exit(1) } + displayName: Build + env: + HOME: $(Build.SourcesDirectory) + MSYSTEM: MINGW64 + DEVELOPER: 1 + NO_PERL: 1 + MSVC: 1 + VCPKG_ROOT: $(Build.SourcesDirectory)\compat\vcbuild\vcpkg + - task: PublishPipelineArtifact@0 + displayName: 'Publish Pipeline Artifact: MSVC test artifacts' + inputs: + artifactName: 'msvc-artifacts' + targetPath: '$(Build.SourcesDirectory)\artifacts' + - task: PublishPipelineArtifact@0 + displayName: 'Publish Pipeline Artifact: git-sdk-64-min-msvc' + inputs: + artifactName: 'git-sdk-64-min-msvc' + targetPath: '$(Build.SourcesDirectory)\git-sdk-64-minimal' + - powershell: | + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + cmd /c rmdir "$(Build.SourcesDirectory)\test-cache" + } + displayName: 'Unmount test-cache' + condition: true + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + +- job: msvc_test + displayName: Windows (MSVC) Test + dependsOn: msvc_build + condition: succeeded() + pool: Hosted + timeoutInMinutes: 240 + strategy: + parallel: 10 + steps: + - powershell: | + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + net use s: \\gitfileshare.file.core.windows.net\test-cache "$GITFILESHAREPWD" /user:AZURE\gitfileshare /persistent:no + cmd /c mklink /d "$(Build.SourcesDirectory)\test-cache" S:\ + } + displayName: 'Mount test-cache' + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: DownloadPipelineArtifact@0 + displayName: 'Download Pipeline Artifact: MSVC test artifacts' + inputs: + artifactName: 'msvc-artifacts' + targetPath: '$(Build.SourcesDirectory)' + - task: DownloadPipelineArtifact@0 + displayName: 'Download Pipeline Artifact: git-sdk-64-min-msvc' + inputs: + artifactName: 'git-sdk-64-min-msvc' + targetPath: '$(Build.SourcesDirectory)\git-sdk-64-minimal' + - powershell: | + & git-sdk-64-minimal\usr\bin\bash.exe -lc @" + test -f artifacts.tar.gz || { + echo No test artifacts found\; skipping >&2 + exit 0 + } + tar xf artifacts.tar.gz || exit 1 + + # Let Git ignore the SDK and the test-cache + printf '%s\n' /git-sdk-64-minimal/ /test-cache/ >>.git/info/exclude + + ci/run-test-slice.sh `$SYSTEM_JOBPOSITIONINPHASE `$SYSTEM_TOTALJOBSINPHASE || { + ci/print-test-failures.sh + exit 1 + } + "@ + if (!$?) { exit(1) } + displayName: 'Test (parallel)' + env: + HOME: $(Build.SourcesDirectory) + MSYSTEM: MINGW64 + NO_SVN_TESTS: 1 + GIT_TEST_SKIP_REBASE_P: 1 + - powershell: | + if ("$GITFILESHAREPWD" -ne "" -and "$GITFILESHAREPWD" -ne "`$`(gitfileshare.pwd)") { + cmd /c rmdir "$(Build.SourcesDirectory)\test-cache" + } + displayName: 'Unmount test-cache' + condition: true + env: + GITFILESHAREPWD: $(gitfileshare.pwd) + - task: PublishTestResults@2 + displayName: 'Publish Test Results **/TEST-*.xml' + inputs: + mergeTestResults: true + testRunTitle: 'msvc' + platform: Windows + publishRunAttachments: false + condition: succeededOrFailed() + - task: PublishBuildArtifacts@1 + displayName: 'Publish trash directories of failed tests' + condition: failed() + inputs: + PathtoPublish: t/failed-test-artifacts + ArtifactName: failed-msvc-test-artifacts + - job: linux_clang displayName: linux-clang condition: succeeded() diff --git a/builtin/push.c b/builtin/push.c index 021dd3b1e48979..d216270d5fa39f 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -143,8 +143,8 @@ static int push_url_of_remote(struct remote *remote, const char ***url_p) return remote->url_nr; } -static NORETURN int die_push_simple(struct branch *branch, - struct remote *remote) +static NORETURN void die_push_simple(struct branch *branch, + struct remote *remote) { /* * There's no point in using shorten_unambiguous_ref here, diff --git a/ci/lib.sh b/ci/lib.sh index 288a5b3884ad82..93a5cba811d761 100755 --- a/ci/lib.sh +++ b/ci/lib.sh @@ -116,6 +116,11 @@ then CI_OS_NAME="$(echo "$AGENT_OS" | tr A-Z a-z)" test darwin != "$CI_OS_NAME" || CI_OS_NAME=osx CI_REPO_SLUG="$(expr "$BUILD_REPOSITORY_URI" : '.*/\([^/]*/[^/]*\)$')" + if test -n "$MSVC" + then + CC=compat/vcbuild/scripts/clink.pl + jobname=windows-msvc + fi CC="${CC:-gcc}" # use a subdirectory of the cache dir (because the file share is shared diff --git a/compat/mingw.c b/compat/mingw.c index 3164814fc49d7f..e4583ace621af0 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2072,6 +2072,8 @@ char *mingw_getenv(const char *name) if (!w_key) die("Out of memory, (tried to allocate %u wchar_t's)", len_key); xutftowcs(w_key, name, len_key); + /* GetEnvironmentVariableW() only sets the last error upon failure */ + SetLastError(ERROR_SUCCESS); len_value = GetEnvironmentVariableW(w_key, w_value, ARRAY_SIZE(w_value)); if (!len_value && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { free(w_key); diff --git a/compat/vcbuild/scripts/clink.pl b/compat/vcbuild/scripts/clink.pl index 3d6fa21c1e5690..4ccfc319d51fdf 100755 --- a/compat/vcbuild/scripts/clink.pl +++ b/compat/vcbuild/scripts/clink.pl @@ -55,8 +55,54 @@ } elsif ("$arg" =~ /^-L/ && "$arg" ne "-LTCG") { $arg =~ s/^-L/-LIBPATH:/; push(@lflags, $arg); - } elsif ("$arg" =~ /^-R/) { + } elsif ("$arg" =~ /^-[Rl]/) { # eat + } elsif ("$arg" eq "-Werror") { + push(@cflags, "-WX"); + } elsif ("$arg" eq "-Wall") { + # cl.exe understands -Wall, but it is really overzealous + push(@cflags, "-W4"); + # disable the "signed/unsigned mismatch" warnings; our source code violates that + push(@cflags, "-wd4018"); + push(@cflags, "-wd4245"); + push(@cflags, "-wd4389"); + # disable the "unreferenced formal parameter" warning; our source code violates that + push(@cflags, "-wd4100"); + # disable the "conditional expression is constant" warning; our source code violates that + push(@cflags, "-wd4127"); + # disable the "const object should be initialized" warning; these warnings affect only objects that are `static` + push(@cflags, "-wd4132"); + # disable the "function/data pointer conversion in expression" warning; our source code violates that + push(@cflags, "-wd4152"); + # disable the "non-constant aggregate initializer" warning; our source code violates that + push(@cflags, "-wd4204"); + # disable the "cannot be initialized using address of automatic variable" warning; our source code violates that + push(@cflags, "-wd4221"); + # disable the "possible loss of data" warnings; our source code violates that + push(@cflags, "-wd4244"); + push(@cflags, "-wd4267"); + # disable the "array is too small to include a terminating null character" warning; we ab-use strings to initialize OIDs + push(@cflags, "-wd4295"); + # disable the "'<<': result of 32-bit shift implicitly converted to 64 bits" warning; our source code violates that + push(@cflags, "-wd4334"); + # disable the "declaration hides previous local declaration" warning; our source code violates that + push(@cflags, "-wd4456"); + # disable the "declaration hides function parameter" warning; our source code violates that + push(@cflags, "-wd4457"); + # disable the "declaration hides global declaration" warning; our source code violates that + push(@cflags, "-wd4459"); + # disable the "potentially uninitialized local variable '' used" warning; our source code violates that + push(@cflags, "-wd4701"); + # disable the "unreachable code" warning; our source code violates that + push(@cflags, "-wd4702"); + # disable the "potentially uninitialized local pointer variable used" warning; our source code violates that + push(@cflags, "-wd4703"); + # disable the "assignment within conditional expression" warning; our source code violates that + push(@cflags, "-wd4706"); + # disable the "'inet_ntoa': Use inet_ntop() or InetNtop() instead" warning; our source code violates that + push(@cflags, "-wd4996"); + } elsif ("$arg" =~ /^-W[a-z]/) { + # let's ignore those } else { push(@args, $arg); } diff --git a/compat/vcbuild/vcpkg_install.bat b/compat/vcbuild/vcpkg_install.bat index 3d086c39c31a53..ebd0bad242a8ca 100644 --- a/compat/vcbuild/vcpkg_install.bat +++ b/compat/vcbuild/vcpkg_install.bat @@ -53,8 +53,7 @@ REM ================================================================ echo Installing third-party libraries... FOR %%i IN (zlib expat libiconv openssl libssh2 curl) DO ( cd %cwd%vcpkg - SET p="packages\%%i_%arch%" - IF NOT EXIST "%p%" CALL :sub__install_one %%i + IF NOT EXIST "packages\%%i_%arch%" CALL :sub__install_one %%i IF ERRORLEVEL 1 ( EXIT /B 1 ) ) diff --git a/compat/win32/fscache.c b/compat/win32/fscache.c index a80c59c948e95e..f1d885c6d888db 100644 --- a/compat/win32/fscache.c +++ b/compat/win32/fscache.c @@ -65,8 +65,8 @@ struct fsentry { struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; - }; - }; + } s; + } u; }; /* @@ -127,7 +127,7 @@ static struct fsentry *fsentry_alloc(struct fscache *cache, struct fsentry *list /* init the rest of the structure */ fsentry_init(fse, list, nm, len); fse->next = NULL; - fse->refcnt = 1; + fse->u.refcnt = 1; return fse; } @@ -139,7 +139,7 @@ inline static void fsentry_addref(struct fsentry *fse) if (fse->list) fse = fse->list; - InterlockedIncrement(&(fse->refcnt)); + InterlockedIncrement(&(fse->u.refcnt)); } /* @@ -150,7 +150,7 @@ static void fsentry_release(struct fsentry *fse) if (fse->list) fse = fse->list; - InterlockedDecrement(&(fse->refcnt)); + InterlockedDecrement(&(fse->u.refcnt)); } static int xwcstoutfn(char *utf, int utflen, const wchar_t *wcs, int wcslen) @@ -205,11 +205,11 @@ static struct fsentry *fseentry_create_entry(struct fscache *cache, struct fsent fse->st_mode = file_attr_to_st_mode(fdata->FileAttributes, fdata->EaSize, buf); - fse->st_size = S_ISLNK(fse->st_mode) ? MAX_LONG_PATH : + fse->u.s.st_size = S_ISLNK(fse->st_mode) ? MAX_LONG_PATH : fdata->EndOfFile.LowPart | (((off_t)fdata->EndOfFile.HighPart) << 32); - filetime_to_timespec((FILETIME *)&(fdata->LastAccessTime), &(fse->st_atim)); - filetime_to_timespec((FILETIME *)&(fdata->LastWriteTime), &(fse->st_mtim)); - filetime_to_timespec((FILETIME *)&(fdata->CreationTime), &(fse->st_ctim)); + filetime_to_timespec((FILETIME *)&(fdata->LastAccessTime), &(fse->u.s.st_atim)); + filetime_to_timespec((FILETIME *)&(fdata->LastWriteTime), &(fse->u.s.st_mtim)); + filetime_to_timespec((FILETIME *)&(fdata->CreationTime), &(fse->u.s.st_ctim)); return fse; } @@ -578,10 +578,10 @@ int fscache_lstat(const char *filename, struct stat *st) st->st_rdev = 0; st->st_nlink = 1; st->st_mode = fse->st_mode; - st->st_size = fse->st_size; - st->st_atim = fse->st_atim; - st->st_mtim = fse->st_mtim; - st->st_ctim = fse->st_ctim; + st->st_size = fse->u.s.st_size; + st->st_atim = fse->u.s.st_atim; + st->st_mtim = fse->u.s.st_mtim; + st->st_ctim = fse->u.s.st_ctim; /* don't forget to release fsentry */ fsentry_release(fse); diff --git a/compat/win32/ntifs.h b/compat/win32/ntifs.h index bcc71c7dd9c5ef..3098f863cbdb21 100644 --- a/compat/win32/ntifs.h +++ b/compat/win32/ntifs.h @@ -99,7 +99,7 @@ typedef struct _IO_STATUS_BLOCK { union { NTSTATUS Status; PVOID Pointer; - } DUMMYUNIONNAME; + } u; ULONG_PTR Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; diff --git a/compat/win32/path-utils.h b/compat/win32/path-utils.h index 0f70d439204fbe..8ed062a6b7887e 100644 --- a/compat/win32/path-utils.h +++ b/compat/win32/path-utils.h @@ -1,3 +1,6 @@ +#ifndef WIN32_PATH_UTILS_H +#define WIN32_PATH_UTILS_H + #define has_dos_drive_prefix(path) \ (isalpha(*(path)) && (path)[1] == ':' ? 2 : 0) int win32_skip_dos_drive_prefix(char **path); @@ -18,3 +21,5 @@ static inline char *win32_find_last_dir_sep(const char *path) #define find_last_dir_sep win32_find_last_dir_sep int win32_offset_1st_component(const char *path); #define offset_1st_component win32_offset_1st_component + +#endif diff --git a/compat/winansi.c b/compat/winansi.c index 087406a4f7f70a..32aca79dd34af6 100644 --- a/compat/winansi.c +++ b/compat/winansi.c @@ -546,7 +546,7 @@ static HANDLE swap_osfhnd(int fd, HANDLE new_handle) typedef struct _OBJECT_NAME_INFORMATION { UNICODE_STRING Name; - WCHAR NameBuffer[0]; + WCHAR NameBuffer[FLEX_ARRAY]; } OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; #define ObjectNameInformation 1 diff --git a/config.mak.uname b/config.mak.uname index a89649ac60c9fc..5cbac1cbff4695 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -451,7 +451,7 @@ endif # Always give "-Zi" to the compiler and "-debug" to linker (even in # release mode) to force a PDB to be generated (like RelWithDebInfo). BASIC_CFLAGS += -Zi - BASIC_LDFLAGS += -debug + BASIC_LDFLAGS += -debug -Zf ifdef NO_SAFESEH LDFLAGS += -SAFESEH:NO diff --git a/git-compat-util.h b/git-compat-util.h index e0275da7e0a794..9be177e588114c 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -210,6 +210,7 @@ #include "compat/mingw.h" #include "compat/win32/fscache.h" #elif defined(_MSC_VER) +#include "compat/win32/path-utils.h" #include "compat/msvc.h" #include "compat/win32/fscache.h" #else diff --git a/read-cache.c b/read-cache.c index bbcf488c20a483..4ed05df715276c 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1266,7 +1266,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e */ if (istate->cache_nr > 0 && strcmp(ce->name, istate->cache[istate->cache_nr - 1]->name) > 0) - pos = -istate->cache_nr - 1; + pos = -1 - istate->cache_nr; else pos = index_name_stage_pos(istate, ce->name, ce_namelen(ce), ce_stage(ce)); @@ -1899,7 +1899,7 @@ static size_t estimate_cache_size(size_t ondisk_size, unsigned int entries) /* * Account for potential alignment differences. */ - per_entry += align_padding_size(sizeof(struct cache_entry), -sizeof(struct ondisk_cache_entry)); + per_entry += align_padding_size(per_entry, 0); return ondisk_size + entries * per_entry; } diff --git a/sha1-lookup.c b/sha1-lookup.c index 796ab68da83c3a..c8196877309369 100644 --- a/sha1-lookup.c +++ b/sha1-lookup.c @@ -97,7 +97,7 @@ int sha1_pos(const unsigned char *sha1, void *table, size_t nr, lo = mi + 1; mi = lo + (hi - lo) / 2; } while (lo < hi); - return -lo-1; + return -1 - lo; } int bsearch_hash(const unsigned char *sha1, const uint32_t *fanout_nbo,