mirror of
https://github.com/git/git.git
synced 2026-01-17 14:21:57 +00:00
Merge branch 'ready-for-upstream'
This is the branch thicket of patches in Git for Windows that are considered ready for upstream. To keep them in a ready-to-submit shape, they are kept as close to the beginning of the branch thicket as possible.
This commit is contained in:
@@ -406,6 +406,8 @@ include::config/reset.txt[]
|
||||
|
||||
include::config/sendemail.txt[]
|
||||
|
||||
include::config/sendpack.txt[]
|
||||
|
||||
include::config/sequencer.txt[]
|
||||
|
||||
include::config/showbranch.txt[]
|
||||
|
||||
5
Documentation/config/sendpack.txt
Normal file
5
Documentation/config/sendpack.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
sendpack.sideband::
|
||||
Allows to disable the side-band-64k capability for send-pack even
|
||||
when it is advertised by the server. Makes it possible to work
|
||||
around a limitation in the git for windows implementation together
|
||||
with the dump git protocol. Defaults to true.
|
||||
@@ -10,6 +10,7 @@ SYNOPSIS
|
||||
[verse]
|
||||
'git reset' [-q] [<tree-ish>] [--] <paths>...
|
||||
'git reset' (--patch | -p) [<tree-ish>] [--] [<paths>...]
|
||||
EXPERIMENTAL: 'git reset' [-q] [--stdin [-z]] [<tree-ish>]
|
||||
'git reset' [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]
|
||||
|
||||
DESCRIPTION
|
||||
@@ -100,6 +101,15 @@ OPTIONS
|
||||
`reset.quiet` config option. `--quiet` and `--no-quiet` will
|
||||
override the default behavior.
|
||||
|
||||
--stdin::
|
||||
EXPERIMENTAL: Instead of taking list of paths from the
|
||||
command line, read list of paths from the standard input.
|
||||
Paths are separated by LF (i.e. one path per line) by
|
||||
default.
|
||||
|
||||
-z::
|
||||
EXPERIMENTAL: Only meaningful with `--stdin`; paths are
|
||||
separated with NUL character instead of LF.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
[](https://dev.azure.com/git/git/_build/latest?definitionId=2)
|
||||
|
||||
Git - fast, scalable, distributed revision control system
|
||||
=========================================================
|
||||
|
||||
|
||||
342
azure-pipelines.yml
Normal file
342
azure-pipelines.yml
Normal file
@@ -0,0 +1,342 @@
|
||||
resources:
|
||||
- repo: self
|
||||
fetchDepth: 1
|
||||
|
||||
phases:
|
||||
- phase: linux_clang
|
||||
displayName: linux-clang
|
||||
condition: succeeded()
|
||||
queue:
|
||||
name: Hosted Ubuntu 1604
|
||||
steps:
|
||||
- bash: |
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
|
||||
|
||||
sudo apt-get update &&
|
||||
sudo rm /var/lib/apt/lists/lock &&
|
||||
sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin &&
|
||||
|
||||
export CC=clang || exit 1
|
||||
|
||||
ci/install-dependencies.sh
|
||||
ci/run-build-and-tests.sh || {
|
||||
ci/print-test-failures.sh
|
||||
exit 1
|
||||
}
|
||||
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
|
||||
displayName: 'ci/run-build-and-tests.sh'
|
||||
env:
|
||||
GITFILESHAREPWD: $(gitfileshare.pwd)
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results **/TEST-*.xml'
|
||||
inputs:
|
||||
mergeTestResults: true
|
||||
testRunTitle: 'linux-clang'
|
||||
platform: Linux
|
||||
publishRunAttachments: false
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- phase: linux_gcc
|
||||
displayName: linux-gcc
|
||||
condition: succeeded()
|
||||
queue:
|
||||
name: Hosted Ubuntu 1604
|
||||
steps:
|
||||
- bash: |
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
|
||||
|
||||
sudo apt-get update &&
|
||||
sudo rm /var/lib/apt/lists/lock &&
|
||||
sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev apache2-bin || exit 1
|
||||
|
||||
ci/install-dependencies.sh
|
||||
ci/run-build-and-tests.sh || {
|
||||
ci/print-test-failures.sh
|
||||
exit 1
|
||||
}
|
||||
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
|
||||
displayName: 'ci/run-build-and-tests.sh'
|
||||
env:
|
||||
GITFILESHAREPWD: $(gitfileshare.pwd)
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results **/TEST-*.xml'
|
||||
inputs:
|
||||
mergeTestResults: true
|
||||
testRunTitle: 'linux-gcc'
|
||||
platform: Linux
|
||||
publishRunAttachments: false
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- phase: osx_clang
|
||||
displayName: osx-clang
|
||||
condition: succeeded()
|
||||
queue:
|
||||
name: Hosted macOS
|
||||
steps:
|
||||
- bash: |
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
|
||||
|
||||
export CC=clang
|
||||
|
||||
ci/install-dependencies.sh
|
||||
ci/run-build-and-tests.sh || {
|
||||
ci/print-test-failures.sh
|
||||
exit 1
|
||||
}
|
||||
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1
|
||||
displayName: 'ci/run-build-and-tests.sh'
|
||||
env:
|
||||
GITFILESHAREPWD: $(gitfileshare.pwd)
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results **/TEST-*.xml'
|
||||
inputs:
|
||||
mergeTestResults: true
|
||||
testRunTitle: 'osx-clang'
|
||||
platform: macOS
|
||||
publishRunAttachments: false
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- phase: osx_gcc
|
||||
displayName: osx-gcc
|
||||
condition: succeeded()
|
||||
queue:
|
||||
name: Hosted macOS
|
||||
steps:
|
||||
- bash: |
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
|
||||
|
||||
ci/install-dependencies.sh
|
||||
ci/run-build-and-tests.sh || {
|
||||
ci/print-test-failures.sh
|
||||
exit 1
|
||||
}
|
||||
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || umount "$HOME/test-cache" || exit 1
|
||||
displayName: 'ci/run-build-and-tests.sh'
|
||||
env:
|
||||
GITFILESHAREPWD: $(gitfileshare.pwd)
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results **/TEST-*.xml'
|
||||
inputs:
|
||||
mergeTestResults: true
|
||||
testRunTitle: 'osx-gcc'
|
||||
platform: macOS
|
||||
publishRunAttachments: false
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- phase: gettext_poison
|
||||
displayName: GETTEXT_POISON
|
||||
condition: succeeded()
|
||||
queue:
|
||||
name: Hosted Ubuntu 1604
|
||||
steps:
|
||||
- bash: |
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
|
||||
|
||||
sudo apt-get update &&
|
||||
sudo rm /var/lib/apt/lists/lock &&
|
||||
sudo apt-get -y install git gcc make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext git-email zlib1g-dev &&
|
||||
|
||||
export jobname=GETTEXT_POISON || exit 1
|
||||
|
||||
ci/run-build-and-tests.sh || {
|
||||
ci/print-test-failures.sh
|
||||
exit 1
|
||||
}
|
||||
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
|
||||
displayName: 'ci/run-build-and-tests.sh'
|
||||
env:
|
||||
GITFILESHAREPWD: $(gitfileshare.pwd)
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results **/TEST-*.xml'
|
||||
inputs:
|
||||
mergeTestResults: true
|
||||
testRunTitle: 'gettext-poison'
|
||||
platform: Linux
|
||||
publishRunAttachments: false
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- phase: windows
|
||||
displayName: Windows
|
||||
queue:
|
||||
name: Hosted
|
||||
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: |
|
||||
# Helper to check the error level of the latest command (exit with error when appropriate)
|
||||
function c() { if (!$?) { exit(1) } }
|
||||
|
||||
# Add build agent's MinGit to PATH
|
||||
$env:PATH = $env:AGENT_HOMEDIRECTORY +"\externals\\git\cmd;" +$env:PATH
|
||||
|
||||
# Helper to initialize (or update) a Git worktree
|
||||
function init ($path, $url, $set_origin) {
|
||||
if (Test-Path $path) {
|
||||
cd $path; c
|
||||
if (Test-Path .git) {
|
||||
git init; c
|
||||
} else {
|
||||
git status
|
||||
}
|
||||
} else {
|
||||
git init $path; c
|
||||
cd $path; c
|
||||
}
|
||||
git config core.autocrlf false; c
|
||||
git config core.untrackedCache true; c
|
||||
if (($set_origin -ne 0) -and !(git config remote.origin.url)) {
|
||||
git remote add origin $url; c
|
||||
}
|
||||
git fetch --depth=1 $url master; c
|
||||
git reset --hard FETCH_HEAD; c
|
||||
git clean -df; c
|
||||
}
|
||||
|
||||
# Initialize Git for Windows' SDK
|
||||
$sdk_path = "$(Build.SourcesDirectory)\git-sdk-64"
|
||||
init "$sdk_path" "https://dev.azure.com/git-for-windows/git-sdk-64/_git/git-sdk-64" 0
|
||||
init usr\src\build-extra https://github.com/git-for-windows/build-extra 1
|
||||
|
||||
# Let Git ignore the SDK and the test-cache
|
||||
"/git-sdk-64/`n/test-cache/`n" | Out-File -NoNewLine -Encoding ascii -Append "$(Build.SourcesDirectory)\.git\info\exclude"
|
||||
|
||||
# Help MSYS2 runtime startup by initializing /etc/passwd
|
||||
& "$sdk_path\git-cmd" --command=usr\\bin\\bash.exe -lc "mkpasswd -c >>/etc/passwd"; c
|
||||
displayName: 'Initialize the Git for Windows SDK'
|
||||
- powershell: |
|
||||
# Helper to check the error level of the latest command (exit with error when appropriate)
|
||||
function c() { if (!$?) { exit(1) } }
|
||||
|
||||
cd "$(Build.SourcesDirectory)"; c
|
||||
|
||||
git-sdk-64\git-cmd --command=usr\\bin\\bash.exe -lc @"
|
||||
export MAKEFLAGS=-j10
|
||||
export DEVELOPER=1
|
||||
export NO_PERL=1
|
||||
export NO_SVN_TESTS=1
|
||||
export GIT_TEST_SKIP_REBASE_P=1
|
||||
|
||||
ci/run-build-and-tests.sh || {
|
||||
ci/print-test-failures.sh
|
||||
exit 1
|
||||
}
|
||||
"@
|
||||
c
|
||||
displayName: 'Build & Test'
|
||||
env:
|
||||
HOME: $(Build.SourcesDirectory)
|
||||
MSYSTEM: MINGW64
|
||||
- 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: 'windows'
|
||||
platform: Windows
|
||||
publishRunAttachments: false
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- phase: linux32
|
||||
displayName: Linux32
|
||||
condition: succeeded()
|
||||
queue:
|
||||
name: Hosted Ubuntu 1604
|
||||
steps:
|
||||
- bash: |
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
|
||||
|
||||
sudo apt-get update &&
|
||||
sudo rm /var/lib/apt/lists/lock &&
|
||||
sudo apt-get -y install \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
curl \
|
||||
software-properties-common &&
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - &&
|
||||
sudo add-apt-repository \
|
||||
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) \
|
||||
stable" &&
|
||||
sudo apt-get update &&
|
||||
sudo apt-get -y install docker-ce &&
|
||||
|
||||
sudo AGENT_OS="$AGENT_OS" BUILD_BUILDNUMBER="$BUILD_BUILDNUMBER" BUILD_REPOSITORY_URI="$BUILD_REPOSITORY_URI" BUILD_SOURCEBRANCH="$BUILD_SOURCEBRANCH" BUILD_SOURCEVERSION="$BUILD_SOURCEVERSION" SYSTEM_PHASENAME="$SYSTEM_PHASENAME" SYSTEM_TASKDEFINITIONSURI="$SYSTEM_TASKDEFINITIONSURI" SYSTEM_TEAMPROJECT="$SYSTEM_TEAMPROJECT" CC=$CC MAKEFLAGS=-j3 bash -lxc ci/run-linux32-docker.sh || exit 1
|
||||
|
||||
sudo chmod a+r t/out/TEST-*.xml
|
||||
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
|
||||
displayName: 'ci/run-linux32-docker.sh'
|
||||
env:
|
||||
GITFILESHAREPWD: $(gitfileshare.pwd)
|
||||
- task: PublishTestResults@2
|
||||
displayName: 'Publish Test Results **/TEST-*.xml'
|
||||
inputs:
|
||||
mergeTestResults: true
|
||||
testRunTitle: 'linux32'
|
||||
platform: Linux
|
||||
publishRunAttachments: false
|
||||
condition: succeededOrFailed()
|
||||
|
||||
- phase: static_analysis
|
||||
displayName: StaticAnalysis
|
||||
condition: succeeded()
|
||||
queue:
|
||||
name: Hosted Ubuntu 1604
|
||||
steps:
|
||||
- bash: |
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
|
||||
|
||||
sudo apt-get update &&
|
||||
sudo rm /var/lib/apt/lists/lock &&
|
||||
sudo apt-get install -y coccinelle &&
|
||||
|
||||
export jobname=StaticAnalysis &&
|
||||
|
||||
ci/run-static-analysis.sh || exit 1
|
||||
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
|
||||
displayName: 'ci/run-static-analysis.sh'
|
||||
env:
|
||||
GITFILESHAREPWD: $(gitfileshare.pwd)
|
||||
|
||||
- phase: documentation
|
||||
displayName: Documentation
|
||||
condition: succeeded()
|
||||
queue:
|
||||
name: Hosted Ubuntu 1604
|
||||
steps:
|
||||
- bash: |
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || ci/mount-fileshare.sh //gitfileshare.file.core.windows.net/test-cache gitfileshare "$GITFILESHAREPWD" "$HOME/test-cache" || exit 1
|
||||
|
||||
sudo apt-get update &&
|
||||
sudo rm /var/lib/apt/lists/lock &&
|
||||
sudo apt-get install -y asciidoc xmlto asciidoctor &&
|
||||
|
||||
export ALREADY_HAVE_ASCIIDOCTOR=yes. &&
|
||||
export jobname=Documentation &&
|
||||
|
||||
ci/test-documentation.sh || exit 1
|
||||
|
||||
test "$GITFILESHAREPWD" = '$(gitfileshare.pwd)' || sudo umount "$HOME/test-cache" || exit 1
|
||||
displayName: 'ci/test-documentation.sh'
|
||||
env:
|
||||
GITFILESHAREPWD: $(gitfileshare.pwd)
|
||||
@@ -239,7 +239,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
|
||||
rev.diffopt.output_format = DIFF_FORMAT_PATCH;
|
||||
rev.diffopt.use_color = 0;
|
||||
rev.diffopt.flags.ignore_dirty_submodules = 1;
|
||||
out = open(file, O_CREAT | O_WRONLY, 0666);
|
||||
out = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
|
||||
if (out < 0)
|
||||
die(_("Could not open '%s' for writing."), file);
|
||||
rev.diffopt.file = xfdopen(out, "w");
|
||||
|
||||
@@ -1167,7 +1167,9 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
|
||||
if (!is_local && !complete_refs_before_fetch)
|
||||
transport_fetch_refs(transport, mapped_refs);
|
||||
if (transport_fetch_refs(transport, mapped_refs))
|
||||
die(_("could not fetch refs from %s"),
|
||||
transport->url);
|
||||
|
||||
remote_head = find_ref_by_name(refs, "HEAD");
|
||||
remote_head_points_at =
|
||||
|
||||
@@ -874,9 +874,20 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_reset(const char *name, struct object *object)
|
||||
{
|
||||
int mark = get_object_mark(object);
|
||||
|
||||
if (mark)
|
||||
printf("reset %s\nfrom :%d\n\n", name,
|
||||
get_object_mark(object));
|
||||
else
|
||||
printf("reset %s\nfrom %s\n\n", name,
|
||||
oid_to_hex(&object->oid));
|
||||
}
|
||||
|
||||
static void handle_tags_and_duplicates(void)
|
||||
{
|
||||
struct commit *commit;
|
||||
int i;
|
||||
|
||||
for (i = extra_refs.nr - 1; i >= 0; i--) {
|
||||
@@ -890,9 +901,7 @@ static void handle_tags_and_duplicates(void)
|
||||
if (anonymize)
|
||||
name = anonymize_refname(name);
|
||||
/* create refs pointing to already seen commits */
|
||||
commit = (struct commit *)object;
|
||||
printf("reset %s\nfrom :%d\n\n", name,
|
||||
get_object_mark(&commit->object));
|
||||
handle_reset(name, object);
|
||||
show_progress();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -659,8 +659,10 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
|
||||
|
||||
report_garbage = report_pack_garbage;
|
||||
reprepare_packed_git(the_repository);
|
||||
if (pack_garbage.nr > 0)
|
||||
if (pack_garbage.nr > 0) {
|
||||
close_all_packs(the_repository->objects);
|
||||
clean_pack_garbage();
|
||||
}
|
||||
|
||||
if (gc_write_commit_graph)
|
||||
write_commit_graph_reachable(get_object_directory(), 0,
|
||||
|
||||
@@ -155,6 +155,9 @@ static int git_init_db_config(const char *k, const char *v, void *cb)
|
||||
if (!strcmp(k, "init.templatedir"))
|
||||
return git_config_pathname(&init_db_template_dir, k, v);
|
||||
|
||||
if (starts_with(k, "core."))
|
||||
return platform_core_config(k, v, cb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -361,6 +364,9 @@ int init_db(const char *git_dir, const char *real_git_dir,
|
||||
}
|
||||
startup_info->have_repository = 1;
|
||||
|
||||
/* Just look for `init.templatedir` and `core.hidedotfiles` */
|
||||
git_config(git_init_db_config, NULL);
|
||||
|
||||
safe_create_dir(git_dir, 0);
|
||||
|
||||
init_is_bare_repository = is_bare_repository();
|
||||
|
||||
@@ -419,6 +419,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
|
||||
if (!names.nr && !po_args.quiet)
|
||||
printf("Nothing new to pack.\n");
|
||||
|
||||
close_all_packs(the_repository->objects);
|
||||
|
||||
/*
|
||||
* Ok we have prepared all new packfiles.
|
||||
* First see if there are packs of the same name and if so
|
||||
|
||||
@@ -24,12 +24,15 @@
|
||||
#include "cache-tree.h"
|
||||
#include "submodule.h"
|
||||
#include "submodule-config.h"
|
||||
#include "strbuf.h"
|
||||
#include "quote.h"
|
||||
|
||||
#define REFRESH_INDEX_DELAY_WARNING_IN_MS (2 * 1000)
|
||||
|
||||
static const char * const git_reset_usage[] = {
|
||||
N_("git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"),
|
||||
N_("git reset [-q] [<tree-ish>] [--] <paths>..."),
|
||||
N_("EXPERIMENTAL: git reset [-q] [--stdin [-z]] [<tree-ish>]"),
|
||||
N_("git reset --patch [<tree-ish>] [--] [<paths>...]"),
|
||||
NULL
|
||||
};
|
||||
@@ -283,7 +286,9 @@ static int git_reset_config(const char *var, const char *value, void *cb)
|
||||
int cmd_reset(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int reset_type = NONE, update_ref_status = 0, quiet = 0;
|
||||
int patch_mode = 0, unborn;
|
||||
int patch_mode = 0, nul_term_line = 0, read_from_stdin = 0, unborn;
|
||||
char **stdin_paths = NULL;
|
||||
int stdin_nr = 0, stdin_alloc = 0;
|
||||
const char *rev;
|
||||
struct object_id oid;
|
||||
struct pathspec pathspec;
|
||||
@@ -305,6 +310,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
||||
OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")),
|
||||
OPT_BOOL('N', "intent-to-add", &intent_to_add,
|
||||
N_("record only the fact that removed paths will be added later")),
|
||||
OPT_BOOL('z', NULL, &nul_term_line,
|
||||
N_("EXPERIMENTAL: paths are separated with NUL character")),
|
||||
OPT_BOOL(0, "stdin", &read_from_stdin,
|
||||
N_("EXPERIMENTAL: read paths from <stdin>")),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
@@ -315,6 +324,42 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
||||
PARSE_OPT_KEEP_DASHDASH);
|
||||
parse_args(&pathspec, argv, prefix, patch_mode, &rev);
|
||||
|
||||
if (read_from_stdin) {
|
||||
strbuf_getline_fn getline_fn = nul_term_line ?
|
||||
strbuf_getline_nul : strbuf_getline_lf;
|
||||
int flags = PATHSPEC_PREFER_FULL;
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
struct strbuf unquoted = STRBUF_INIT;
|
||||
|
||||
if (patch_mode)
|
||||
die(_("--stdin is incompatible with --patch"));
|
||||
|
||||
if (pathspec.nr)
|
||||
die(_("--stdin is incompatible with path arguments"));
|
||||
|
||||
while (getline_fn(&buf, stdin) != EOF) {
|
||||
if (!nul_term_line && buf.buf[0] == '"') {
|
||||
strbuf_reset(&unquoted);
|
||||
if (unquote_c_style(&unquoted, buf.buf, NULL))
|
||||
die(_("line is badly quoted"));
|
||||
strbuf_swap(&buf, &unquoted);
|
||||
}
|
||||
ALLOC_GROW(stdin_paths, stdin_nr + 1, stdin_alloc);
|
||||
stdin_paths[stdin_nr++] = xstrdup(buf.buf);
|
||||
strbuf_reset(&buf);
|
||||
}
|
||||
strbuf_release(&unquoted);
|
||||
strbuf_release(&buf);
|
||||
|
||||
ALLOC_GROW(stdin_paths, stdin_nr + 1, stdin_alloc);
|
||||
stdin_paths[stdin_nr++] = NULL;
|
||||
flags |= PATHSPEC_LITERAL_PATH;
|
||||
parse_pathspec(&pathspec, 0, flags, prefix,
|
||||
(const char **)stdin_paths);
|
||||
|
||||
} else if (nul_term_line)
|
||||
die(_("-z requires --stdin"));
|
||||
|
||||
unborn = !strcmp(rev, "HEAD") && get_oid("HEAD", &oid);
|
||||
if (unborn) {
|
||||
/* reset on unborn branch: treat as reset to empty tree */
|
||||
@@ -415,5 +460,11 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
|
||||
if (!pathspec.nr)
|
||||
remove_branch_state();
|
||||
|
||||
if (stdin_paths) {
|
||||
while (stdin_nr)
|
||||
free(stdin_paths[--stdin_nr]);
|
||||
free(stdin_paths);
|
||||
}
|
||||
|
||||
return update_ref_status;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Install dependencies required to build and test Git on Linux and macOS
|
||||
#
|
||||
|
||||
. ${0%/*}/lib-travisci.sh
|
||||
. ${0%/*}/lib.sh
|
||||
|
||||
P4WHENCE=http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION
|
||||
LFSWHENCE=https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION
|
||||
@@ -37,7 +37,8 @@ osx-clang|osx-gcc)
|
||||
brew update --quiet
|
||||
# Uncomment this if you want to run perf tests:
|
||||
# brew install gnu-time
|
||||
brew install git-lfs gettext
|
||||
test -z "$BREW_INSTALL_PACKAGES" ||
|
||||
brew install $BREW_INSTALL_PACKAGES
|
||||
brew link --force gettext
|
||||
brew install caskroom/cask/perforce
|
||||
;;
|
||||
|
||||
@@ -1,5 +1,51 @@
|
||||
# Library of functions shared by all CI scripts
|
||||
|
||||
if test true = "$TRAVIS"
|
||||
then
|
||||
# We are running within Travis CI
|
||||
CI_BRANCH="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}"
|
||||
CI_COMMIT="$TRAVIS_COMMIT"
|
||||
CI_JOB_ID="$TRAVIS_JOB_ID"
|
||||
CI_JOB_NUMBER="$TRAVIS_JOB_NUMBER"
|
||||
CI_OS_NAME="$TRAVIS_OS_NAME"
|
||||
CI_REPO_SLUG="$TRAVIS_REPO_SLUG"
|
||||
|
||||
cache_dir="$HOME/travis-cache"
|
||||
|
||||
url_for_job_id () {
|
||||
echo "https://travis-ci.org/$CI_REPO_SLUG/jobs/$1"
|
||||
}
|
||||
|
||||
BREW_INSTALL_PACKAGES="git-lfs gettext"
|
||||
export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save"
|
||||
export GIT_TEST_OPTS="--verbose-log -x --immediate"
|
||||
elif test -n "$SYSTEM_TASKDEFINITIONSURI"
|
||||
then
|
||||
# We are running in Azure Pipelines
|
||||
CI_BRANCH="$BUILD_SOURCEBRANCH"
|
||||
CI_COMMIT="$BUILD_SOURCEVERSION"
|
||||
CI_JOB_ID="$BUILD_BUILDID"
|
||||
CI_JOB_NUMBER="$BUILD_BUILDNUMBER"
|
||||
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" : '.*/\([^/]*/[^/]*\)$')"
|
||||
CC="${CC:-gcc}"
|
||||
|
||||
# use a subdirectory of the cache dir (because the file share is shared
|
||||
# among *all* phases)
|
||||
cache_dir="$HOME/test-cache/$SYSTEM_PHASENAME"
|
||||
|
||||
url_for_job_id () {
|
||||
echo "$SYSTEM_TASKDEFINITIONSURI$SYSTEM_TEAMPROJECT/_build/results?buildId=$1"
|
||||
}
|
||||
|
||||
BREW_INSTALL_PACKAGES=
|
||||
export GIT_PROVE_OPTS="--timer --jobs 10 --state=failed,slow,save"
|
||||
export GIT_TEST_OPTS="--verbose-log -x --write-junit-xml"
|
||||
test windows_nt != "$CI_OS_NAME" ||
|
||||
GIT_TEST_OPTS="--no-chain-lint --no-bin-wrappers $GIT_TEST_OPTS"
|
||||
fi
|
||||
|
||||
skip_branch_tip_with_tag () {
|
||||
# Sometimes, a branch is pushed at the same time the tag that points
|
||||
# at the same commit as the tip of the branch is pushed, and building
|
||||
@@ -13,10 +59,10 @@ skip_branch_tip_with_tag () {
|
||||
# we can skip the build because we won't be skipping a build
|
||||
# of a tag.
|
||||
|
||||
if TAG=$(git describe --exact-match "$TRAVIS_BRANCH" 2>/dev/null) &&
|
||||
test "$TAG" != "$TRAVIS_BRANCH"
|
||||
if TAG=$(git describe --exact-match "$CI_BRANCH" 2>/dev/null) &&
|
||||
test "$TAG" != "$CI_BRANCH"
|
||||
then
|
||||
echo "$(tput setaf 2)Tip of $TRAVIS_BRANCH is exactly at $TAG$(tput sgr0)"
|
||||
echo "$(tput setaf 2)Tip of $CI_BRANCH is exactly at $TAG$(tput sgr0)"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
@@ -25,7 +71,7 @@ skip_branch_tip_with_tag () {
|
||||
# job if we encounter the same tree again and can provide a useful info
|
||||
# message.
|
||||
save_good_tree () {
|
||||
echo "$(git rev-parse $TRAVIS_COMMIT^{tree}) $TRAVIS_COMMIT $TRAVIS_JOB_NUMBER $TRAVIS_JOB_ID" >>"$good_trees_file"
|
||||
echo "$(git rev-parse $CI_COMMIT^{tree}) $CI_COMMIT $CI_JOB_NUMBER $CI_JOB_ID" >>"$good_trees_file"
|
||||
# limit the file size
|
||||
tail -1000 "$good_trees_file" >"$good_trees_file".tmp
|
||||
mv "$good_trees_file".tmp "$good_trees_file"
|
||||
@@ -35,7 +81,7 @@ save_good_tree () {
|
||||
# successfully before (e.g. because the branch got rebased, changing only
|
||||
# the commit messages).
|
||||
skip_good_tree () {
|
||||
if ! good_tree_info="$(grep "^$(git rev-parse $TRAVIS_COMMIT^{tree}) " "$good_trees_file")"
|
||||
if ! good_tree_info="$(grep "^$(git rev-parse $CI_COMMIT^{tree}) " "$good_trees_file")"
|
||||
then
|
||||
# Haven't seen this tree yet, or no cached good trees file yet.
|
||||
# Continue the build job.
|
||||
@@ -45,18 +91,18 @@ skip_good_tree () {
|
||||
echo "$good_tree_info" | {
|
||||
read tree prev_good_commit prev_good_job_number prev_good_job_id
|
||||
|
||||
if test "$TRAVIS_JOB_ID" = "$prev_good_job_id"
|
||||
if test "$CI_JOB_ID" = "$prev_good_job_id"
|
||||
then
|
||||
cat <<-EOF
|
||||
$(tput setaf 2)Skipping build job for commit $TRAVIS_COMMIT.$(tput sgr0)
|
||||
$(tput setaf 2)Skipping build job for commit $CI_COMMIT.$(tput sgr0)
|
||||
This commit has already been built and tested successfully by this build job.
|
||||
To force a re-build delete the branch's cache and then hit 'Restart job'.
|
||||
EOF
|
||||
else
|
||||
cat <<-EOF
|
||||
$(tput setaf 2)Skipping build job for commit $TRAVIS_COMMIT.$(tput sgr0)
|
||||
$(tput setaf 2)Skipping build job for commit $CI_COMMIT.$(tput sgr0)
|
||||
This commit's tree has already been built and tested successfully in build job $prev_good_job_number for commit $prev_good_commit.
|
||||
The log of that build job is available at https://travis-ci.org/$TRAVIS_REPO_SLUG/jobs/$prev_good_job_id
|
||||
The log of that build job is available at $(url_for_job_id $prev_good_job_id)
|
||||
To force a re-build delete the branch's cache and then hit 'Restart job'.
|
||||
EOF
|
||||
fi
|
||||
@@ -81,7 +127,6 @@ check_unignored_build_artifacts ()
|
||||
# and installing dependencies.
|
||||
set -ex
|
||||
|
||||
cache_dir="$HOME/travis-cache"
|
||||
good_trees_file="$cache_dir/good-trees"
|
||||
|
||||
mkdir -p "$cache_dir"
|
||||
@@ -91,13 +136,11 @@ skip_good_tree
|
||||
|
||||
if test -z "$jobname"
|
||||
then
|
||||
jobname="$TRAVIS_OS_NAME-$CC"
|
||||
jobname="$CI_OS_NAME-$CC"
|
||||
fi
|
||||
|
||||
export DEVELOPER=1
|
||||
export DEFAULT_TEST_TARGET=prove
|
||||
export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save"
|
||||
export GIT_TEST_OPTS="--verbose-log -x --immediate"
|
||||
export GIT_TEST_CLONE_2GB=YesPlease
|
||||
if [ "$jobname" = linux-gcc ]; then
|
||||
export CC=gcc-8
|
||||
26
ci/mount-fileshare.sh
Executable file
26
ci/mount-fileshare.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
die () {
|
||||
echo "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
test $# = 4 ||
|
||||
die "Usage: $0 <share> <username> <password> <mountpoint"
|
||||
|
||||
mkdir -p "$4" || die "Could not create $4"
|
||||
|
||||
case "$(uname -s)" in
|
||||
Linux)
|
||||
sudo mount -t cifs -o vers=3.0,username="$2",password="$3",dir_mode=0777,file_mode=0777,serverino "$1" "$4"
|
||||
;;
|
||||
Darwin)
|
||||
pass="$(echo "$3" | sed -e 's/\//%2F/g' -e 's/+/%2B/g')" &&
|
||||
mount -t smbfs,soft "smb://$2:$pass@${1#//}" "$4"
|
||||
;;
|
||||
*)
|
||||
die "No support for $(uname -s)"
|
||||
;;
|
||||
esac ||
|
||||
die "Could not mount $4"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Print output of failing tests
|
||||
#
|
||||
|
||||
. ${0%/*}/lib-travisci.sh
|
||||
. ${0%/*}/lib.sh
|
||||
|
||||
# Tracing executed commands would produce too much noise in the loop below.
|
||||
set +x
|
||||
@@ -69,7 +69,7 @@ do
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $combined_trash_size -gt 0 ]
|
||||
if [ -n "$TRAVIS_JOB_ID" -a $combined_trash_size -gt 0 ]
|
||||
then
|
||||
echo "------------------------------------------------------------------------"
|
||||
echo "Trash directories embedded in this log can be extracted by running:"
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
# Build and test Git
|
||||
#
|
||||
|
||||
. ${0%/*}/lib-travisci.sh
|
||||
. ${0%/*}/lib.sh
|
||||
|
||||
ln -s "$cache_dir/.prove" t/.prove
|
||||
case "$CI_OS_NAME" in
|
||||
windows*) cmd //c mklink //j t\\.prove "$(cygpath -aw "$cache_dir/.prove")";;
|
||||
*) ln -s "$cache_dir/.prove" t/.prove;;
|
||||
esac
|
||||
|
||||
make --jobs=2
|
||||
make
|
||||
make --quiet test
|
||||
if test "$jobname" = "linux-gcc"
|
||||
then
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Download and run Docker image to build and test 32-bit Git
|
||||
#
|
||||
|
||||
. ${0%/*}/lib-travisci.sh
|
||||
. ${0%/*}/lib.sh
|
||||
|
||||
docker pull daald/ubuntu32:xenial
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Perform various static code analysis checks
|
||||
#
|
||||
|
||||
. ${0%/*}/lib-travisci.sh
|
||||
. ${0%/*}/lib.sh
|
||||
|
||||
make --jobs=2 coccicheck
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# supported) and a commit hash.
|
||||
#
|
||||
|
||||
. ${0%/*}/lib-travisci.sh
|
||||
. ${0%/*}/lib.sh
|
||||
|
||||
test $# -ne 2 && echo "Unexpected number of parameters" && exit 1
|
||||
test -z "$GFW_CI_TOKEN" && echo "GFW_CI_TOKEN not defined" && exit
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
# Perform sanity checks on documentation and build it.
|
||||
#
|
||||
|
||||
. ${0%/*}/lib-travisci.sh
|
||||
. ${0%/*}/lib.sh
|
||||
|
||||
test -n "$ALREADY_HAVE_ASCIIDOCTOR" ||
|
||||
gem install asciidoctor
|
||||
|
||||
make check-builtins
|
||||
|
||||
@@ -928,11 +928,19 @@ unsigned int sleep (unsigned int seconds)
|
||||
char *mingw_mktemp(char *template)
|
||||
{
|
||||
wchar_t wtemplate[MAX_PATH];
|
||||
int offset = 0;
|
||||
|
||||
if (xutftowcs_path(wtemplate, template) < 0)
|
||||
return NULL;
|
||||
|
||||
if (is_dir_sep(template[0]) && !is_dir_sep(template[1]) &&
|
||||
iswalpha(wtemplate[0]) && wtemplate[1] == L':') {
|
||||
/* We have an absolute path missing the drive prefix */
|
||||
offset = 2;
|
||||
}
|
||||
if (!_wmktemp(wtemplate))
|
||||
return NULL;
|
||||
if (xwcstoutf(template, wtemplate, strlen(template) + 1) < 0)
|
||||
if (xwcstoutf(template, wtemplate + offset, strlen(template) + 1) < 0)
|
||||
return NULL;
|
||||
return template;
|
||||
}
|
||||
@@ -1031,7 +1039,7 @@ char *mingw_getcwd(char *pointer, int len)
|
||||
* See "Parsing C++ Command-Line Arguments" at Microsoft's Docs:
|
||||
* https://docs.microsoft.com/en-us/cpp/cpp/parsing-cpp-command-line-arguments
|
||||
*/
|
||||
static const char *quote_arg(const char *arg)
|
||||
static const char *quote_arg_msvc(const char *arg)
|
||||
{
|
||||
/* count chars to quote */
|
||||
int len = 0, n = 0;
|
||||
@@ -1086,6 +1094,37 @@ static const char *quote_arg(const char *arg)
|
||||
return q;
|
||||
}
|
||||
|
||||
#include "quote.h"
|
||||
|
||||
static const char *quote_arg_msys2(const char *arg)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
const char *p2 = arg, *p;
|
||||
|
||||
for (p = arg; *p; p++) {
|
||||
int ws = isspace(*p);
|
||||
if (!ws && *p != '\\' && *p != '"' && *p != '{')
|
||||
continue;
|
||||
if (!buf.len)
|
||||
strbuf_addch(&buf, '"');
|
||||
if (p != p2)
|
||||
strbuf_add(&buf, p2, p - p2);
|
||||
if (!ws && *p != '{')
|
||||
strbuf_addch(&buf, '\\');
|
||||
p2 = p;
|
||||
}
|
||||
|
||||
if (p == arg)
|
||||
strbuf_addch(&buf, '"');
|
||||
else if (!buf.len)
|
||||
return arg;
|
||||
else
|
||||
strbuf_add(&buf, p2, p - p2),
|
||||
|
||||
strbuf_addch(&buf, '"');
|
||||
return strbuf_detach(&buf, 0);
|
||||
}
|
||||
|
||||
static const char *parse_interpreter(const char *cmd)
|
||||
{
|
||||
static char buf[100];
|
||||
@@ -1129,14 +1168,21 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
|
||||
int isexe, int exe_only)
|
||||
{
|
||||
char path[MAX_PATH];
|
||||
wchar_t wpath[MAX_PATH];
|
||||
snprintf(path, sizeof(path), "%.*s\\%s.exe", dirlen, dir, cmd);
|
||||
|
||||
if (!isexe && access(path, F_OK) == 0)
|
||||
if (xutftowcs_path(wpath, path) < 0)
|
||||
return NULL;
|
||||
|
||||
if (!isexe && _waccess(wpath, F_OK) == 0)
|
||||
return xstrdup(path);
|
||||
path[strlen(path)-4] = '\0';
|
||||
if ((!exe_only || isexe) && access(path, F_OK) == 0)
|
||||
if (!(GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY))
|
||||
wpath[wcslen(wpath)-4] = '\0';
|
||||
if ((!exe_only || isexe) && _waccess(wpath, F_OK) == 0) {
|
||||
if (!(GetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
path[strlen(path)-4] = '\0';
|
||||
return xstrdup(path);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1317,6 +1363,34 @@ struct pinfo_t {
|
||||
static struct pinfo_t *pinfo = NULL;
|
||||
CRITICAL_SECTION pinfo_cs;
|
||||
|
||||
static int is_msys2_sh(const char *cmd)
|
||||
{
|
||||
if (cmd && !strcmp(cmd, "sh")) {
|
||||
static int ret = -1;
|
||||
char *p;
|
||||
|
||||
if (ret >= 0)
|
||||
return ret;
|
||||
|
||||
p = path_lookup(cmd, 0);
|
||||
if (!p)
|
||||
ret = 0;
|
||||
else {
|
||||
size_t len = strlen(p);
|
||||
ret = len > 15 &&
|
||||
is_dir_sep(p[len - 15]) &&
|
||||
!strncasecmp(p + len - 14, "usr", 3) &&
|
||||
is_dir_sep(p[len - 11]) &&
|
||||
!strncasecmp(p + len - 10, "bin", 3) &&
|
||||
is_dir_sep(p[len - 7]) &&
|
||||
!strcasecmp(p + len - 6, "sh.exe");
|
||||
free(p);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaenv,
|
||||
const char *dir,
|
||||
int prepend_cmd, int fhin, int fhout, int fherr)
|
||||
@@ -1328,6 +1402,8 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen
|
||||
unsigned flags = CREATE_UNICODE_ENVIRONMENT;
|
||||
BOOL ret;
|
||||
HANDLE cons;
|
||||
const char *(*quote_arg)(const char *arg) =
|
||||
is_msys2_sh(*argv) ? quote_arg_msys2 : quote_arg_msvc;
|
||||
|
||||
do_unset_environment_variables();
|
||||
|
||||
|
||||
@@ -269,6 +269,20 @@ win32_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
|
||||
return happened;
|
||||
}
|
||||
|
||||
#include <windows.h>
|
||||
#include "compat/win32/lazyload.h"
|
||||
|
||||
static ULONGLONG CompatGetTickCount64(void)
|
||||
{
|
||||
DECLARE_PROC_ADDR(kernel32.dll, ULONGLONG, GetTickCount64, void);
|
||||
|
||||
if (!INIT_PROC_ADDR(GetTickCount64))
|
||||
return (ULONGLONG)GetTickCount();
|
||||
|
||||
return GetTickCount64();
|
||||
}
|
||||
#define GetTickCount64 CompatGetTickCount64
|
||||
|
||||
#else /* !MinGW */
|
||||
|
||||
/* Convert select(2) returned fd_sets into poll(2) revents values. */
|
||||
|
||||
@@ -551,11 +551,19 @@ else
|
||||
ifeq ($(shell expr "$(uname_R)" : '2\.'),2)
|
||||
# MSys2
|
||||
prefix = /usr/
|
||||
# Enable DEP
|
||||
BASIC_LDFLAGS += -Wl,--nxcompat
|
||||
# Enable ASLR (unless debugging)
|
||||
ifneq (,$(findstring -O,$(CFLAGS)))
|
||||
BASIC_LDFLAGS += -Wl,--dynamicbase
|
||||
endif
|
||||
ifeq (MINGW32,$(MSYSTEM))
|
||||
prefix = /mingw32
|
||||
BASIC_LDFLAGS += -Wl,--pic-executable,-e,_mainCRTStartup
|
||||
endif
|
||||
ifeq (MINGW64,$(MSYSTEM))
|
||||
prefix = /mingw64
|
||||
BASIC_LDFLAGS += -Wl,--pic-executable,-e,mainCRTStartup
|
||||
else
|
||||
COMPAT_CFLAGS += -D_USE_32BIT_TIME_T
|
||||
BASIC_LDFLAGS += -Wl,--large-address-aware
|
||||
|
||||
@@ -918,6 +918,10 @@ static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
|
||||
|
||||
if (protocol == PROTO_LOCAL)
|
||||
path = end;
|
||||
else if (protocol == PROTO_FILE && *host != '/' &&
|
||||
!has_dos_drive_prefix(host) &&
|
||||
offset_1st_component(host - 2) > 1)
|
||||
path = host - 2; /* include the leading "//" */
|
||||
else if (protocol == PROTO_FILE && has_dos_drive_prefix(end))
|
||||
path = end; /* "file://$(pwd)" may be "file://C:/projects/repo" */
|
||||
else
|
||||
|
||||
@@ -136,7 +136,9 @@ static void credential_getpass(struct credential *c)
|
||||
{
|
||||
if (!c->username)
|
||||
c->username = credential_ask_one("Username", c,
|
||||
PROMPT_ASKPASS|PROMPT_ECHO);
|
||||
(getenv("GIT_ASKPASS") ?
|
||||
PROMPT_ASKPASS : 0) |
|
||||
PROMPT_ECHO);
|
||||
if (!c->password)
|
||||
c->password = credential_ask_one("Password", c,
|
||||
PROMPT_ASKPASS);
|
||||
|
||||
@@ -82,6 +82,18 @@ static struct diff_rename_src *register_rename_src(struct diff_filepair *p)
|
||||
|
||||
first = 0;
|
||||
last = rename_src_nr;
|
||||
|
||||
if (last > 0) {
|
||||
struct diff_rename_src *src = &(rename_src[last-1]);
|
||||
int cmp = strcmp(one->path, src->p->one->path);
|
||||
if (!cmp)
|
||||
return src;
|
||||
if (cmp > 0) {
|
||||
first = last;
|
||||
goto append_it;
|
||||
}
|
||||
}
|
||||
|
||||
while (last > first) {
|
||||
int next = (last + first) >> 1;
|
||||
struct diff_rename_src *src = &(rename_src[next]);
|
||||
@@ -95,6 +107,7 @@ static struct diff_rename_src *register_rename_src(struct diff_filepair *p)
|
||||
first = next+1;
|
||||
}
|
||||
|
||||
append_it:
|
||||
/* insert to make it at "first" */
|
||||
ALLOC_GROW(rename_src, rename_src_nr + 1, rename_src_alloc);
|
||||
rename_src_nr++;
|
||||
|
||||
@@ -431,6 +431,7 @@ END
|
||||
sub safe_pipe_capture {
|
||||
my @output;
|
||||
if (my $pid = open my $child, '-|') {
|
||||
binmode($child, ":crlf");
|
||||
@output = (<$child>);
|
||||
close $child or die join(' ',@_).": $! $?";
|
||||
} else {
|
||||
|
||||
5
path.c
5
path.c
@@ -11,6 +11,7 @@
|
||||
#include "path.h"
|
||||
#include "packfile.h"
|
||||
#include "object-store.h"
|
||||
#include "exec-cmd.h"
|
||||
|
||||
static int get_st_mode_bits(const char *path, int *mode)
|
||||
{
|
||||
@@ -711,6 +712,10 @@ char *expand_user_path(const char *path, int real_home)
|
||||
|
||||
if (path == NULL)
|
||||
goto return_null;
|
||||
#ifdef __MINGW32__
|
||||
if (path[0] == '/')
|
||||
return system_path(path + 1);
|
||||
#endif
|
||||
if (path[0] == '~') {
|
||||
const char *first_slash = strchrnul(path, '/');
|
||||
const char *username = path + 1;
|
||||
|
||||
14
send-pack.c
14
send-pack.c
@@ -38,6 +38,16 @@ int option_parse_push_signed(const struct option *opt,
|
||||
die("bad %s argument: %s", opt->long_name, arg);
|
||||
}
|
||||
|
||||
static int config_use_sideband = 1;
|
||||
|
||||
static int send_pack_config(const char *var, const char *value, void *unused)
|
||||
{
|
||||
if (!strcmp("sendpack.sideband", var))
|
||||
config_use_sideband = git_config_bool(var, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void feed_object(const struct object_id *oid, FILE *fh, int negative)
|
||||
{
|
||||
if (negative && !has_sha1_file(oid->hash))
|
||||
@@ -391,6 +401,8 @@ int send_pack(struct send_pack_args *args,
|
||||
struct async demux;
|
||||
const char *push_cert_nonce = NULL;
|
||||
|
||||
git_config(send_pack_config, NULL);
|
||||
|
||||
/* Does the other end support the reporting? */
|
||||
if (server_supports("report-status"))
|
||||
status_report = 1;
|
||||
@@ -398,7 +410,7 @@ int send_pack(struct send_pack_args *args,
|
||||
allow_deleting_refs = 1;
|
||||
if (server_supports("ofs-delta"))
|
||||
args->use_ofs_delta = 1;
|
||||
if (server_supports("side-band-64k"))
|
||||
if (config_use_sideband && server_supports("side-band-64k"))
|
||||
use_sideband = 1;
|
||||
if (server_supports("quiet"))
|
||||
quiet_supported = 1;
|
||||
|
||||
16
setup.c
16
setup.c
@@ -39,7 +39,7 @@ static int abspath_part_inside_repo(char *path)
|
||||
off = offset_1st_component(path);
|
||||
|
||||
/* check if work tree is already the prefix */
|
||||
if (wtlen <= len && !strncmp(path, work_tree, wtlen)) {
|
||||
if (wtlen <= len && !fspathncmp(path, work_tree, wtlen)) {
|
||||
if (path[wtlen] == '/') {
|
||||
memmove(path, path + wtlen + 1, len - wtlen);
|
||||
return 0;
|
||||
@@ -59,7 +59,7 @@ static int abspath_part_inside_repo(char *path)
|
||||
path++;
|
||||
if (*path == '/') {
|
||||
*path = '\0';
|
||||
if (strcmp(real_path(path0), work_tree) == 0) {
|
||||
if (fspathcmp(real_path(path0), work_tree) == 0) {
|
||||
memmove(path0, path + 1, len - (path - path0));
|
||||
return 0;
|
||||
}
|
||||
@@ -68,7 +68,7 @@ static int abspath_part_inside_repo(char *path)
|
||||
}
|
||||
|
||||
/* check whole path */
|
||||
if (strcmp(real_path(path0), work_tree) == 0) {
|
||||
if (fspathcmp(real_path(path0), work_tree) == 0) {
|
||||
*path0 = '\0';
|
||||
return 0;
|
||||
}
|
||||
@@ -784,7 +784,7 @@ static const char *setup_discovered_git_dir(const char *gitdir,
|
||||
set_git_dir(gitdir);
|
||||
inside_git_dir = 0;
|
||||
inside_work_tree = 1;
|
||||
if (offset == cwd->len)
|
||||
if (offset >= cwd->len)
|
||||
return NULL;
|
||||
|
||||
/* Make "offset" point past the '/' (already the case for root dirs) */
|
||||
@@ -916,7 +916,7 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
|
||||
const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
|
||||
struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
|
||||
const char *gitdirenv;
|
||||
int ceil_offset = -1, min_offset = has_dos_drive_prefix(dir->buf) ? 3 : 1;
|
||||
int ceil_offset = -1, min_offset = offset_1st_component(dir->buf);
|
||||
dev_t current_device = 0;
|
||||
int one_filesystem = 1;
|
||||
|
||||
@@ -944,6 +944,12 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
|
||||
if (ceil_offset < 0)
|
||||
ceil_offset = min_offset - 2;
|
||||
|
||||
if (min_offset && min_offset == dir->len &&
|
||||
!is_dir_sep(dir->buf[min_offset - 1])) {
|
||||
strbuf_addch(dir, '/');
|
||||
min_offset++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test in the following order (relative to the dir):
|
||||
* - .git (file containing "gitdir: <path>")
|
||||
|
||||
1
t/.gitignore
vendored
1
t/.gitignore
vendored
@@ -2,3 +2,4 @@
|
||||
/test-results
|
||||
/.prove
|
||||
/chainlinttmp
|
||||
/out/
|
||||
|
||||
9
t/README
9
t/README
@@ -170,6 +170,15 @@ appropriately before running "make".
|
||||
implied by other options like --valgrind and
|
||||
GIT_TEST_INSTALLED.
|
||||
|
||||
--no-bin-wrappers::
|
||||
By default, the test suite uses the wrappers in
|
||||
`../bin-wrappers/` to execute `git` and friends. With this option,
|
||||
`../git` and friends are run directly. This is not recommended
|
||||
in general, as the wrappers contain safeguards to ensure that no
|
||||
files from an installed Git are used, but can speed up test runs
|
||||
especially on platforms where running shell scripts is expensive
|
||||
(most notably, Windows).
|
||||
|
||||
--root=<directory>::
|
||||
Create "trash" directories used to store all temporary data during
|
||||
testing under <directory>, instead of the t/ directory.
|
||||
|
||||
@@ -7,6 +7,7 @@ static const char *usage_msg = "\n"
|
||||
" test-tool date parse [date]...\n"
|
||||
" test-tool date approxidate [date]...\n"
|
||||
" test-tool date timestamp [date]...\n"
|
||||
" test-tool date getnanos [start-nanos]\n"
|
||||
" test-tool date is64bit\n"
|
||||
" test-tool date time_t-is64bit\n";
|
||||
|
||||
@@ -82,6 +83,15 @@ static void parse_approx_timestamp(const char **argv, struct timeval *now)
|
||||
}
|
||||
}
|
||||
|
||||
static void getnanos(const char **argv, struct timeval *now)
|
||||
{
|
||||
double seconds = getnanotime() / 1.0e9;
|
||||
|
||||
if (*argv)
|
||||
seconds -= strtod(*argv, NULL);
|
||||
printf("%lf\n", seconds);
|
||||
}
|
||||
|
||||
int cmd__date(int argc, const char **argv)
|
||||
{
|
||||
struct timeval now;
|
||||
@@ -108,6 +118,8 @@ int cmd__date(int argc, const char **argv)
|
||||
parse_approxidate(argv+1, &now);
|
||||
else if (!strcmp(*argv, "timestamp"))
|
||||
parse_approx_timestamp(argv+1, &now);
|
||||
else if (!strcmp(*argv, "getnanos"))
|
||||
getnanos(argv+1, &now);
|
||||
else if (!strcmp(*argv, "is64bit"))
|
||||
return sizeof(timestamp_t) == 8 ? 0 : 1;
|
||||
else if (!strcmp(*argv, "time_t-is64bit"))
|
||||
|
||||
@@ -453,6 +453,18 @@ test_expect_success 're-init from a linked worktree' '
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success MINGW 'core.hidedotfiles = false' '
|
||||
git config --global core.hidedotfiles false &&
|
||||
rm -rf newdir &&
|
||||
(
|
||||
sane_unset GIT_DIR GIT_WORK_TREE GIT_CONFIG &&
|
||||
mkdir newdir &&
|
||||
cd newdir &&
|
||||
git init
|
||||
) &&
|
||||
! is_hidden newdir/.git
|
||||
'
|
||||
|
||||
test_expect_success MINGW 'redirect std handles' '
|
||||
GIT_REDIRECT_STDOUT=output.txt git rev-parse --git-dir &&
|
||||
test .git = "$(cat output.txt)" &&
|
||||
|
||||
@@ -158,7 +158,8 @@ test_trace () {
|
||||
expect="$1"
|
||||
shift
|
||||
GIT_TRACE=1 test-tool run-command "$@" run-command true 2>&1 >/dev/null | \
|
||||
sed -e 's/.* run_command: //' -e '/trace: .*/d' >actual &&
|
||||
sed -e 's/.* run_command: //' -e '/trace: .*/d' \
|
||||
-e '/RUNTIME_PREFIX requested/d' >actual &&
|
||||
echo "$expect true" >expect &&
|
||||
test_cmp expect actual
|
||||
}
|
||||
@@ -191,4 +192,14 @@ test_expect_success 'GIT_TRACE with environment variables' '
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success MINGW 'verify curlies are quoted properly' '
|
||||
: force the rev-parse through the MSYS2 Bash &&
|
||||
git -c alias.r="!git rev-parse" r -- a{b}c >actual &&
|
||||
cat >expect <<-\EOF &&
|
||||
--
|
||||
a{b}c
|
||||
EOF
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -402,4 +402,11 @@ test_expect_success 'all statuses changed in folder if . is given' '
|
||||
test $(git ls-files --stage | grep ^100755 | wc -l) -eq 0
|
||||
'
|
||||
|
||||
test_expect_success MINGW 'path is case-insensitive' '
|
||||
path="$(pwd)/BLUB" &&
|
||||
touch "$path" &&
|
||||
downcased="$(echo "$path" | tr A-Z a-z)" &&
|
||||
git add "$downcased"
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -698,13 +698,22 @@ do
|
||||
# file with scheme
|
||||
for p in file
|
||||
do
|
||||
test_expect_success "fetch-pack --diag-url $p://$h/$r" '
|
||||
test_expect_success !MINGW "fetch-pack --diag-url $p://$h/$r" '
|
||||
check_prot_path $p://$h/$r $p "/$r"
|
||||
'
|
||||
test_expect_success MINGW "fetch-pack --diag-url $p://$h/$r" '
|
||||
check_prot_path $p://$h/$r $p "//$h/$r"
|
||||
'
|
||||
test_expect_success MINGW "fetch-pack --diag-url $p:///$r" '
|
||||
check_prot_path $p:///$r $p "/$r"
|
||||
'
|
||||
# No "/~" -> "~" conversion for file
|
||||
test_expect_success "fetch-pack --diag-url $p://$h/~$r" '
|
||||
test_expect_success !MINGW "fetch-pack --diag-url $p://$h/~$r" '
|
||||
check_prot_path $p://$h/~$r $p "/~$r"
|
||||
'
|
||||
test_expect_success MINGW "fetch-pack --diag-url $p://$h/~$r" '
|
||||
check_prot_path $p://$h/~$r $p "//$h/~$r"
|
||||
'
|
||||
done
|
||||
# file without scheme
|
||||
for h in nohost nohost:12 [::1] [::1]:23 [ [:aa
|
||||
|
||||
@@ -17,14 +17,11 @@ fi
|
||||
UNCPATH="$(winpwd)"
|
||||
case "$UNCPATH" in
|
||||
[A-Z]:*)
|
||||
WITHOUTDRIVE="${UNCPATH#?:}"
|
||||
# Use administrative share e.g. \\localhost\C$\git-sdk-64\usr\src\git
|
||||
# (we use forward slashes here because MSYS2 and Git accept them, and
|
||||
# they are easier on the eyes)
|
||||
UNCPATH="//localhost/${UNCPATH%%:*}\$/${UNCPATH#?:}"
|
||||
test -d "$UNCPATH" || {
|
||||
skip_all='could not access administrative share; skipping'
|
||||
test_done
|
||||
}
|
||||
UNCPATH="//localhost/${UNCPATH%%:*}\$$WITHOUTDRIVE"
|
||||
;;
|
||||
*)
|
||||
skip_all='skipping UNC path tests, cannot determine current path as UNC'
|
||||
@@ -32,6 +29,18 @@ case "$UNCPATH" in
|
||||
;;
|
||||
esac
|
||||
|
||||
test_expect_success 'clone into absolute path lacking a drive prefix' '
|
||||
USINGBACKSLASHES="$(echo "$WITHOUTDRIVE"/without-drive-prefix |
|
||||
tr / \\\\)" &&
|
||||
git clone . "$USINGBACKSLASHES" &&
|
||||
test -f without-drive-prefix/.git/HEAD
|
||||
'
|
||||
|
||||
test -d "$UNCPATH" || {
|
||||
skip_all='could not access administrative share; skipping'
|
||||
test_done
|
||||
}
|
||||
|
||||
test_expect_success setup '
|
||||
test_commit initial
|
||||
'
|
||||
@@ -40,6 +49,23 @@ test_expect_success clone '
|
||||
git clone "file://$UNCPATH" clone
|
||||
'
|
||||
|
||||
test_expect_success 'clone without file://' '
|
||||
git clone "$UNCPATH" clone-without-file
|
||||
'
|
||||
|
||||
test_expect_success 'clone with backslashed path' '
|
||||
BACKSLASHED="$(echo "$UNCPATH" | tr / \\\\)" &&
|
||||
git clone "$BACKSLASHED" backslashed
|
||||
'
|
||||
|
||||
test_expect_success fetch '
|
||||
git init to-fetch &&
|
||||
(
|
||||
cd to-fetch &&
|
||||
git fetch "$UNCPATH" master
|
||||
)
|
||||
'
|
||||
|
||||
test_expect_success push '
|
||||
(
|
||||
cd clone &&
|
||||
@@ -57,4 +83,16 @@ test_expect_success MINGW 'remote nick cannot contain backslashes' '
|
||||
test_i18ngrep ! "unable to access" err
|
||||
'
|
||||
|
||||
test_expect_success 'unc alternates' '
|
||||
tree="$(git rev-parse HEAD:)" &&
|
||||
mkdir test-unc-alternate &&
|
||||
(
|
||||
cd test-unc-alternate &&
|
||||
git init &&
|
||||
test_must_fail git show $tree &&
|
||||
echo "$UNCPATH/.git/objects" >.git/objects/info/alternates &&
|
||||
git show $tree
|
||||
)
|
||||
'
|
||||
|
||||
test_done
|
||||
@@ -228,7 +228,7 @@ test_expect_success 'push update refs failure' '
|
||||
echo "update fail" >>file &&
|
||||
git commit -a -m "update fail" &&
|
||||
git rev-parse --verify testgit/origin/heads/update >expect &&
|
||||
test_expect_code 1 env GIT_REMOTE_TESTGIT_FAILURE="non-fast forward" \
|
||||
test_must_fail env GIT_REMOTE_TESTGIT_FAILURE="non-fast forward" \
|
||||
git push origin update &&
|
||||
git rev-parse --verify testgit/origin/heads/update >actual &&
|
||||
test_cmp expect actual
|
||||
|
||||
32
t/t7108-reset-stdin.sh
Executable file
32
t/t7108-reset-stdin.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='reset --stdin'
|
||||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'reset --stdin' '
|
||||
test_commit hello &&
|
||||
git rm hello.t &&
|
||||
test -z "$(git ls-files hello.t)" &&
|
||||
echo hello.t | git reset --stdin &&
|
||||
test hello.t = "$(git ls-files hello.t)"
|
||||
'
|
||||
|
||||
test_expect_success 'reset --stdin -z' '
|
||||
test_commit world &&
|
||||
git rm hello.t world.t &&
|
||||
test -z "$(git ls-files hello.t world.t)" &&
|
||||
printf world.tQworld.tQhello.tQ | q_to_nul | git reset --stdin -z &&
|
||||
printf "hello.t\nworld.t\n" >expect &&
|
||||
git ls-files >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success '--stdin requires --mixed' '
|
||||
echo hello.t >list &&
|
||||
test_must_fail git reset --soft --stdin <list &&
|
||||
test_must_fail git reset --hard --stdin <list &&
|
||||
git reset --mixed --stdin <list
|
||||
'
|
||||
|
||||
test_done
|
||||
@@ -556,4 +556,15 @@ test_expect_success 'merge commit gets exported with --import-marks' '
|
||||
)
|
||||
'
|
||||
|
||||
cat > expected << EOF
|
||||
reset refs/heads/master
|
||||
from $(git rev-parse master)
|
||||
|
||||
EOF
|
||||
|
||||
test_expect_failure 'refs are updated even if no commits need to be exported' '
|
||||
git fast-export master..master > actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
159
t/test-lib.sh
159
t/test-lib.sh
@@ -95,6 +95,13 @@ done,*)
|
||||
test "$(cat "$BASE.exit")" = 0
|
||||
exit
|
||||
;;
|
||||
*' --write-junit-xml '*)
|
||||
# record how to call this script *with* --verbose-log, in case
|
||||
# we encounter a breakage
|
||||
junit_rerun_options_sq="$(printf '%s\n' "$0" --verbose-log -x "$@" |
|
||||
sed -e "s/'/'\\\\''/g" -e "s/^/'/" -e "s/\$/'/" |
|
||||
tr '\012' ' ')"
|
||||
;;
|
||||
esac
|
||||
|
||||
# For repeatability, reset the environment to known value.
|
||||
@@ -294,6 +301,8 @@ do
|
||||
test -z "$HARNESS_ACTIVE" && quiet=t; shift ;;
|
||||
--with-dashes)
|
||||
with_dashes=t; shift ;;
|
||||
--no-bin-wrappers)
|
||||
no_bin_wrappers=t; shift ;;
|
||||
--no-color)
|
||||
color=; shift ;;
|
||||
--va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
|
||||
@@ -339,6 +348,9 @@ do
|
||||
-V|--verbose-log)
|
||||
verbose_log=t
|
||||
shift ;;
|
||||
--write-junit-xml)
|
||||
write_junit_xml=t
|
||||
shift ;;
|
||||
*)
|
||||
echo "error: unknown test option '$1'" >&2; exit 1 ;;
|
||||
esac
|
||||
@@ -486,11 +498,34 @@ trap 'exit $?' INT
|
||||
# the test_expect_* functions instead.
|
||||
|
||||
test_ok_ () {
|
||||
if test -n "$write_junit_xml"
|
||||
then
|
||||
write_junit_xml_testcase "$*"
|
||||
fi
|
||||
test_success=$(($test_success + 1))
|
||||
say_color "" "ok $test_count - $@"
|
||||
}
|
||||
|
||||
test_failure_ () {
|
||||
if test -n "$write_junit_xml"
|
||||
then
|
||||
junit_insert="<failure message=\"not ok $test_count -"
|
||||
junit_insert="$junit_insert $(xml_attr_encode "$1")\">"
|
||||
junit_insert="$junit_insert $(xml_attr_encode \
|
||||
"$(if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
|
||||
then
|
||||
cut -c "$GIT_TEST_TEE_OFFSET-" <"$GIT_TEST_TEE_OUTPUT_FILE"
|
||||
else
|
||||
printf '%s\n' "$@" | sed 1d
|
||||
fi)")"
|
||||
junit_insert="$junit_insert</failure>"
|
||||
if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
|
||||
then
|
||||
junit_insert="$junit_insert<system-err>$(xml_attr_encode \
|
||||
"$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")</system-err>"
|
||||
fi
|
||||
write_junit_xml_testcase "$1" " $junit_insert"
|
||||
fi
|
||||
test_failure=$(($test_failure + 1))
|
||||
say_color error "not ok $test_count - $1"
|
||||
shift
|
||||
@@ -499,11 +534,19 @@ test_failure_ () {
|
||||
}
|
||||
|
||||
test_known_broken_ok_ () {
|
||||
if test -n "$write_junit_xml"
|
||||
then
|
||||
write_junit_xml_testcase "$* (breakage fixed)"
|
||||
fi
|
||||
test_fixed=$(($test_fixed+1))
|
||||
say_color error "ok $test_count - $@ # TODO known breakage vanished"
|
||||
}
|
||||
|
||||
test_known_broken_failure_ () {
|
||||
if test -n "$write_junit_xml"
|
||||
then
|
||||
write_junit_xml_testcase "$* (known breakage)"
|
||||
fi
|
||||
test_broken=$(($test_broken+1))
|
||||
say_color warn "not ok $test_count - $@ # TODO known breakage"
|
||||
}
|
||||
@@ -761,6 +804,10 @@ test_start_ () {
|
||||
test_count=$(($test_count+1))
|
||||
maybe_setup_verbose
|
||||
maybe_setup_valgrind
|
||||
if test -n "$write_junit_xml"
|
||||
then
|
||||
junit_start=$(test-tool date getnanos)
|
||||
fi
|
||||
}
|
||||
|
||||
test_finish_ () {
|
||||
@@ -798,6 +845,13 @@ test_skip () {
|
||||
|
||||
case "$to_skip" in
|
||||
t)
|
||||
if test -n "$write_junit_xml"
|
||||
then
|
||||
message="$(xml_attr_encode "$skipped_reason")"
|
||||
write_junit_xml_testcase "$1" \
|
||||
" <skipped message=\"$message\" />"
|
||||
fi
|
||||
|
||||
say_color skip >&3 "skipping test: $@"
|
||||
say_color skip "ok $test_count # skip $1 ($skipped_reason)"
|
||||
: true
|
||||
@@ -813,9 +867,66 @@ test_at_end_hook_ () {
|
||||
:
|
||||
}
|
||||
|
||||
write_junit_xml () {
|
||||
case "$1" in
|
||||
--truncate)
|
||||
>"$junit_xml_path"
|
||||
junit_have_testcase=
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
printf '%s\n' "$@" >>"$junit_xml_path"
|
||||
}
|
||||
|
||||
xml_attr_encode () {
|
||||
# We do not translate CR to 
 because BSD sed does not handle
|
||||
# \r in the regex. In practice, the output should not even have any
|
||||
# carriage returns.
|
||||
printf '%s\n' "$@" |
|
||||
sed -e 's/&/\&/g' -e "s/'/\'/g" -e 's/"/\"/g' \
|
||||
-e 's/</\</g' -e 's/>/\>/g' \
|
||||
-e "s/$(printf \\x1c)/\\�/g" \
|
||||
-e "s/$(printf \\x1d)/\\�/g" \
|
||||
-e "s/$(printf \\x1e)/\\�/g" \
|
||||
-e "s/$(printf \\x1f)/\\�/g" \
|
||||
-e 's/ /\	/g' -e 's/$/\
/' -e '$s/
$//' |
|
||||
tr -d '\012\015'
|
||||
}
|
||||
|
||||
write_junit_xml_testcase () {
|
||||
junit_attrs="name=\"$(xml_attr_encode "$this_test.$test_count $1")\""
|
||||
shift
|
||||
junit_attrs="$junit_attrs classname=\"$this_test\""
|
||||
junit_attrs="$junit_attrs time=\"$(test-tool \
|
||||
date getnanos $junit_start)\""
|
||||
write_junit_xml "$(printf '%s\n' \
|
||||
" <testcase $junit_attrs>" "$@" " </testcase>")"
|
||||
junit_have_testcase=t
|
||||
if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
|
||||
then
|
||||
GIT_TEST_TEE_OFFSET=$(perl -e 'print -s $ARGV[0]' "$GIT_TEST_TEE_OUTPUT_FILE")
|
||||
fi
|
||||
}
|
||||
|
||||
test_done () {
|
||||
GIT_EXIT_OK=t
|
||||
|
||||
if test -n "$write_junit_xml" && test -n "$junit_xml_path"
|
||||
then
|
||||
test -n "$junit_have_testcase" || {
|
||||
junit_start=$(test-tool date getnanos)
|
||||
write_junit_xml_testcase "all tests skipped"
|
||||
}
|
||||
|
||||
# adjust the overall time
|
||||
junit_time=$(test-tool date getnanos $junit_suite_start)
|
||||
sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
|
||||
<"$junit_xml_path" >"$junit_xml_path.new"
|
||||
mv "$junit_xml_path.new" "$junit_xml_path"
|
||||
|
||||
write_junit_xml " </testsuite>" "</testsuites>"
|
||||
fi
|
||||
|
||||
if test -z "$HARNESS_ACTIVE"
|
||||
then
|
||||
test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
|
||||
@@ -878,7 +989,11 @@ test_done () {
|
||||
error "Tests passed but trash directory already removed before test cleanup; aborting"
|
||||
|
||||
cd "$TRASH_DIRECTORY/.." &&
|
||||
rm -fr "$TRASH_DIRECTORY" ||
|
||||
rm -fr "$TRASH_DIRECTORY" || {
|
||||
# try again in a bit
|
||||
sleep 5;
|
||||
rm -fr "$TRASH_DIRECTORY"
|
||||
} ||
|
||||
error "Tests passed but test cleanup failed; aborting"
|
||||
fi
|
||||
test_at_end_hook_
|
||||
@@ -984,20 +1099,25 @@ then
|
||||
PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR/t/helper:$PATH
|
||||
GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}
|
||||
else # normal case, use ../bin-wrappers only unless $with_dashes:
|
||||
git_bin_dir="$GIT_BUILD_DIR/bin-wrappers"
|
||||
if ! test -x "$git_bin_dir/git"
|
||||
if test -n "$no_bin_wrappers"
|
||||
then
|
||||
if test -z "$with_dashes"
|
||||
then
|
||||
say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH"
|
||||
fi
|
||||
with_dashes=t
|
||||
else
|
||||
git_bin_dir="$GIT_BUILD_DIR/bin-wrappers"
|
||||
if ! test -x "$git_bin_dir/git"
|
||||
then
|
||||
if test -z "$with_dashes"
|
||||
then
|
||||
say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH"
|
||||
fi
|
||||
with_dashes=t
|
||||
fi
|
||||
PATH="$git_bin_dir:$PATH"
|
||||
fi
|
||||
PATH="$git_bin_dir:$PATH"
|
||||
GIT_EXEC_PATH=$GIT_BUILD_DIR
|
||||
if test -n "$with_dashes"
|
||||
then
|
||||
PATH="$GIT_BUILD_DIR:$PATH"
|
||||
PATH="$GIT_BUILD_DIR:$GIT_BUILD_DIR/t/helper:$PATH"
|
||||
fi
|
||||
fi
|
||||
GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt
|
||||
@@ -1021,7 +1141,7 @@ test -d "$GIT_BUILD_DIR"/templates/blt || {
|
||||
error "You haven't built things yet, have you?"
|
||||
}
|
||||
|
||||
if ! test -x "$GIT_BUILD_DIR"/t/helper/test-tool
|
||||
if ! test -x "$GIT_BUILD_DIR"/t/helper/test-tool$X
|
||||
then
|
||||
echo >&2 'You need to build test-tool:'
|
||||
echo >&2 'Run "make t/helper/test-tool" in the source (toplevel) directory'
|
||||
@@ -1051,6 +1171,7 @@ then
|
||||
else
|
||||
mkdir -p "$TRASH_DIRECTORY"
|
||||
fi
|
||||
|
||||
# Use -P to resolve symlinks in our working directory so that the cwd
|
||||
# in subprocesses like git equals our $PWD (for pathname comparisons).
|
||||
cd -P "$TRASH_DIRECTORY" || exit 1
|
||||
@@ -1064,6 +1185,24 @@ then
|
||||
test_done
|
||||
fi
|
||||
|
||||
if test -n "$write_junit_xml"
|
||||
then
|
||||
junit_xml_dir="$TEST_OUTPUT_DIRECTORY/out"
|
||||
mkdir -p "$junit_xml_dir"
|
||||
junit_xml_base=${0##*/}
|
||||
junit_xml_path="$junit_xml_dir/TEST-${junit_xml_base%.sh}.xml"
|
||||
junit_attrs="name=\"${junit_xml_base%.sh}\""
|
||||
junit_attrs="$junit_attrs timestamp=\"$(TZ=UTC \
|
||||
date +%Y-%m-%dT%H:%M:%S)\""
|
||||
write_junit_xml --truncate "<testsuites>" " <testsuite $junit_attrs>"
|
||||
junit_suite_start=$(test-tool date getnanos)
|
||||
if test -n "$GIT_TEST_TEE_OUTPUT_FILE"
|
||||
then
|
||||
GIT_TEST_TEE_OFFSET=0
|
||||
GIT_TEST_TEE_ERR_OFFSET=0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Provide an implementation of the 'yes' utility
|
||||
yes () {
|
||||
if test $# = 0
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "protocol.h"
|
||||
|
||||
static int debug;
|
||||
/* TODO: put somewhere sensible, e.g. git_transport_options? */
|
||||
static int auto_gc = 1;
|
||||
|
||||
struct helper_data {
|
||||
const char *name;
|
||||
@@ -460,10 +462,25 @@ static int get_exporter(struct transport *transport,
|
||||
for (i = 0; i < revlist_args->nr; i++)
|
||||
argv_array_push(&fastexport->args, revlist_args->items[i].string);
|
||||
|
||||
argv_array_push(&fastexport->args, "--");
|
||||
|
||||
fastexport->git_cmd = 1;
|
||||
return start_command(fastexport);
|
||||
}
|
||||
|
||||
static void check_helper_status(struct helper_data *data)
|
||||
{
|
||||
int pid, status;
|
||||
|
||||
pid = waitpid(data->helper->pid, &status, WNOHANG);
|
||||
if (pid < 0)
|
||||
die("Could not retrieve status of remote helper '%s'",
|
||||
data->name);
|
||||
if (pid > 0 && WIFEXITED(status))
|
||||
die("Remote helper '%s' died with %d",
|
||||
data->name, WEXITSTATUS(status));
|
||||
}
|
||||
|
||||
static int fetch_with_import(struct transport *transport,
|
||||
int nr_heads, struct ref **to_fetch)
|
||||
{
|
||||
@@ -500,6 +517,7 @@ static int fetch_with_import(struct transport *transport,
|
||||
|
||||
if (finish_command(&fastimport))
|
||||
die(_("error while running fast-import"));
|
||||
check_helper_status(data);
|
||||
|
||||
/*
|
||||
* The fast-import stream of a remote helper that advertises
|
||||
@@ -533,6 +551,12 @@ static int fetch_with_import(struct transport *transport,
|
||||
}
|
||||
}
|
||||
strbuf_release(&buf);
|
||||
if (auto_gc) {
|
||||
const char *argv_gc_auto[] = {
|
||||
"gc", "--auto", "--quiet", NULL,
|
||||
};
|
||||
run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -987,6 +1011,7 @@ static int push_refs_with_export(struct transport *transport,
|
||||
|
||||
if (finish_command(&exporter))
|
||||
die(_("error while running fast-export"));
|
||||
check_helper_status(data);
|
||||
if (push_update_refs_status(data, remote_refs, flags))
|
||||
return 1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user