summaryrefslogtreecommitdiff
path: root/ci
AgeCommit message (Collapse)AuthorFilesLines
2019-02-06Merge branch 'js/vsts-ci'Libravatar Junio C Hamano12-35/+157
Prepare to run test suite on Azure Pipeline. * js/vsts-ci: (22 commits) test-date: drop unused parameter to getnanos() ci: parallelize testing on Windows ci: speed up Windows phase tests: optionally skip bin-wrappers/ t0061: workaround issues with --with-dashes and RUNTIME_PREFIX tests: add t/helper/ to the PATH with --with-dashes mingw: try to work around issues with the test cleanup tests: include detailed trace logs with --write-junit-xml upon failure tests: avoid calling Perl just to determine file sizes README: add a build badge (status of the Azure Pipelines build) mingw: be more generous when wrapping up the setitimer() emulation ci: use git-sdk-64-minimal build artifact ci: add a Windows job to the Azure Pipelines definition Add a build definition for Azure DevOps ci/lib.sh: add support for Azure Pipelines tests: optionally write results as JUnit-style .xml test-date: add a subcommand to measure times in shell scripts ci: use a junction on Windows instead of a symlink ci: inherit --jobs via MAKEFLAGS in run-build-and-tests ci/lib.sh: encapsulate Travis-specific things ...
2019-01-29ci: parallelize testing on WindowsLibravatar Johannes Schindelin2-0/+29
The fact that Git's test suite is implemented in Unix shell script that is as portable as we can muster, combined with the fact that Unix shell scripting is foreign to Windows (and therefore has to be emulated), results in pretty abysmal speed of the test suite on that platform, for pretty much no other reason than that language choice. For comparison: while the Linux build & test is typically done within about 8 minutes, the Windows build & test typically lasts about 80 minutes in Azure Pipelines. To help with that, let's use the Azure Pipeline feature where you can parallelize jobs, make jobs depend on each other, and pass artifacts between them. The tests are distributed using the following heuristic: listing all test scripts ordered by size in descending order (as a cheap way to estimate the overall run time), every Nth script is run (where N is the total number of parallel jobs), starting at the index corresponding to the parallel job. This slicing is performed by a new function that is added to the `test-tool`. To optimize the overall runtime of the entire Pipeline, we need to move the Windows jobs to the beginning (otherwise there would be a very decent chance for the Pipeline to be run only the Windows build, while all the parallel Windows test jobs wait for this single one). We use Azure Pipelines Artifacts for both the minimal Git for Windows SDK as well as the built executables, as deduplication and caching close to the agents makes that really fast. For comparison: while downloading and unpacking the minimal Git for Windows SDK via PowerShell takes only one minute (down from anywhere between 2.5 to 7 when using a shallow clone), uploading it as Pipeline Artifact takes less than 30s and downloading and unpacking less than 20s (sometimes even as little as only twelve seconds). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-29ci: speed up Windows phaseLibravatar Johannes Schindelin1-0/+2
As Unix shell scripting comes at a hefty price on Windows, we have to see where we can save some time to run the test suite. Let's skip the chain linting and the bin-wrappers/ redirection on Windows; this seems to shave of anywhere between 10-30% from the overall runtime. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-29Add a build definition for Azure DevOpsLibravatar Johannes Schindelin1-0/+25
This commit adds an azure-pipelines.yml file which is Azure DevOps' equivalent to Travis CI's .travis.yml. The main idea is to replicate the Travis configuration as faithfully as possible, to make it easy to compare the Azure Pipeline builds to the Travis ones (spoiler: some parts, especially the macOS jobs, are way faster in Azure Pileines). Meaning: the number and the order of the jobs added in this commit faithfully replicates what we have in .travis.yml. Note: Our .travis.yml configuration has a Windows part that is *not* replicated in the Azure Pipelines definition. The reason is easy to see: As Travis cannot support our Windws needs (even with the preliminary Windows support that was recently added to Travis after waiting for *years* for that feature, our test suite would simply hit Travis' timeout every single time). To make things a bit easier to understand, we refrain from using the `matrix` feature here because (while it is powerful) it can be a bit confusing to users who are not familiar with CI setups. Therefore, we use a separate phase even for similar configurations (such as GCC vs Clang on Linux, GCC vs Clang on macOS). Also, we make use of the shiny new feature we just introduced where the test suite can output JUnit-style .xml files. This information is made available in a nice UI that allows the viewer to filter by phase and/or test number, and to see trends such as: number of (failing) tests, time spent running the test suite, etc. (While this seemingly contradicts the intention to replicate the Travis configuration as faithfully as possible, it is just too nice to show off that capability here already.) Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-29ci/lib.sh: add support for Azure PipelinesLibravatar Johannes Schindelin2-0/+30
This patch introduces a conditional arm that defines some environment variables and a function that displays the URL given the job id (to identify previous runs for known-good trees). Because Azure Pipeline's macOS agents already have git-lfs and gettext installed, we can leave `BREW_INSTALL_PACKAGES` empty (unlike in Travis' case). Note: this patch does not introduce an Azure Pipelines definition yet; That is left for the next patch. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-28ci: use a junction on Windows instead of a symlinkLibravatar Johannes Schindelin1-1/+4
Symbolic links are still not quite as easy to use on Windows as on Linux (for example, on versions older than Windows 10, only administrators can create symlinks, and on Windows 10 you still need to be in developer mode for regular users to have permission), but NTFS junctions can give us a way out. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-28ci: inherit --jobs via MAKEFLAGS in run-build-and-testsLibravatar Johannes Schindelin5-5/+6
Let's not decide in the generic ci/ part how many jobs to run in parallel; different CI configurations would favor a different number of parallel jobs, and it is easy enough to hand that information down via the `MAKEFLAGS` variable. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-28ci/lib.sh: encapsulate Travis-specific thingsLibravatar Johannes Schindelin4-14/+43
The upcoming patches will allow building git.git via Azure Pipelines (i.e. Azure DevOps' Continuous Integration), where variable names and URLs look a bit different than in Travis CI. Also, the configurations of the available agents are different. For example, Travis' and Azure Pipelines' macOS agents are set up differently, so that on Travis, we have to install the git-lfs and gettext Homebrew packages, and on Azure Pipelines we do not need to. Likewise, Azure Pipelines' Ubuntu agents already have asciidoctor installed. Finally, on Azure Pipelines the natural way is not to base64-encode tar files of the trash directories of failed tests, but to publish build artifacts instead. Therefore, that code to log those base64-encoded tar files is guarded to be Travis-specific. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-28ci: rename the library of common functionsLibravatar Johannes Schindelin8-7/+7
The name is hard-coded to reflect that we use Travis CI for continuous testing. In the next commits, we will extend this to be able use Azure DevOps, too. So let's adjust the name to make it more generic. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-28travis: fix skipping tagged releasesLibravatar Johannes Schindelin1-11/+14
When building a PR, TRAVIS_BRANCH refers to the *target branch*. Therefore, if a PR targets `master`, and `master` happened to be tagged, we skipped the build by mistake. Fix this by using TRAVIS_PULL_REQUEST_BRANCH (i.e. the *source branch*) when available, falling back to TRAVIS_BRANCH (i.e. for CI builds, also known as "push builds"). Let's give it a new variable name, too: CI_BRANCH (as it is different from TRAVIS_BRANCH). This also prepares for the upcoming patches which will make our ci/* code a bit more independent from Travis and open it to other CI systems (in particular to Azure Pipelines). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-17travis-ci: build with the right compilerLibravatar SZEDER Gábor2-3/+17
Our 'Makefile' hardcodes the compiler to build Git as 'CC = cc'. This CC variable can be overridden from the command line, i.e. 'make CC=gcc-X.Y' will build with that particular GCC version, but not from the environment, i.e. 'CC=gcc-X.Y make' will still build with whatever 'cc' happens to be on the platform. Our build jobs on Travis CI are badly affected by this. In the build matrix we have dedicated build jobs to build Git with GCC and Clang both on Linux and macOS from the very beginning (522354d70f (Add Travis CI support, 2015-11-27)). Alas, this never really worked as supposed to, because Travis CI specifies the compiler for those build jobs as 'export CC=gcc' and 'export CC=clang' (which works fine for projects built with './configure && make'). Consequently, our 'linux-clang' build job has always used GCC, because that's where 'cc' points at in Travis CI's Linux images, while the 'osx-gcc' build job has always used Clang. Furthermore, 37fa4b3c78 (travis-ci: run gcc-8 on linux-gcc jobs, 2018-05-19) added an 'export CC=gcc-8' in an attempt to build with a more modern compiler, but to no avail. Set MAKEFLAGS with CC based on the $CC environment variable, so 'make' will run the "right" compiler. The Xcode 10.1 macOS image on Travis CI already contains the gcc@8 package from Homebrew, but we have to 'brew link' it first to be able to use it. So with this patch our build jobs will build Git with the following compiler versions: linux-clang: clang version 5.0.0 (tags/RELEASE_500/final) linux-gcc: gcc-8 (Ubuntu 8.1.0-5ubuntu1~14.04) 8.1.0 osx-clang: Apple LLVM version 10.0.0 (clang-1000.11.45.5) osx-gcc: gcc-8 (Homebrew GCC 8.2.0) 8.2.0 GETTEXT_POISON: gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4 Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-17travis-ci: don't be '--quiet' when running the testsLibravatar SZEDER Gábor2-3/+3
All Travis CI build jobs run the test suite with 'make --quiet test'. On one hand, being quiet doesn't save us from much clutter in the output: $ make test |wc -l 861 $ make --quiet test |wc -l 848 It only spares 13 lines, mostly the output of entering the 't/' directory and the pre- and post-cleanup commands, which is negligible compared to the ~700 lines printed while building Git and the ~850 lines of 'prove' output. On the other hand, it's asking for trouble. In our CI build scripts we build Git and run the test suite in two separate 'make' invocations. In a prelimiary version of one of the later patches in this series, to explicitly specify which compiler to use, I changed them to basically run: make CC=$CC make --quiet test naively thinking that it should Just Work... but then that 'make --quiet test' got all clever on me, noticed the changed build flags, and then proceeded to rebuild everything with the default 'cc'. And because of that '--quiet' option, it did so, well, quietly, only saying "* new build flags", and it was by mere luck that I happened to notice that something is amiss. Let's just drop that '--quiet' option when running the test suite in all build scripts. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-11-19Merge branch 'ab/dynamic-gettext-poison'Libravatar Junio C Hamano1-2/+2
Our testing framework uses a special i18n "poisoned localization" feature to find messages that ought to stay constant but are incorrectly marked to be translated. This feature has been made into a runtime option (it used to be a compile-time option). * ab/dynamic-gettext-poison: Makefile: ease dynamic-gettext-poison transition i18n: make GETTEXT_POISON a runtime option
2018-11-13Merge branch 'sg/travis-install-dependencies'Libravatar Junio C Hamano1-6/+29
The procedure to install dependencies before testing at Travis CI is getting revamped for both simplicity and flexibility, taking advantage of the recent move to the vm-based environment. * sg/travis-install-dependencies: travis-ci: install packages in 'ci/install-dependencies.sh'
2018-11-09i18n: make GETTEXT_POISON a runtime optionLibravatar Ævar Arnfjörð Bjarmason1-2/+2
Change the GETTEXT_POISON compile-time + runtime GIT_GETTEXT_POISON test parameter to only be a GIT_TEST_GETTEXT_POISON=<non-empty?> runtime parameter, to be consistent with other parameters documented in "Running tests with special setups" in t/README. When I added GETTEXT_POISON in bb946bba76 ("i18n: add GETTEXT_POISON to simulate unfriendly translator", 2011-02-22) I was concerned with ensuring that the _() function would get constant folded if NO_GETTEXT was defined, and likewise that GETTEXT_POISON would be compiled out unless it was defined. But as the benchmark in my [1] shows doing a one-off runtime getenv("GIT_TEST_[...]") is trivial, and since GETTEXT_POISON was originally added the GIT_TEST_* env variables have become the common idiom for turning on special test setups. So change GETTEXT_POISON to work the same way. Now the GETTEXT_POISON=YesPlease compile-time option is gone, and running the tests with GIT_TEST_GETTEXT_POISON=[YesPlease|] can be toggled on/off without recompiling. This allows for conditionally amending tests to test with/without poison, similar to what 859fdc0c3c ("commit-graph: define GIT_TEST_COMMIT_GRAPH", 2018-08-29) did for GIT_TEST_COMMIT_GRAPH. Do some of that, now we e.g. always run the t0205-gettext-poison.sh test. I did enough there to remove the GETTEXT_POISON prerequisite, but its inverse C_LOCALE_OUTPUT is still around, and surely some tests using it can be converted to e.g. always set GIT_TEST_GETTEXT_POISON=. Notes on the implementation: * We still compile a dedicated GETTEXT_POISON build in Travis CI. Perhaps this should be revisited and integrated into the "linux-gcc" build, see ae59a4e44f ("travis: run tests with GIT_TEST_SPLIT_INDEX", 2018-01-07) for prior art in that area. Then again maybe not, see [2]. * We now skip a test in t0000-basic.sh under GIT_TEST_GETTEXT_POISON=YesPlease that wasn't skipped before. This test relies on C locale output, but due to an edge case in how the previous implementation of GETTEXT_POISON worked (reading it from GIT-BUILD-OPTIONS) wasn't enabling poison correctly. Now it does, and needs to be skipped. * The getenv() function is not reentrant, so out of paranoia about code of the form: printf(_("%s"), getenv("some-env")); call use_gettext_poison() in our early setup in git_setup_gettext() so we populate the "poison_requested" variable in a codepath that's won't suffer from that race condition. * We error out in the Makefile if you're still saying GETTEXT_POISON=YesPlease to prompt users to change their invocation. * We should not print out poisoned messages during the test initialization itself to keep it more readable, so the test library hides the variable if set in $GIT_TEST_GETTEXT_POISON_ORIG during setup. See [3]. See also [4] for more on the motivation behind this patch, and the history of the GETTEXT_POISON facility. 1. https://public-inbox.org/git/871s8gd32p.fsf@evledraar.gmail.com/ 2. https://public-inbox.org/git/20181102163725.GY30222@szeder.dev/ 3. https://public-inbox.org/git/20181022202241.18629-2-szeder.dev@gmail.com/ 4. https://public-inbox.org/git/878t2pd6yu.fsf@evledraar.gmail.com/ Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-11-02travis-ci: install packages in 'ci/install-dependencies.sh'Libravatar SZEDER Gábor1-6/+29
Ever since we started using Travis CI, we specified the list of packages to install in '.travis.yml' via the APT addon. While running our builds on Travis CI's container-based infrastructure we didn't have another choice, because that environment didn't support 'sudo', and thus we didn't have permission to install packages ourselves. With the switch to the VM-based infrastructure in the previous patch we do get a working 'sudo', so we can install packages by running 'sudo apt-get -y install ...' as well. Let's make use of this and install necessary packages in 'ci/install-dependencies.sh', so all the dependencies (i.e. both packages and "non-packages" (P4 and Git-LFS)) are handled in the same file. Install gcc-8 only in the 'linux-gcc' build job; so far it has been unnecessarily installed in the 'linux-clang' build job as well. Print the versions of P4 and Git-LFS conditionally, i.e. only when they have been installed; with this change even the static analysis and documentation build jobs start using 'ci/install-dependencies.sh' to install packages, and neither of these two build jobs depend on and thus install those. This change will presumably be beneficial for the upcoming Azure Pipelines integration [1]: preliminary versions of that patch series run a couple of 'apt-get' commands to install the necessary packages before running 'ci/install-dependencies.sh', but with this patch it will be sufficient to run only 'ci/install-dependencies.sh'. [1] https://public-inbox.org/git/1a22efe849d6da79f2c639c62a1483361a130238.1539598316.git.gitgitgadget@gmail.com/ Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-10-19ci: add optional test variablesLibravatar Derrick Stolee1-0/+2
The commit-graph and multi-pack-index features introduce optional data structures that are not required for normal Git operations. It is important to run the normal test suite without them enabled, but it is helpful to also run the test suite using them. Our continuous integration scripts include a second test stage that runs with optional GIT_TEST_* variables enabled. Add the following two variables to that stage: GIT_TEST_COMMIT_GRAPH GIT_TEST_MULTI_PACK_INDEX This will slow down the operation, as we build a commit-graph file after every 'git commit' operation and build a multi-pack-index during every 'git repack' operation. However, it is important that future changes are compatible with these features. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-22Merge branch 'nd/pack-deltify-regression-fix'Libravatar Junio C Hamano1-0/+1
In a recent update in 2.18 era, "git pack-objects" started producing a larger than necessary packfiles by missing opportunities to use large deltas. * nd/pack-deltify-regression-fix: pack-objects: fix performance issues on packing large deltas
2018-08-15Merge branch 'sg/travis-retrieve-trash-upon-failure'Libravatar Junio C Hamano3-3/+104
The Travis CI scripts were taught to ship back the test data from failed tests. * sg/travis-retrieve-trash-upon-failure: travis-ci: include the trash directories of failed tests in the trace log
2018-08-01travis-ci: include the trash directories of failed tests in the trace logLibravatar SZEDER Gábor3-3/+104
The trash directory of a failed test might contain invaluable information about the cause of the failure, but we have no access to the trash directories of Travis CI build jobs. The only feedback we get from there is the build job's trace log, so... Modify 'ci/print-test-failures.sh' to create a tar.gz archive of the trash directory of each failed test, encode that archive with base64, and print the resulting block of ASCII text, so it gets embedded in the trace log. Furthermore, run tests with '--immediate' to faithfully preserve the failed state. Extracting the trash directories from the trace log turned out to be a bit of a hassle, partly because of the size of these logs (usually resulting in several hundreds or even thousands of lines of base64-encoded text), and partly because these logs have CRLF, CRCRLF and occasionally even CRCRCRLF line endings, which cause 'base64 -d' from coreutils to complain about "invalid input". For convenience add a small script 'ci/util/extract-trash-dirs.sh', which will extract and unpack all base64-encoded trash directories embedded in the log fed to its standard input, and include an example command to be copy-pasted into a terminal to do it all at the end of the failure report. A few of our tests create sizeable trash directories, so limit the size of each included base64-encoded block, let's say, to 1MB. And just in case something fundamental gets broken and a lot of tests fail at once, don't include trash directories when the combined size of the included base64-encoded blocks would exceed 1MB. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-23travis-ci: fail if Coccinelle static analysis found something to transformLibravatar SZEDER Gábor1-0/+19
Coccinelle's and in turn 'make coccicheck's exit code only indicates that Coccinelle managed to finish its analysis without any errors (e.g. no unknown --options, no missing files, no syntax errors in the semantic patches, etc.), but it doesn't indicate whether it found any undesired code patterns to transform or not. To find out the latter, one has to look closer at 'make coccicheck's standard output and look for lines like: SPATCH result: contrib/coccinelle/<something>.cocci.patch And this only indicates that there is something to transform, but to see what the suggested transformations are one has to actually look into those '*.cocci.patch' files. This makes the automated static analysis build job on Travis CI not particularly useful, because it neither draws our attention to Coccinelle's findings, nor shows the actual findings. Consequently, new topics introducing undesired code patterns graduated to master on several occasions without anyone noticing. The only way to draw attention in such an automated setting is to fail the build job. Therefore, modify the 'ci/run-static-analysis.sh' build script to check all the resulting '*.cocci.patch' files, and fail the build job if any of them turns out to be not empty. Include those files' contents, i.e. Coccinelle's suggested transformations, in the build job's trace log, so we'll know why it failed. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-23travis-ci: run Coccinelle static analysis with two parallel jobsLibravatar SZEDER Gábor1-1/+1
Currently the static analysis build job runs Coccinelle using a single 'make' job. Using two parallel jobs cuts down the build job's run time from around 10-12mins to 6-7mins, sometimes even under 6mins (there is quite large variation between build job runtimes). More than two parallel jobs don't seem to bring further runtime benefits. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-07-23pack-objects: fix performance issues on packing large deltasLibravatar Nguyễn Thái Ngọc Duy1-0/+1
Let's start with some background about oe_delta_size() and oe_set_delta_size(). If you already know, skip the next paragraph. These two are added in 0aca34e826 (pack-objects: shrink delta_size field in struct object_entry - 2018-04-14) to help reduce 'struct object_entry' size. The delta size field in this struct is reduced to only contain max 1MB. So if any new delta is produced and larger than 1MB, it's dropped because we can't really save such a large size anywhere. Fallback is provided in case existing packfiles already have large deltas, then we can retrieve it from the pack. While this should help small machines repacking large repos without large deltas (i.e. less memory pressure), dropping large deltas during the delta selection process could end up with worse pack files. And if existing packfiles already have >1MB delta and pack-objects is instructed to not reuse deltas, all of them will be dropped on the floor, and the resulting pack would be definitely bigger. There is also a regression in terms of CPU/IO if we have large on-disk deltas because fallback code needs to parse the pack every time the delta size is needed and just access to the mmap'd pack data is enough for extra page faults when memory is under pressure. Both of these issues were reported on the mailing list. Here's some numbers for comparison. Version Pack (MB) MaxRSS(kB) Time (s) ------- --------- ---------- -------- 2.17.0 5498 43513628 2494.85 2.18.0 10531 40449596 4168.94 This patch provides a better fallback that is - cheaper in terms of cpu and io because we won't have to read existing pack files as much - better in terms of pack size because the pack heuristics is back to 2.17.0 time, we do not drop large deltas at all If we encounter any delta (on-disk or created during try_delta phase) that is larger than the 1MB limit, we stop using delta_size_ field for this because it can't contain such size anyway. A new array of delta size is dynamically allocated and can hold all the deltas that 2.17.0 can. This array only contains delta sizes that delta_size_ can't contain. With this, we do not have to drop deltas in try_delta() anymore. Of course the downside is we use slightly more memory, even compared to 2.17.0. But since this is considered an uncommon case, a bit more memory consumption should not be a problem. Delta size limit is also raised from 1MB to 16MB to better cover common case and avoid that extra memory consumption (99.999% deltas in this reported repo are under 12MB; Jeff noted binary artifacts topped out at about 3MB in some other private repos). Other fields are shuffled around to keep this struct packed tight. We don't use more memory in common case even with this limit update. A note about thread synchronization. Since this code can be run in parallel during delta searching phase, we need a mutex. The realloc part in packlist_alloc() is not protected because it only happens during the object counting phase, which is always single-threaded. Access to e->delta_size_ (and by extension pack->delta_size[e - pack->objects]) is unprotected as before, the thread scheduler in pack-objects must make sure "e" is never updated by two different threads. The area under the new lock is as small as possible, avoiding locking at all in common case, since lock contention with high thread count could be expensive (most blobs are small enough that delta compute time is short and we end up taking the lock very often). The previous attempt to always hold a lock in oe_delta_size() and oe_set_delta_size() increases execution time by 33% when repacking linux.git with with 40 threads. Reported-by: Elijah Newren <newren@gmail.com> Helped-by: Elijah Newren <newren@gmail.com> Helped-by: Jeff King <peff@peff.net> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-30Merge branch 'nd/travis-gcc-8'Libravatar Junio C Hamano1-0/+3
Developer support. Use newer GCC on one of the builds done at TravisCI.org to get more warnings and errors diagnosed. * nd/travis-gcc-8: travis-ci: run gcc-8 on linux-gcc jobs
2018-05-21travis-ci: run gcc-8 on linux-gcc jobsLibravatar Nguyễn Thái Ngọc Duy1-0/+3
Switch from gcc-4.8 to gcc-8. Newer compilers come with more warning checks (usually in -Wextra). Since -Wextra is enabled in developer mode (which is also enabled in travis), this lets travis report more warnings before other people do it. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-16ci: exercise the whole test suite with uncommon code in pack-objectsLibravatar Nguyễn Thái Ngọc Duy1-1/+4
Some recent optimizations have been added to pack-objects to reduce memory usage and some code paths are split into two: one for common use cases and one for rare ones. Make sure the rare cases are tested with Travis since it requires manual test configuration that is unlikely to be done by developers. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-16read-cache.c: make $GIT_TEST_SPLIT_INDEX booleanLibravatar Nguyễn Thái Ngọc Duy1-1/+1
While at there, document about this special mode when running the test suite. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-03-14Merge branch 'sg/test-x'Libravatar Junio C Hamano1-1/+1
Running test scripts under -x option of the shell is often not a useful way to debug them, because the error messages from the commands tests try to capture and inspect are contaminated by the tracing output by the shell. An earlier work done to make it more pleasant to run tests under -x with recent versions of bash is extended to cover posix shells that do not support BASH_XTRACEFD. * sg/test-x: travis-ci: run tests with '-x' tracing t/README: add a note about don't saving stderr of compound commands t1510-repo-setup: mark as untraceable with '-x' t9903-bash-prompt: don't check the stderr of __git_ps1() t5570-git-daemon: don't check the stderr of a subshell t5526: use $TRASH_DIRECTORY to specify the path of GIT_TRACE log file t5500-fetch-pack: don't check the stderr of a subshell t3030-merge-recursive: don't check the stderr of a subshell t1507-rev-parse-upstream: don't check the stderr of a shell function t: add means to disable '-x' tracing for individual test scripts t: prevent '-x' tracing from interfering with test helpers' stderr
2018-03-08Merge branch 'sg/travis-build-during-script-phase'Libravatar Junio C Hamano2-9/+2
Build the executable in 'script' phase in Travis CI integration, to follow the established practice, rather than during 'before_script' phase. This allows the CI categorize the failures better ('failed' is project's fault, 'errored' is build environment's). * sg/travis-build-during-script-phase: travis-ci: build Git during the 'script' phase
2018-02-28travis-ci: run tests with '-x' tracingLibravatar SZEDER Gábor1-1/+1
Now that the test suite runs successfully with '-x' tracing even with /bin/sh, enable it on Travis CI in order to - get more information about test failures, and - catch constructs breaking '-x' with /bin/sh sneaking into our test suite. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-02-13Merge branch 'sg/travis-linux32-sanity'Libravatar Junio C Hamano4-18/+50
Travis updates. * sg/travis-linux32-sanity: travis-ci: don't fail if user already exists on 32 bit Linux build job travis-ci: don't run the test suite as root in the 32 bit Linux build travis-ci: don't repeat the path of the cache directory travis-ci: use 'set -e' in the 32 bit Linux build job travis-ci: use 'set -x' for the commands under 'su' in the 32 bit Linux build
2018-02-13Merge branch 'tg/split-index-fixes'Libravatar Junio C Hamano1-0/+4
The split-index mode had a few corner case bugs fixed. * tg/split-index-fixes: travis: run tests with GIT_TEST_SPLIT_INDEX split-index: don't write cache tree with null oid entries read-cache: fix reading the shared index for other repos
2018-01-30travis-ci: don't fail if user already exists on 32 bit Linux build jobLibravatar SZEDER Gábor1-1/+7
The 32 bit Linux build job runs in a Docker container, which lends itself to running and debugging locally, too. Especially during debugging one usually doesn't want to start with a fresh container every time, to save time spent on installing a bunch of dependencies. However, that doesn't work quite smootly, because the script running in the container always creates a new user, which then must be removed every time before subsequent executions, or the build script fails. Make this process more convenient and don't try to create that user if it already exists and has the right user ID in the container, so developers don't have to bother with running a 'userdel' each time before they run the build script. The build job on Travis CI always starts with a fresh Docker container, so this change doesn't make a difference there. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-30travis-ci: don't run the test suite as root in the 32 bit Linux buildLibravatar SZEDER Gábor2-6/+26
Travis CI runs the 32 bit Linux build job in a Docker container, where all commands are executed as root by default. Therefore, ever since we added this build job in 88dedd5e7 (Travis: also test on 32-bit Linux, 2017-03-05), we have a bit of code to create a user in the container matching the ID of the host user and then to run the test suite as this user. Matching the host user ID is important, because otherwise the host user would have no access to any files written by processes running in the container, notably the logs of failed tests couldn't be included in the build job's trace log. Alas, this piece of code never worked, because it sets the variable holding the user name ($CI_USER) in a subshell, meaning it doesn't have any effect by the time we get to the point to actually use the variable to switch users with 'su'. So all this time we were running the test suite as root. Reorganize that piece of code in 'ci/run-linux32-build.sh' a bit to avoid that problematic subshell and to ensure that we switch to the right user. Furthermore, make the script's optional host user ID option mandatory, so running the build accidentally as root will become harder when debugging locally. If someone really wants to run the test suite as root, whatever the reasons might be, it'll still be possible to do so by explicitly passing '0' as host user ID. Finally, one last catch: since commit 7e72cfcee (travis-ci: save prove state for the 32 bit Linux build, 2017-12-27) the 'prove' test harness has been writing its state to the Travis CI cache directory from within the Docker container while running as root. After this patch 'prove' will run as a regular user, so in future build jobs it won't be able overwrite a previously written, still root-owned state file, resulting in build job failures. To resolve this we should manually delete caches containing such root-owned files, but that would be a hassle. Instead, work this around by changing the owner of the whole contents of the cache directory to the host user ID. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-30travis-ci: don't repeat the path of the cache directoryLibravatar SZEDER Gábor4-6/+11
Some of our 'ci/*' scripts repeat the name or full path of the Travis CI cache directory, and the following patches will add new places using that path. Use a variable to refer to the path of the cache directory instead, so it's hard-coded only in a single place. Pay extra attention to the 32 bit Linux build: it runs in a Docker container, so pass the path of the cache directory from the host to the container in an environment variable. Note that an environment variable passed this way is exported inside the container, therefore its value is directly available in the 'su' snippet even though that snippet is single quoted. Furthermore, use the variable in the container only if it's been assigned a non-empty value, to prevent errors when someone is running or debugging the Docker build locally, because in that case the variable won't be set as there won't be any Travis CI cache. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-30travis-ci: use 'set -e' in the 32 bit Linux build jobLibravatar SZEDER Gábor1-10/+10
The script 'ci/run-linux32-build.sh' running inside the Docker container of the 32 bit Linux build job uses an && chain to break the build if one of the commands fails. This is problematic for two reasons: - The && chain is broken, because there is this in the middle: test -z $HOST_UID || (CI_USER="ci" && useradd -u $HOST_UID $CI_USER) && Luckily it is broken in a way that it didn't lead to false successes. If installing dependencies fails, then the rest of the first && chain is skipped and execution resumes after the || operator. At that point $HOST_UID is still unset, causing 'useradd' to error out with "invalid user ID 'ci'", which in turn causes the second && chain to abort the script and thus break the build. - All other 'ci/*' scripts use 'set -e' to break the build if one of the commands fails. This inconsistency among these scripts is asking for trouble: I forgot about the && chain more than once while working on this patch series. Enable 'set -e' for the whole script and for the commands executed under 'su' as well. While touching every line in the 'su' command block anyway, change their indentation to use a tab instead of spaces. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-30travis-ci: use 'set -x' for the commands under 'su' in the 32 bit Linux buildLibravatar SZEDER Gábor1-0/+1
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-19travis: run tests with GIT_TEST_SPLIT_INDEXLibravatar Thomas Gummerer1-0/+4
Split index mode only has a few dedicated tests, but as the index is involved in nearly every git operation, this doesn't quite cover all the ways repositories with split index can break. To use split index mode throughout the test suite a GIT_TEST_SPLIT_INDEX environment variable can be set, which makes git split the index at random and thus excercises the functionality much more thoroughly. As this is not turned on by default, it is not executed nearly as often as the test suite is run, so occationally breakages slip through. Try to counteract that by running the test suite with GIT_TEST_SPLIT_INDEX mode turned on on travis. To avoid using too many cycles on travis only run split index mode in the linux-gcc target only. The Linux build was chosen over the Mac OS builds because it tends to be much faster to complete. The linux gcc build was chosen over the linux clang build because the linux clang build is the fastest build, so it can serve as an early indicator if something is broken and we want to avoid spending the extra cycles of running the test suite twice for that. Helped-by: Lars Schneider <larsxschneider@gmail.com> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-08travis-ci: build Git during the 'script' phaseLibravatar SZEDER Gábor2-9/+3
Ever since we started building and testing Git on Travis CI (522354d70 (Add Travis CI support, 2015-11-27)), we build Git in the 'before_script' phase and run the test suite in the 'script' phase (except in the later introduced 32 bit Linux and Windows build jobs, where we build in the 'script' phase'). Contrarily, the Travis CI practice is to build and test in the 'script' phase; indeed Travis CI's default build command for the 'script' phase of C/C++ projects is: ./configure && make && make test The reason why Travis CI does it this way and why it's a better approach than ours lies in how unsuccessful build jobs are categorized. After something went wrong in a build job, its state can be: - 'failed', if a command in the 'script' phase returned an error. This is indicated by a red 'X' on the Travis CI web interface. - 'errored', if a command in the 'before_install', 'install', or 'before_script' phase returned an error, or the build job exceeded the time limit. This is shown as a red '!' on the web interface. This makes it easier, both for humans looking at the Travis CI web interface and for automated tools querying the Travis CI API, to decide when an unsuccessful build is our responsibility requiring human attention, i.e. when a build job 'failed' because of a compiler error or a test failure, and when it's caused by something beyond our control and might be fixed by restarting the build job, e.g. when a build job 'errored' because a dependency couldn't be installed due to a temporary network error or because the OSX build job exceeded its time limit. The drawback of building Git in the 'before_script' phase is that one has to check the trace log of all 'errored' build jobs, too, to see what caused the error, as it might have been caused by a compiler error. This requires additional clicks and page loads on the web interface and additional complexity and API requests in automated tools. Therefore, move building Git from the 'before_script' phase to the 'script' phase, updating the script's name accordingly as well. 'ci/run-builds.sh' now becomes basically empty, remove it. Several of our build job configurations override our default 'before_script' to do nothing; with this change our default 'before_script' won't do anything, either, so remove those overriding directives as well. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-03travis-ci: check that all build artifacts are .gitignore-dLibravatar SZEDER Gábor4-0/+20
Every once in a while our explicit .gitignore files get out of sync when our build process learns to create new artifacts, like test helper executables, but the .gitignore files are not updated accordingly. Use Travis CI to help catch such issues earlier: check that there are no untracked files at the end of any build jobs building Git (i.e. the 64 bit Clang and GCC Linux and OSX build jobs, plus the GETTEXT_POISON and 32 bit Linux build jobs) or its documentation, and fail the build job if there are any present. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-03travis-ci: don't store P4 and Git LFS in the working treeLibravatar SZEDER Gábor1-2/+2
The Clang and GCC 64 bit Linux build jobs download and store the P4 and Git LFS executables under the current directory, which is the working tree that we are about to build and test. This means that Git commands like 'status' or 'ls-files' would list these files as untracked. The next commit is about to make sure that there are no untracked files present after the build, and the downloaded executables in the working tree are interfering with those upcoming checks. Therefore, let's download P4 and Git LFS in the home directory, outside of the working tree. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-02travis-ci: record and skip successfully built treesLibravatar SZEDER Gábor6-0/+57
Travis CI dutifully builds and tests each new branch tip, even if its tree has previously been successfully built and tested. This happens often enough in contributors' workflows, when a work-in-progress branch is rebased changing e.g. only commit messages or the order or number of commits while leaving the resulting code intact, and is then pushed to a Travis CI-enabled GitHub fork. This is wasting Travis CI's resources and is sometimes scary-annoying when the new tip commit with a tree identical to the previous, successfully tested one is suddenly reported in red, because one of the OSX build jobs happened to exceed the time limit yet again. So extend our Travis CI build scripts to skip building commits whose trees have previously been successfully built and tested. Use the Travis CI cache feature to keep a record of the object names of trees that tested successfully, in a plain and simple flat text file, one line per tree object name. Append the current tree's object name at the end of every successful build job to this file, along with a bit of additional info about the build job (commit object name, Travis CI job number and id). Limit the size of this file to 1000 records, to prevent it from growing too large for git/git's forever living integration branches. Check, using a simple grep invocation, in each build job whether the current commit's tree is already in there, and skip the build if it is. Include a message in the skipped build job's trace log, containing the URL to the build job successfully testing that tree for the first time and instructions on how to force a re-build. Catch the case when a build job, which successfully built and tested a particular tree for the first time, is restarted and omit the URL of the previous build job's trace log, as in this case it's the same build job and the trace log has just been overwritten. Note: this won't kick in if two identical trees are on two different branches, because Travis CI caches are not shared between build jobs of different branches. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Reviewed-by: Lars Schneider <larsxschneider@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-02travis-ci: create the cache directory early in the build processLibravatar SZEDER Gábor2-1/+2
It seems that Travis CI creates the cache directory for us anyway, even when a previous cache doesn't exist for the current build job. Alas, this behavior is not explicitly documented, therefore we don't rely on it and create the cache directory ourselves in those build jobs that read/write cached data (currently only the prove state). In the following commit we'll start to cache additional data in every build job, and will access the cache much earlier in the build process. Therefore move creating the cache directory to 'ci/lib-travisci.sh' to make sure that it exists at the very beginning of every build job. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Reviewed-by: Lars Schneider <larsxschneider@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-01-02travis-ci: print the "tip of branch is exactly at tag" message in colorLibravatar SZEDER Gábor1-1/+1
To make this info message stand out from the regular build job trace output. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Reviewed-by: Lars Schneider <larsxschneider@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-27travis-ci: only print test failures if there are test results availableLibravatar SZEDER Gábor1-0/+6
When a build job running the test suite fails, our 'ci/print-test-failures.sh' script scans all 't/test-results/*.exit' files to find failed tests and prints their verbose output. However, if a build job were to fail before it ever gets to run the test suite, then there will be no files to match the above pattern and the shell will take the pattern literally, resulting in errors like this in the trace log: cat: t/test-results/*.exit: No such file or directory ------------------------------------------------------------------------ t/test-results/*.out... ------------------------------------------------------------------------ cat: t/test-results/*.out: No such file or directory Check upfront and proceed only if there are any such files present. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Reviewed-by: Lars Schneider <larsxschneider@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-27travis-ci: save prove state for the 32 bit Linux buildLibravatar SZEDER Gábor2-0/+2
This change follows suit of 6272ed319 (travis-ci: run previously failed tests first, then slowest to fastest, 2016-01-26), which did this for the Linux and OSX build jobs. Travis CI build jobs run the tests parallel, which is sligtly faster when tests are run in slowest to fastest order, shortening the overall runtime of this build job by about a minute / 10%. Note, that the 32 bit Linux build job runs the tests suite in a Docker container and we have to share the Travis CI cache directory with the container as a second volume. Otherwise we couldn't use a symlink pointing to the prove state file in the cache directory, because that's outside of the directory hierarchy accessible from within the container. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Reviewed-by: Lars Schneider <larsxschneider@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-27travis-ci: fine tune the use of 'set -x' in 'ci/*' scriptsLibravatar SZEDER Gábor4-1/+13
The change in commit 4f2636667 (travis-ci: use 'set -x' in 'ci/*' scripts for extra tracing output, 2017-12-12) left a couple of rough edges: - 'ci/run-linux32-build.sh' is executed in a Docker container and therefore doesn't source 'ci/lib-travisci.sh', which would enable tracing executed commands. Enable 'set -x' in this script, too. - 'ci/print-test-failures.sh' iterates over all the files containing the exit codes of all the executed test scripts. Since there are over 800 such files, the loop produces way too much noise with tracing executed commands enabled, so disable 'set -x' for this script. - 'ci/run-windows-build.sh' busily waits in a loop for the result of the Windows build, producing too much noise with tracing executed commands enabled as well. Disable 'set -x' for the duration of that loop. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-12travis-ci: use 'set -x' in 'ci/*' scripts for extra tracing outputLibravatar SZEDER Gábor1-1/+1
While the build logic was embedded in our '.travis.yml', Travis CI used to produce a nice trace log including all commands executed in those embedded scriptlets. Since 657343a60 (travis-ci: move Travis CI code into dedicated scripts, 2017-09-10), however, we only see the name of the dedicated scripts, but not what those scripts are actually doing, resulting in a less useful trace log. A patch later in this series will move setting environment variables from '.travis.yml' to the 'ci/*' scripts, so not even those will be included in the trace log. Use 'set -x' in 'ci/lib-travisci.sh', which is sourced in most other 'ci/*' scripts, so we get trace log about the commands executed in all of those scripts. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-12travis-ci: set GIT_TEST_HTTPD in 'ci/lib-travisci.sh'Libravatar SZEDER Gábor2-2/+2
Commit 657343a60 (travis-ci: move Travis CI code into dedicated scripts, 2017-09-10) converted '.travis.yml's default 'before_install' scriptlet to the 'ci/install-dependencies.sh' script, and while doing so moved setting GIT_TEST_HTTPD=YesPlease for the 64-bit GCC and Clang Linux build jobs to that script. This is wrong for two reasons: - The purpose of that script is, as its name suggests, to install dependencies, not to set any environment variables influencing which tests should be run (though, arguably, this was already an issue with the original 'before_install' scriptlet). - Setting the variable has no effect anymore, because that script is run in a separate shell process, and the variable won't be visible in any of the other scripts, notably in 'ci/run-tests.sh' responsible for, well, running the tests. Luckily, this didn't have a negative effect on our Travis CI build jobs, because GIT_TEST_HTTPD is a tri-state variable defaulting to "auto" and a functioning web server was installed in those Linux build jobs, so the httpd tests were run anyway. Apparently the httpd tests run just fine without GIT_TEST_HTTPD being set, therefore we could simply remove this environment variable. However, if a bug were to creep in to change the Travis CI build environment to run the tests as root or to not install Apache, then the httpd tests would be skipped and the build job would still succeed. We would only notice if someone actually were to look through the build job's trace log; but who would look at the trace log of a successful build job?! Since httpd tests are important, we do want to run them and we want to be loudly reminded if they can't be run. Therefore, move setting GIT_TEST_HTTPD=YesPlease for the 64-bit GCC and Clang Linux build jobs to 'ci/lib-travisci.sh' to ensure that the build job fails when the httpd tests can't be run. (We could set it in 'ci/run-tests.sh' just as well, but it's better to keep all environment variables in one place in 'ci/lib-travisci.sh'.) Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-12travis-ci: move setting environment variables to 'ci/lib-travisci.sh'Libravatar SZEDER Gábor1-0/+21
Our '.travis.yml's 'env.global' section sets a bunch of environment variables for all build jobs, though none of them actually affects all build jobs. It's convenient for us, and in most cases it works just fine, because irrelevant environment variables are simply ignored. However, $GIT_SKIP_TESTS is an exception: it tells the test harness to skip the two test scripts that are prone to occasional failures on OSX, but as it's set for all build jobs those tests are not run in any of the build jobs that are capable to run them reliably, either. Therefore $GIT_SKIP_TESTS should only be set in the OSX build jobs, but those build jobs are included in the build matrix implicitly (i.e. by combining the matrix keys 'os' and 'compiler'), and there is no way to set an environment variable only for a subset of those implicit build jobs. (Unless we were to add new scriptlets to '.travis.yml', which is exactly the opposite direction that we took with commit 657343a60 (travis-ci: move Travis CI code into dedicated scripts, 2017-09-10)). So move setting $GIT_SKIP_TESTS to 'ci/lib-travisci.sh', where it can trivially be set only for the OSX build jobs. Furthermore, move setting all other environment variables from '.travis.yml' to 'ci/lib-travisci.sh', too, because a couple of environment variables are already set there, and this way all environment variables will be set in the same place. All the logic controlling our builds is already in the 'ci/*' scripts anyway, so there is really no good reason to keep the environment variables separately. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>