summaryrefslogtreecommitdiff
path: root/t
AgeCommit message (Collapse)Author
2021-09-27connect: also update offset for features without valuesAndrzej Hunt
parse_feature_value() takes an offset, and uses it to seek past the point in features_list that we've already seen. However if the feature being searched for does not specify a value, the offset is not updated. Therefore if we call parse_feature_value() in a loop on a value-less feature, we'll keep on parsing the same feature over and over again. This usually isn't an issue: there's no point in using next_server_feature_value() to search for repeated instances of the same capability unless that capability typically specifies a value - but a broken server could send a response that omits the value for a feature even when we are expecting a value. Therefore we add an offset update calculation for the no-value case, which helps ensure that loops using next_server_feature_value() will always terminate. next_server_feature_value(), and the offset calculation, were first added in 2.28 in 2c6a403d96 (connect: add function to parse multiple v1 capability values, 2020-05-25). Thanks to Peff for authoring the test. Co-authored-by: Jeff King <peff@peff.net> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Andrzej Hunt <andrzej@ahunt.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-23difftool: fix symlink-file writing in dir-diff modeDavid Aguilar
The difftool dir-diff mode handles symlinks by replacing them with their readlink(2) values. This allows diff tools to see changes to symlinks as if they were regular text diffs with the old and new path values. This is analogous to what "git diff" displays when symlinks change. The temporary diff directories that are created initially contain symlinks because they get checked-out using a temporary index that retains the original symlinks as checked-in to the repository. A bug was introduced when difftool was rewritten in C that made difftool write the readlink(2) contents into the pointed-to file rather than the symlink itself. The write was going through the symlink and writing to its target rather than writing to the symlink path itself. Replace symlinks with raw text files by unlinking the symlink path before writing the readlink(2) content into them. When 18ec800512 (difftool: handle modified symlinks in dir-diff mode, 2017-03-15) added handling for modified symlinks this bug got recorded in the test suite. The tests included the pointed-to symlink target paths. These paths were being reported because difftool was erroneously writing to them, but they should have never been reported nor written. Correct the modified-symlinks test cases by removing the target files from the expected output. Add a test to ensure that symlinks are written with the readlink(2) values and that the target files contain their original content. Reported-by: Alan Blotz <work@blotz.org> Helped-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: David Aguilar <davvid@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-23http: match headers case-insensitively when redactingJeff King
When HTTP/2 is in use, we fail to correctly redact "Authorization" (and other) headers in our GIT_TRACE_CURL output. We get the headers in our CURLOPT_DEBUGFUNCTION callback, curl_trace(). It passes them along to curl_dump_header(), which in turn checks redact_sensitive_header(). We see the headers as a text buffer like: Host: ... Authorization: Basic ... After breaking it into lines, we match each header using skip_prefix(). This is case-sensitive, even though HTTP headers are case-insensitive. This has worked reliably in the past because these headers are generated by curl itself, which is predictable in what it sends. But when HTTP/2 is in use, instead we get a lower-case "authorization:" header, and we fail to match it. The fix is simple: we should match with skip_iprefix(). Testing is more complicated, though. We do have a test for the redacting feature, but we don't hit the problem case because our test Apache setup does not understand HTTP/2. You can reproduce the issue by applying this on top of the test change in this patch: diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index afa91e38b0..19267c7107 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -29,6 +29,9 @@ ErrorLog error.log LoadModule setenvif_module modules/mod_setenvif.so </IfModule> +LoadModule http2_module modules/mod_http2.so +Protocols h2c + <IfVersion < 2.4> LockFile accept.lock </IfVersion> @@ -64,8 +67,8 @@ LockFile accept.lock <IfModule !mod_access_compat.c> LoadModule access_compat_module modules/mod_access_compat.so </IfModule> -<IfModule !mod_mpm_prefork.c> - LoadModule mpm_prefork_module modules/mod_mpm_prefork.so +<IfModule !mod_mpm_event.c> + LoadModule mpm_event_module modules/mod_mpm_event.so </IfModule> <IfModule !mod_unixd.c> LoadModule unixd_module modules/mod_unixd.so diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh index 1c2a444ae7..ff74f0ae8a 100755 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@ -24,6 +24,10 @@ test_expect_success 'create http-accessible bare repository' ' git push public main:main ' +test_expect_success 'prefer http/2' ' + git config --global http.version HTTP/2 +' + setup_askpass_helper test_expect_success 'clone http repository' ' but this has a few issues: - it's not necessarily portable. The http2 apache module might not be available on all systems. Further, the http2 module isn't compatible with the prefork mpm, so we have to switch to something else. But we don't necessarily know what's available. It would be nice if we could have conditional config, but IfModule only tells us if a module is already loaded, not whether it is available at all. This might be a non-issue. The http tests are already optional, and modern-enough systems may just have both of these. But... - if we do this, then we'd no longer be testing HTTP/1.1 at all. I'm not sure how much that matters since it's all handled by curl under the hood, but I'd worry that some detail leaks through. We'd probably want two scripts running similar tests, one with HTTP/2 and one with HTTP/1.1. - speaking of which, a later test fails with the patch above! The problem is that it is making sure we used a chunked transfer-encoding by looking for that header in the trace. But HTTP/2 doesn't support that, as it has its own streaming mechanisms (the overall operation works fine; we just don't see the header in the trace). Furthermore, even with the changes above, this test still does not detect the current failure, because we see _both_ HTTP/1.1 and HTTP/2 requests, which confuse it. Quoting only the interesting bits from the resulting trace file, we first see: => Send header: GET /auth/smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 => Send header: Connection: Upgrade, HTTP2-Settings => Send header: Upgrade: h2c => Send header: HTTP2-Settings: AAMAAABkAAQCAAAAAAIAAAAA <= Recv header: HTTP/1.1 401 Unauthorized <= Recv header: Date: Wed, 22 Sep 2021 20:03:32 GMT <= Recv header: Server: Apache/2.4.49 (Debian) <= Recv header: WWW-Authenticate: Basic realm="git-auth" So the client asks for HTTP/2, but Apache does not do the upgrade for the 401 response. Then the client repeats with credentials: => Send header: GET /auth/smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 => Send header: Authorization: Basic <redacted> => Send header: Connection: Upgrade, HTTP2-Settings => Send header: Upgrade: h2c => Send header: HTTP2-Settings: AAMAAABkAAQCAAAAAAIAAAAA <= Recv header: HTTP/1.1 101 Switching Protocols <= Recv header: Upgrade: h2c <= Recv header: Connection: Upgrade <= Recv header: HTTP/2 200 <= Recv header: content-type: application/x-git-upload-pack-advertisement So the client does properly redact there, because we're speaking HTTP/1.1, and the server indicates it can do the upgrade. And then the client will make further requests using HTTP/2: => Send header: POST /auth/smart/repo.git/git-upload-pack HTTP/2 => Send header: authorization: Basic dXNlckBob3N0OnBhc3NAaG9zdA== => Send header: content-type: application/x-git-upload-pack-request And there we can see that the credential is _not_ redacted. This part of the test is what gets confused: # Ensure that there is no "Basic" followed by a base64 string, but that # the auth details are redacted ! grep "Authorization: Basic [0-9a-zA-Z+/]" trace && grep "Authorization: Basic <redacted>" trace The first grep does not match the un-redacted HTTP/2 header, because it insists on an uppercase "A". And the second one does find the HTTP/1.1 header. So as far as the test is concerned, everything is OK, but it failed to notice the un-redacted lines. We can make this test (and the other related ones) more robust by adding "-i" to grep case-insensitively. This isn't really doing anything for now, since we're not actually speaking HTTP/2, but it future-proofs the tests for a day when we do (either we add explicit HTTP/2 test support, or it's eventually enabled by default by our Apache+curl test setup). And it doesn't hurt in the meantime for the tests to be more careful. The change to use "grep -i", coupled with the changes to use HTTP/2 shown above, causes the test to fail with the current code, and pass after this patch is applied. And finally, there's one other way to demonstrate the issue (and how I actually found it originally). Looking at GIT_TRACE_CURL output against github.com, you'll see the unredacted output, even if you didn't set http.version. That's because setting it is only necessary for curl to send the extra headers in its HTTP/1.1 request that say "Hey, I speak HTTP/2; upgrade if you do, too". But for a production site speaking https, the server advertises via ALPN, a TLS extension, that it supports HTTP/2, and the client can immediately start using it. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-20clone: handle unborn branch in bare reposJeff King
When cloning a repository with an unborn HEAD, we'll set the local HEAD to match it only if the local repository is non-bare. This is inconsistent with all other combinations: remote HEAD | local repo | local HEAD ----------------------------------------------- points to commit | non-bare | same as remote points to commit | bare | same as remote unborn | non-bare | same as remote unborn | bare | local default So I don't think this is some clever or subtle behavior, but just a bug in 4f37d45706 (clone: respect remote unborn HEAD, 2021-02-05). And it's easy to see how we ended up there. Before that commit, the code to set up the HEAD for an empty repo was guarded by "if (!option_bare)". That's because the only thing it did was call install_branch_config(), and we don't want to do so for a bare repository (unborn HEAD or not). That commit put the handling of unborn HEADs into the same block, since those also need to call install_branch_config(). But the unborn case has an additional side effect of calling create_symref(), and we want that to happen whether we are bare or not. This patch just pulls all of the "figure out the default branch" code out of the "!option_bare" block. Only the actual config installation is kept there. Note that this does mean we might allocate "ref" and not use it (if the remote is empty but did not advertise an unborn HEAD). But that's not really a big deal since this isn't a hot code path, and it keeps the code simple. The alternative would be handling unborn_head_target separately, but that gets confusing since its memory ownership is tangled up with the "ref" variable. There's just one new test, for the case we're fixing. The other ones in the table are handled elsewhere (the unborn non-bare case just above, and the actually-born cases in t5601, t5606, and t5609, as they do not require v2's "unborn" protocol extension). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-17git-cvsserver: protect against NULL in crypt(3)Carlo Marcelo Arenas Belón
Some versions of crypt(3) will return NULL when passed an unsupported hash type (ex: OpenBSD with DES), so check for undef instead of using it directly. Also use this to probe the system and select a better hash function in the tests, so it can pass successfully. Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com> [jc: <CAPUEspjqD5zy8TLuFA96usU7FYi=0wF84y7NgOVFqegtxL9zbw@mail.gmail.com>] Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-16git-cvsserver: use crypt correctly to compare password hashesCarlo Marcelo Arenas Belón
c057bad370 (git-cvsserver: use a password file cvsserver pserver, 2010-05-15) adds a way for `git cvsserver` to provide authenticated pserver accounts without having clear text passwords, but uses the username instead of the password to the call for crypt(3). Correct that, and make sure the documentation correctly indicates how to obtain hashed passwords that could be used to populate this configuration, as well as correcting the hash that was used for the tests. This change will require that any user of this feature updates the hashes in their configuration, but has the advantage of using a more similar format than cvs uses, probably also easying any migration. Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-16t0000: avoid masking git exit value through pipesCarlo Marcelo Arenas Belón
9af0b8dbe2 (t0000-basic: more commit-tree tests., 2006-04-26) adds tests for commit-tree that mask the return exit from git as described in a378fee5b07 (Documentation: add shell guidelines, 2018-10-05). Fix the tests, to avoid pipes by using a temporary file instead. Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-15t1400: avoid SIGPIPE race condition on fifoJeff King
t1400.190 sometimes fails or even hangs because of the way it uses fifos. Our goal is to interactively read and write lines from update-ref, so we have two fifos, in and out. We open a descriptor connected to "in" and redirect output to that, so that update-ref does not see EOF as it would if we opened and closed it for each "echo" call. But we don't do the same for the output. This leads to a race where our "read response <out" has not yet opened the fifo, but update-ref tries to write to it and gets SIGPIPE. This can result in the test failing, or worse, hanging as we wait forever for somebody to write to the pipe. This is the same proble we fixed in 4783e7ea83 (t0008: avoid SIGPIPE race condition on fifo, 2013-07-12), and we can fix it the same way, by opening a second long-running descriptor. Before this patch, running: ./t1400-update-ref.sh --run=1,190 --stress failed or hung within a few dozen iterations. After it, I ran it for several hundred without problems. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-10am: fix incorrect exit status on am fail to abortElijah Newren
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-10t4151: add a few am --abort testsElijah Newren
Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-10stash: restore untracked files AFTER restoring tracked filesElijah Newren
If a user deletes a file and places a directory of untracked files there, then stashes all these changes, the untracked directory of files cannot be restored until after the corresponding file in the way is removed. So, restore changes to tracked files before restoring untracked files. There is no counterpart problem to worry about with the user deleting an untracked file and then add a tracked one in its place. Git does not track untracked files, and so will not know the untracked file was deleted, and thus won't be able to stash the removal of that file. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-10stash: avoid feeding directories to update-indexElijah Newren
When a file is removed from the cache, but there is a file of the same name present in the working directory, we would normally treat that file in the working directory as untracked. However, in the case of stash, doing that would prevent a simple 'git stash push', because the untracked file would be in the way of restoring the deleted file. git stash, however, blindly assumes that whatever is in the working directory for a deleted file is wanted and passes that path along to update-index. That causes problems when the working directory contains a directory with the same name as the deleted file. Add some code for this special case that will avoid passing directory names to update-index. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-10t3903: document a pair of directory/file bugsElijah Newren
There are three tests here, because the second bug is documented with two tests: a file -> directory change and a directory -> file change. The reason for the two tests is just to verify that both are indeed broken but that both will be fixed by the same simple change (which will be provided in a subsequent patch). Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-10t5562: use alarm() to interrupt timed child-waitJeff King
The t5562 script occasionally takes 60 extra seconds to complete due to a race condition in the invoke-with-content-length.pl helper. The way it's supposed to work is this: - we set up a SIGCLD handler - we kick off http-backend and write to it with a set content-length, but _don't_ close the pipe - we sleep for 60 seconds, assuming that SIGCLD from http-backend finishing will interrupt us - after the sleep finishes (whetherby 60 seconds or because it was interrupted by the signal), we check a flag to see if our SIGCLD handler was called. If not, then we complain. This usually completes immediately, because the signal interrupts our sleep. But very occasionally the child process dies _before_ we hit the sleep, so we don't realize it. The test still completes successfully (because our $exited flag is set), but it takes an extra 60 seconds. There's no way to check the flag and sleep atomically. So the best we can do with this approach is to sleep in smaller chunks (say, 1 second) and check the flag incrementally. Then we waste a maximum of 1 second if we lose the race. This was proposed in: https://lore.kernel.org/git/20190218205028.32486-1-max@max630.net/ and it does work. But we can do better. Instead of blocking on sleep and waiting for the child signal to interrupt us, we can block on the child exiting and set an alarm signal to trigger the timeout. This lets us exit the script immediately when the child behaves (with no race possible), and wait a maximum of 60 seconds when it doesn't. Note one small subtlety: perl is very willing to restart the waitpid() call after the alarm is delivered, even if we've thrown an exception via die. "perldoc -f alarm" claims you can get around this with an eval/die combo (and even has some example code), but it doesn't seem to work for me with waitpid(); instead, we continue waiting until the child exits. So instead, we'll instruct the child process to exit in the alarm handler itself. In the original code this was done by calling close($out). That would continue to work, since our child is always http-backend, which should exit when its stdin closes. But we can be even more robust against a hung or confused child by sending a KILL signal, which should terminate it immediately. Reported-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-07send-email: fix a "first config key wins" regression in v2.33.0Ævar Arnfjörð Bjarmason
Fix a regression in my c95e3a3f0b8 (send-email: move trivial config handling to Perl, 2021-05-28) where we'd pick the first config key out of multiple defined ones, instead of using the normal "last key wins" semantics of "git config --get". This broke e.g. cases where a .git/config would have a different sendemail.smtpServer than ~/.gitconfig. We'd pick the ~/.gitconfig over .git/config, instead of preferring the repository-local version. The same would go for /etc/gitconfig etc. The full list of impacted config keys (the %config_settings values which are references to scalars, not arrays) is: sendemail.smtpencryption sendemail.smtpserver sendemail.smtpserverport sendemail.smtpuser sendemail.smtppass sendemail.smtpdomain sendemail.smtpauth sendemail.smtpbatchsize sendemail.smtprelogindelay sendemail.tocmd sendemail.cccmd sendemail.aliasfiletype sendemail.envelopesender sendemail.confirm sendemail.from sendemail.assume8bitencoding sendemail.composeencoding sendemail.transferencoding sendemail.sendmailcmd I.e. having any of these set in say ~/.gitconfig and in-repo .git/config regressed in v2.33.0 to prefer the --global one over the --local. To test this add a test of config priority to one of these config variables, most don't have tests at all, but there was an existing one for sendemail.8bitEncoding. The "git config" (instead of "test_config") is somewhat of an anti-pattern, but follows established conventions in t9001-send-email.sh, likewise with any other pattern or idiom in this test. The populating of home/.gitconfig and setting of HOME= is copied from a test in t0017-env-helper.sh added in 1ff750b128e (tests: make GIT_TEST_GETTEXT_POISON a boolean, 2019-06-21). This test fails without this bugfix, but now it works. Reported-by: Eli Schwartz <eschwartz@archlinux.org> Tested-by: Eli Schwartz <eschwartz@archlinux.org> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-05apply: resolve trivial merge without hitting ll-merge with "--3way"Junio C Hamano
The ll_binary_merge() function assumes that the ancestor blob is different from either side of the new versions, and always fails the merge in conflict, unless -Xours or -Xtheirs is in effect. The normal "merge" machineries all resolve the trivial cases (e.g. if our side changed while their side did not, the result is ours) without triggering the file-level merge drivers, so the assumption is warranted. The code path in "git apply --3way", however, does not check for the trivial three-way merge situation and always calls the file-level merge drivers. This used to be perfectly OK back when we always first attempted a straight patch application and used the three-way code path only as a fallback. Any binary patch that can be applied as a trivial three-way merge (e.g. the patch is based exactly on the version we happen to have) would always cleanly apply, so the ll_binary_merge() that is not prepared to see the trivial case would not have to handle such a case. This no longer is true after we made "--3way" to mean "first try three-way and then fall back to straight application", and made "git apply -3" on a binary patch that is based on the current version no longer apply. Teach "git apply -3" to first check for the trivial merge cases and resolve them without hitting the file-level merge drivers. Signed-off-by: Jerry Zhang <jerry@skydio.com> [jc: stolen tests from Jerry's patch] Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-03update-ref: fix streaming of status updatesPatrick Steinhardt
When executing git-update-ref(1) with the `--stdin` flag, then the user can queue updates and, since e48cf33b61 (update-ref: implement interactive transaction handling, 2020-04-02), interactively drive the transaction's state via a set of transactional verbs. This interactivity is somewhat broken though: while the caller can use these verbs to drive the transaction's state, the status messages which confirm that a verb has been processed is not flushed. The caller may thus be left hanging waiting for the acknowledgement. Fix the bug by flushing stdout after writing the status update. Add a test which catches this bug. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-01upload-pack.c: treat want-ref relative to namespaceKim Altintop
When 'upload-pack' runs within the context of a git namespace, treat any 'want-ref' lines the client sends as relative to that namespace. Also check if the wanted ref is hidden via 'hideRefs'. If it is hidden, respond with an error as if the ref didn't exist. Helped-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Kim Altintop <kim@eagain.st> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-01t5730: introduce fetch command helperKim Altintop
Assembling a "raw" fetch command to be fed directly to "test-tool serve-v2" is extracted into a test helper. Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Kim Altintop <kim@eagain.st> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-31fast-export: fix anonymized tag using original lengthTal Kelrich
Commit 7f4075949686 (fast-export: tighten anonymize_mem() interface to handle only strings, 2020-06-23) changed the interface used in anonymizing strings, but failed to update the size of annotated tag messages to match the new anonymized string. As a result, exporting tags having messages longer than 13 characters would create output that couldn't be parsed by fast-import, as the data length indicated was larger than the data output. Reset the message size when anonymizing, and add a tag with a "long" message to the test. Signed-off-by: Tal Kelrich <hasturkun@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-30send-email: avoid incorrect header propagationMarvin Häuser
If multiple independent patches are sent with send-email, even if the "In-Reply-To" and "References" headers are not managed by --thread or --in-reply-to, their values may be propagated from prior patches to subsequent patches with no such headers defined. To mitigate this and potential future issues, make sure all global patch-specific variables are always either handled by command-specific code (e.g. threading), or are reset to their default values for every iteration. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Marvin Häuser <mhaeuser@posteo.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-30test-lib: set GIT_CEILING_DIRECTORIES to protect the surrounding repositorySZEDER Gábor
Every once in a while a test somehow manages to escape from its trash directory and modifies the surrounding repository, whether because of a bug in git itself, a bug in a test [1], or e.g. when trying to run tests with a shell that is, in general, unable to run our tests [2]. Set GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/.." as an additional safety measure to protect the surrounding repository at least from modifications by git commands executed in the tests (assuming that handling of ceiling directories during repository discovery is not broken, and, of course, it won't save us from regular shell commands, e.g. 'cd .. && rm -f ...'). [1] e.g. https://public-inbox.org/git/20210423051255.GD2947267@szeder.dev [2] $ git symbolic-ref HEAD refs/heads/master $ ksh ./t2011-checkout-invalid-head.sh [... a lot of "not ok" ...] $ git symbolic-ref HEAD refs/heads/other (In short: 'ksh' doesn't support the 'local' builtin command, which is used by 'test_oid', causing it to return with error whenever it's called, leaving ZERO_OID set to empty, so when the test 'checkout main from invalid HEAD' runs 'echo $ZERO_OID >.git/HEAD' it writes a corrupt (not invalid) HEAD, and subsequent git commands don't recognize the repository in the trash directory anymore, but operate on the surrounding repo.) Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-27branch: allow deleting dangling branches with --forceRené Scharfe
git branch only allows deleting branches that point to valid commits. Skip that check if --force is given, as the caller is indicating with it that they know what they are doing and accept the consequences. This allows deleting dangling branches, which previously had to be reset to a valid start-point using --force first. Reported-by: Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de> Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-27logmsg_reencode(): warn when iconv() failsJeff King
If the user asks for a pretty-printed commit to be converted (either explicitly with --encoding=foo, or implicitly because the commit is non-utf8 and we want to convert it), we pass it through iconv(). If that fails, we fall back to showing the input verbatim, but don't tell the user that the output may be bogus. Let's add a warning to do so, along with a mention in the documentation for --encoding. Two things to note about the implementation: - we could produce the warning closer to the call to iconv() in reencode_string_len(), which would let us relay the value of errno. But this is not actually very helpful. reencode_string_len() does not know we are operating on a commit, and indeed does not know that the caller won't produce an error of its own. And the errno values from iconv() are seldom helpful (iconv_open() only ever produces EINVAL; perhaps EILSEQ from iconv() might be illuminating, but it can also return EINVAL for incomplete sequences). - if the reason for the failure is that the output charset is not supported, then the user will see this warning for every commit we try to display. That might be ugly and overwhelming, but on the other hand it is making it clear that every one of them has not been converted (and the likely outcome anyway is to re-try the command with a supported output encoding). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-27checkout: make delayed checkout respect --quiet and --no-progressMatheus Tavares
The 'Filtering contents...' progress report from delayed checkout is displayed even when checkout and clone are invoked with --quiet or --no-progress. Furthermore, it is displayed unconditionally, without first checking whether stdout is a tty. Let's fix these issues and also add some regression tests for the two code paths that currently use delayed checkout: unpack_trees.c:check_updates() and builtin/checkout.c:checkout_worktree(). Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-26column: fix parsing of the '--nl' optionSZEDER Gábor
'git column's '--nl' option can be used to specify a "string to be printed at the end of each line" (quoting the man page), but this option and its mandatory argument has been parsed as OPT_INTEGER since the introduction of the command in 7e29b8254f (Add column layout skeleton and git-column, 2012-04-21). Consequently, any non-number argument is rejected by parse-options, and any number other than 0 leads to segfault: $ printf "%s\n" one two |git column --mode=plain --nl=foo error: option `nl' expects a numerical value $ printf "%s\n" one two |git column --mode=plain --nl=42 Segmentation fault (core dumped) $ printf "%s\n" one two |git column --mode=plain --nl=0 one two Parse this option as OPT_STRING. Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-25diff-lib: ignore paths that are outside $cwd if --relative askedĐoàn Trần Công Danh
For diff family commands, we can tell them to exclude changes outside of some directories if --relative is requested. In diff_unmerge(), NULL will be returned if the requested path is outside of the interesting directories, thus we'll run into NULL pointer dereference in run_diff_files when trying to dereference its return value. Checking for return value of diff_unmerge before dereferencing is not sufficient, though. Since, diff engine will try to work on such pathspec later. Let's not run diff on those unintesting entries, instead. As a side effect, by skipping like that, we can save some CPU cycles. Reported-by: Thomas De Zeeuw <thomas@slight.dev> Tested-by: Carlo Arenas <carenas@gmail.com> Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-25t6300: check for cat-file exit status codeĐoàn Trần Công Danh
In test_atom(), we're piping the output of cat-file to tail(1), thus, losing its exit status. Let's use a temporary file to preserve git exit status code. Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-25t6300: don't run cat-file on non-existent objectĐoàn Trần Công Danh
In t6300, some tests are guarded behind some prerequisites. Thus, objects created by those tests ain't available if those prerequisites are unsatistified. Attempting to run "cat-file" on those objects will run into failure. In fact, running t6300 in an environment without gpg(1), we'll see those warnings: fatal: Not a valid object name refs/tags/signed-empty fatal: Not a valid object name refs/tags/signed-short fatal: Not a valid object name refs/tags/signed-long Let's put those commands into the real tests, in order to: * skip their execution if prerequisites aren't satistified. * check their exit status code The expected value for objects with type: commit needs to be computed outside the test because we can't rely on "$3" there. Furthermore, to prevent the accidental usage of that computed expected value, BUG out on unknown object's type. Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-25t5323: drop mentions of "master"Jeff King
Commit 0696232390 (pack-redundant: fix crash when one packfile in repo, 2020-12-16) added one some new tests to t5323. At the time, the sub-repo we used was called "master". But in a parallel branch, this was switched to "main". When the latter branch was merged in 27d7c8599b (Merge branch 'js/default-branch-name-tests-final-stretch', 2021-01-25), some of those spots caused textual conflicts, but some (for tests that were far enough away from other changed code) were just semantic. The merge resolution fixed up most spots, but missed this one. Even though this did impact actual code, it turned out not to fail the tests. Running 'cd "$master_repo"' ended up staying in the same directory, running the test in the main trash repo instead of the sub-repo. But because the point of the test is checking behavior when there are no packfiles, it worked in either repo (since both are empty at this point in the script). Reported-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-24ls-remote: set packet_trace_identity(<name>)Ævar Arnfjörð Bjarmason
Set packet_trace_identity() for ls-remote. This replaces the generic "git" identity in GIT_TRACE_PACKET=<file> traces to "ls-remote", e.g.: [...] packet: upload-pack> version 2 [...] packet: upload-pack> agent=git/2.32.0-dev [...] packet: ls-remote< version 2 [...] packet: ls-remote< agent=git/2.32.0-dev Where in an "git ls-remote file://<path>" dialog ">" is the sender (or "to the server") and "<" is the recipient (or "received by the client"). Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-24maintenance: skip bootout/bootstrap when plist is registeredDerrick Stolee
On macOS, we use launchctl to manage the background maintenance schedule. This uses a set of .plist files to describe the schedule, but these files are also registered with 'launchctl bootstrap'. If multiple 'git maintenance start' commands run concurrently, then they can collide replacing these schedule files and registering them with launchctl. To avoid extra launchctl commands, do a check for the .plist files on disk and check if they are registered using 'launchctl list <name>'. This command will return with exit code 0 if it exists, or exit code 113 if it does not. We can test this behavior using the GIT_TEST_MAINT_SCHEDULER environment variable. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-24t9001: PATH must not use Windows-style pathsJohannes Sixt
On Windows, $(pwd) returns a drive-letter style path C:/foo, while $PWD contains a POSIX style /c/foo path. When we want to interpolate the current directory in the PATH variable, we must not use the C:/foo style, because the meaning of the colon is ambiguous. Use the POSIX style. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-24t5582: remove spurious 'cd "$D"' lineMickey Endito
The variable D is never defined in test t5582, more severely the test fails if D is defined by something outside the test suite, so remove this spurious line. Signed-off-by: Mickey Endito <mickey.endito.2323@protonmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-23rebase -r: fix merge -c with a merge strategyPhillip Wood
If a rebase is started with a --strategy option other than "ort" or "recursive" then "merge -c" does not allow the user to reword the commit message. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-23rebase -r: don't write .git/MERGE_MSG when fast-forwardingPhillip Wood
When fast-forwarding we do not create a new commit so .git/MERGE_MSG is not removed and can end up seeding the message of a commit made after the rebase has finished. Avoid writing .git/MERGE_MSG when we are fast-forwarding by writing the file after the fast-forward checks. Note that there are no changes to the fast-forward code, it is simply moved. Note that the way this change is implemented means we no longer write the author script when fast-forwarding either. I believe this is safe for the reasons below but it is a departure from what we do when fast-forwarding a non-merge commit. If we reword the merge then 'git commit --amend' will keep the authorship of the commit we're rewording as it ignores GIT_AUTHOR_* unless --reset-author is passed. It will also export the correct GIT_AUTHOR_* variables to any hooks and we already test the authorship of the reworded commit. If we are not rewording then we no longer call spilt_ident() which means we are no longer checking the commit author header looks sane. However this is what we already do when fast-forwarding non-merge commits in skip_unnecessary_picks() so I don't think we're breaking any promises by not checking the author here. Reported-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-23rebase -i: add another reword testPhillip Wood
None of the existing reword tests check that there are no uncommitted changes when the editor is opened. Reuse the editor script from the last commit to fix this omission. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-20rebase -r: make 'merge -c' behave like rewordPhillip Wood
If the user runs git log while rewording a commit it is confusing if sometimes we're amending the commit that's being reworded and at other times we're creating a new commit depending on whether we could fast-forward or not[1]. For this reason the reword command ensures that there are no uncommitted changes when rewording. The reword command also allows the user to edit the todo list while the rebase is paused. As 'merge -c' also rewords commits make it behave like reword and add a test. [1] https://lore.kernel.org/git/xmqqlfvu4be3.fsf@gitster-ct.c.googlers.com/T/#m133009cb91cf0917bcf667300f061178be56680a Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-18completion: bash: fix for suboptions with valueFelipe Contreras
We need to ignore options that don't start with -- as well. Depending on the value of COMP_WORDBREAKS the last word could be duplicated otherwise. Can be tested with: git merge -X diff-algorithm=<tab> Tested-by: David Aguilar <davvid@gmail.com> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-15commit: restore --edit when combined with --fixupJoel Klinghed
Recent changes to --fixup, adding amend suboption, caused the --edit flag to be ignored as use_editor was always set to zero. Restore edit_flag having higher priority than fixup_message when deciding the value of use_editor by moving the edit flag condition later in the method. Signed-off-by: Joel Klinghed <the_jk@spawned.biz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-13rebase --continue: remove .git/MERGE_MSGPhillip Wood
If the user skips the final commit by removing all the changes from the index and worktree with 'git restore' (or read-tree) and then runs 'git rebase --continue' .git/MERGE_MSG is left behind. This will seed the commit message the next time the user commits which is not what we want to happen. Reported-by: Victor Gambier <vgambier@excilys.com> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-13rebase --apply: restore some testsPhillip Wood
980b482d28 ("rebase tests: mark tests specific to the am-backend with --am", 2020-02-15) sought to prepare tests testing the "apply" backend in preparation for 2ac0d6273f ("rebase: change the default backend from "am" to "merge"", 2020-02-15). However some tests seem to have been missed leading to us testing the "merge" backend twice. This patch fixes some cases that I noticed while adding tests to these files, I have not audited all the other rebase test files. I've reworded a couple of the test descriptions to make it clear which backend they are testing. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-13t3403: fix commit authorshipPhillip Wood
Setting GIT_AUTHOR_* when committing with --amend will only change the author if we also pass --reset-author. This commit is used in some tests that ensure the author ident does not change when rebasing. Creating this commit without changing the authorship meant that the test would not catch regressions that caused rebase to discard the original authorship information. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-11Merge branch 'jn/log-m-does-not-imply-p'Junio C Hamano
Earlier "git log -m" was changed to always produce patch output, which would break existing scripts, which has been reverted. * jn/log-m-does-not-imply-p: Revert 'diff-merges: let "-m" imply "-p"'
2021-08-10connect, protocol: log negotiated protocol versionJosh Steadmon
It is useful for performance monitoring and debugging purposes to know the wire protocol used for remote operations. This may differ from the version set in local configuration due to differences in version and/or configuration between the server and the client. Therefore, log the negotiated wire protocol version via trace2, for both clients and servers. Signed-off-by: Josh Steadmon <steadmon@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-10apply: keep buffer/size pair in sync when parsing binary hunksJeff King
We parse through binary hunks by looping through the buffer with code like: llen = linelen(buffer, size); ...do something with the line... buffer += llen; size -= llen; However, before we enter the loop, there is one call that increments "buffer" but forgets to decrement "size". As a result, our "size" is off by the length of that line, and subsequent calls to linelen() may look past the end of the buffer for a newline. The fix is easy: we just need to decrement size as we do elsewhere. This bug goes all the way back to 0660626caf (binary diff: further updates., 2006-05-05). Presumably nobody noticed because it only triggers if the patch is corrupted, and even then we are often "saved" by luck. We use a strbuf to store the incoming patch, so we overallocate there, plus we add a 16-byte run of NULs as slop for memory comparisons. So if this happened accidentally, the common case is that we'd just read a few uninitialized bytes from the end of the strbuf before producing the expected "this patch is corrupted" error complaint. However, it is possible to carefully construct a case which reads off the end of the buffer. The included test does so. It will pass both before and after this patch when run normally, but using a tool like ASan shows that we get an out-of-bounds read before this patch, but not after. Reported-by: Xingman Chen <xichixingman@gmail.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-09Revert 'diff-merges: let "-m" imply "-p"'Jonathan Nieder
This reverts commit f5bfcc823ba242a46e20fb6f71c9fbf7ebb222fe, which made "git log -m" imply "--patch" by default. The logic was that "-m", which makes diff generation for merges perform a diff against each parent, has no use unless I am viewing the diff, so we could save the user some typing by turning on display of the resulting diff automatically. That wasn't expected to adversely affect scripts because scripts would either be using a command like "git diff-tree" that already emits diffs by default or would be combining -m with a diff generation option such as --name-status. By saving typing for interactive use without adversely affecting scripts in the wild, it would be a pure improvement. The problem is that although diff generation options are only relevant for the displayed diff, a script author can imagine them affecting path limiting. For example, I might run git log -w --format=%H -- README hoping to list commits that edited README, excluding whitespace-only changes. In fact, a whitespace-only change is not TREESAME so the use of -w here has no effect (since we don't apply these diff generation flags to the diff_options struct rev_info::pruning used for this purpose), but the documentation suggests that it should work Suppose you specified foo as the <paths>. We shall call commits that modify foo !TREESAME, and the rest TREESAME. (In a diff filtered for foo, they look different and equal, respectively.) and a script author who has not tested whitespace-only changes wouldn't notice. Similarly, a script author could include git log -m --first-parent --format=%H -- README to filter the first-parent history for commits that modified README. The -m is a no-op but it reflects the script author's intent. For example, until 1e20a407fe2 (stash list: stop passing "-m" to "git log", 2021-05-21), "git stash list" did this. As a result, we can't safely change "-m" to imply "-p" without fear of breaking such scripts. Restore the previous behavior. Noticed because Rust's src/bootstrap/bootstrap.py made use of this same construct: https://github.com/rust-lang/rust/pull/87513. That script has been updated to omit the unnecessary "-m" option, but we can expect other scripts in the wild to have similar expectations. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-08-06Merge branch 'cb/t7508-regexp-fix'Junio C Hamano
* cb/t7508-regexp-fix: t7508: avoid non POSIX BRE
2021-08-06Merge branch 'fc/disable-checkwinsize'Junio C Hamano
* fc/disable-checkwinsize: test: fix for COLUMNS and bash 5
2021-08-06test: fix for COLUMNS and bash 5Felipe Contreras
Since c49a177bec (test-lib.sh: set COLUMNS=80 for --verbose repeatability, 2021-06-29) multiple tests have been failing when using bash 5 because checkwinsize is enabled by default, therefore COLUMNS is reset using TIOCGWINSZ even for non-interactive shells. It's debatable whether or not bash should even be doing that, but for now we can avoid this undesirable behavior by disabling this option. Reported-by: Fabian Stelzer <fabian.stelzer@campoint.net> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> [jc: with SZEDER Gábor's suggestion to do this before setting COLUMNS] Signed-off-by: Junio C Hamano <gitster@pobox.com>