aboutsummaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)AuthorFilesLines
2024-06-12commit-graph: increment progress indicatorDerrick Stolee2-2/+2
This fixes a bug that was introduced by 368d19b0b7 (commit-graph: refactor compute_topological_levels(), 2023-03-20): Previously, the progress indicator was updated from `i + 1` where `i` is the loop variable of the enclosing `for` loop. After this patch, the update used `info->progress_cnt + 1` instead, however, unlike `i`, the `progress_cnt` attribute was not incremented. Let's increment it. Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> [jc: squashed in a test update from Patrick Steinhardt] Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-20commit-reach: add tips_reachable_from_bases()Derrick Stolee5-21/+219
Both 'git for-each-ref --merged=<X>' and 'git branch --merged=<X>' use the ref-filter machinery to select references or branches (respectively) that are reachable from a set of commits presented by one or more --merged arguments. This happens within reach_filter(), which uses the revision-walk machinery to walk history in a standard way. However, the commit-reach.c file is full of custom searches that are more efficient, especially for reachability queries that can terminate early when reachability is discovered. Add a new tips_reachable_from_bases() method to commit-reach.c and call it from within reach_filter() in ref-filter.c. This affects both 'git branch' and 'git for-each-ref' as tested in p1500-graph-walks.sh. For the Linux kernel repository, we take an already-fast algorithm and make it even faster: Test HEAD~1 HEAD ------------------------------------------------------------------- 1500.5: contains: git for-each-ref --merged 0.13 0.02 -84.6% 1500.6: contains: git branch --merged 0.14 0.02 -85.7% 1500.7: contains: git tag --merged 0.15 0.03 -80.0% (Note that we remove the iterative 'git rev-list' test from p1500 because it no longer makes sense as a comparison to 'git for-each-ref' and would just waste time running it for these comparisons.) The algorithm is implemented in commit-reach.c in the method tips_reachable_from_base(). This method takes a string_list of tips and assigns the 'util' for each item with the value 1 if the base commit can reach those tips. Like other reachability queries in commit-reach.c, the fastest way to search for "can A reach B?" is to do a depth-first search up to the generation number of B, preferring to explore first parents before later parents. While we must walk all reachable commits up to that generation number when the answer is "no", the depth-first search can answer "yes" much faster than other approaches in most cases. This search becomes trickier when there are multiple targets for the depth-first search. The commits with lower generation number are more likely to be within the history of the start commit, but we don't want to waste time searching commits of low generation number if the commit target with lowest generation number has already been found. The trick here is to take the input commits and sort them by generation number in ascending order. Track the index within this order as min_generation_index. When we find a commit, if its index in the list is equal to min_generation_index, then we can increase the generation number boundary of our search to the next-lowest value in the list. With this mechanism, the number of commits to search is minimized with respect to the depth-first search heuristic. We will walk all commits up to the minimum generation number of a commit that is _not_ reachable from the start, but we will walk only the necessary portion of the depth-first search for the reachable commits of lower generation. Add extra tests for this behavior in t6600-test-reach.sh as the interesting data shape of that repository can sometimes demonstrate corner case bugs. Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-20for-each-ref: add ahead-behind format atomDerrick Stolee11-1/+295
The previous change implemented the ahead_behind() method, including an algorithm to compute the ahead/behind values for a number of commit tips relative to a number of commit bases. Now, integrate that algorithm as part of 'git for-each-ref' hidden behind a new format atom, ahead-behind. This naturally extends to 'git branch' and 'git tag' builtins, as well. This format allows specifying multiple bases, if so desired, and all matching references are compared against all of those bases. For this reason, failing to read a reference provided from these atoms results in an error. In order to translate the ahead_behind() method information to the format output code in ref-filter.c, we must populate arrays of ahead_behind_count structs. In struct ref_array, we store the full array that will be passed to ahead_behind(). In struct ref_array_item, we store an array of pointers that point to the relvant items within the full array. In this way, we can pull all relevant ahead/behind values directly when formatting output for a specific item. It also ensures the lifetime of the ahead_behind_count structs matches the time that the array is being used. Add specific tests of the ahead/behind counts in t6600-test-reach.sh, as it has an interesting repository shape. In particular, its merging strategy and its use of different commit-graphs would demonstrate over- counting if the ahead_behind() method did not already account for that possibility. Also add tests for the specific for-each-ref, branch, and tag builtins. In the case of 'git tag', there are intersting cases that happen when some of the selected tips are not commits. This requires careful logic around commits_nr in the second loop of filter_ahead_behind(). Also, the test in t7004 is carefully located to avoid being dependent on the GPG prereq. It also avoids using the test_commit helper, as that will add ticks to the time and disrupt the expected timestamps in later tag tests. Also add performance tests in a new p1300-graph-walks.sh script. This will be useful for more uses in the future, but for now compare the ahead-behind counting algorithm in 'git for-each-ref' to the naive implementation by running 'git rev-list --count' processes for each input. For the Git source code repository, the improvement is already obvious: Test this tree --------------------------------------------------------------- 1500.2: ahead-behind counts: git for-each-ref 0.07(0.07+0.00) 1500.3: ahead-behind counts: git branch 0.07(0.06+0.00) 1500.4: ahead-behind counts: git tag 0.07(0.06+0.00) 1500.5: ahead-behind counts: git rev-list 1.32(1.04+0.27) But the standard performance benchmark is the Linux kernel repository, which demosntrates a significant improvement: Test this tree --------------------------------------------------------------- 1500.2: ahead-behind counts: git for-each-ref 0.27(0.24+0.02) 1500.3: ahead-behind counts: git branch 0.27(0.24+0.03) 1500.4: ahead-behind counts: git tag 0.28(0.27+0.01) 1500.5: ahead-behind counts: git rev-list 4.57(4.03+0.54) The 'git rev-list' test exists in this change as a demonstration, but it will be removed in the next change to avoid wasting time on this comparison. Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-20commit-reach: implement ahead_behind() logicDerrick Stolee2-0/+134
Fully implement the commit-counting logic required to determine ahead/behind counts for a batch of commit pairs. This is a new library method within commit-reach.h. This method will be linked to the for-each-ref builtin in the next change. The interface for ahead_behind() uses two arrays. The first array of commits contains the list of all starting points for the walk. This includes all tip commits _and_ base commits. The second array specifies base/tip pairs by pointing to commits within the first array, by index. The second array also stores the resulting ahead/behind counts for each of these pairs. This implementation of ahead_behind() allows multiple bases, if desired. Even with multiple bases, there is only one commit walk used for counting the ahead/behind values, saving time when the base/tip ranges overlap significantly. This interface for ahead_behind() also makes it very easy to call ensure_generations_valid() on the entire array of bases and tips. This call is necessary because it is critical that the walk that counts ahead/behind values never walks a commit more than once. Without generation numbers on every commit, there is a possibility that a commit date skew could cause the walk to revisit a commit and then double-count it. For this reason, it is strongly recommended that 'git ahead-behind' is only run in a repository with a commit-graph file that covers most of the reachable commits, storing precomputed generation numbers. If no commit-graph exists, this walk will be much slower as it must walk all reachable commits in ensure_generations_valid() before performing the counting logic. It is possible to detect if generation numbers are available at run time and redirect the implementation to another algorithm that does not require this property. However, that implementation requires a commit walk per base/tip pair _and_ can be slower due to the commit date heuristics required. Such an implementation could be considered in the future if there is a reason to include it, but most Git hosts should already be generating a commit-graph file as part of repository maintenance. Most Git clients should also be generating commit-graph files as part of background maintenance or automatic GCs. Now, let's discuss the ahead/behind counting algorithm. The first array of commits are considered the starting commits. The index within that array will play a critical role. We create a new commit slab that maps commits to a bitmap. For a given commit (anywhere in the history), its bitmap stores information relative to which of the input commits can reach that commit. The ith bit will be on if the ith commit from the starting list can reach that commit. It is important to notice that these bitmaps are not the typical "reachability bitmaps" that are stored in .bitmap files. Instead of signalling which objects are reachable from the current commit, they instead signal "which starting commits can reach me?" It is also important to know that the bitmap is not necessarily "complete" until we walk that commit. We will perform a commit walk by generation number in such a way that we can guarantee the bitmap is correct when we visit that commit. At the beginning of the ahead_behind() method, we initialize the bitmaps for each of the starting commits. By enabling the ith bit for the ith starting commit, we signal "the ith commit can reach itself." We walk commits by popping the commit with maximum generation number out of the queue, guaranteeing that we will never walk a child of that commit in any future steps. As we walk, we load the bitmap for the current commit and perform two main steps. The _second_ step examines each parent of the current commit and adds the current commit's bitmap bits to each parent's bitmap. (We create a new bitmap for the parent if this is our first time seeing that parent.) After adding the bits to the parent's bitmap, the parent is added to the walk queue. Due to this passing of bits to parents, the current commit has a guarantee that the ith bit is enabled on its bitmap if and only if the ith commit can reach the current commit. The first step of the walk is to examine the bitmask on the current commit and decide which ranges the commit is in or not. Due to the "bit pushing" in the second step, we have a guarantee that the ith bit of the current commit's bitmap is on if and only if the ith starting commit can reach it. For each ahead_behind_count struct, check the base_index and tip_index to see if those bits are enabled on the current bitmap. If exactly one bit is enabled, then increment the corresponding 'ahead' or 'behind' count. This increment is the reason we _absolutely need_ to walk commits at most once. The only subtle thing to do with this walk is to check to see if a parent has all bits on in its bitmap, in which case it becomes "stale" and is marked with the STALE bit. This allows queue_has_nonstale() to be the terminating condition of the walk, which greatly reduces the number of commits walked if all of the commits are nearby in history. It avoids walking a large number of common commits when there is a deep history. We also use the helper method insert_no_dup() to add commits to the priority queue without adding them multiple times. This uses the PARENT2 flag. Thus, we must clear both the STALE and PARENT2 bits of all commits, in case ahead_behind() is called multiple times in the same process. Co-authored-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-20commit-graph: introduce `ensure_generations_valid()`Taylor Blau2-0/+37
Use the just-introduced compute_reachable_generation_numbers_1() to implement a function which dynamically computes topological levels (or corrected commit dates) for out-of-graph commits. This will be useful for the ahead-behind algorithm we are about to introduce, which needs accurate topological levels on _all_ commits reachable from the tips in order to avoid over-counting. Co-authored-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-20commit-graph: return generation from memoryDerrick Stolee2-6/+4
The commit_graph_generation() method used to report a value of GENERATION_NUMBER_INFINITY if the commit_graph_data_slab had an instance for the given commit but the graph_pos indicated the commit was not in the commit-graph file. However, an upcoming change will introduce the ability to set generation values in-memory without writing the commit-graph file. Thus, we can no longer trust 'graph_pos' to indicate whether or not the generation member can be trusted. Instead, trust the 'generation' member if the commit has a value in the slab _and_ the 'generation' member is non-zero. Otherwise, treat it as GENERATION_NUMBER_INFINITY. This only makes a difference for a very old case for the commit-graph: the very first Git release to write commit-graph files wrote zeroes in the topological level positions. If we are parsing a commit-graph with all zeroes, those commits will now appear to have GENERATION_NUMBER_INFINITY (as if they were not parsed from the commit-graph). I attempted several variations to work around the need for providing an uninitialized 'generation' member, but this was the best one I found. It does require a change to a verification test in t5318 because it reports a different error than the one about non-zero generation numbers. Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-20commit-graph: simplify compute_generation_numbers()Derrick Stolee1-43/+21
The previous change introduced the generic algorithm compute_reachable_generation_numbers() and used it as the core functionality of compute_topological_levels(). Now, use it as the core functionality of compute_generation_numbers(). The main difference here is that we use generation version 2, which is used in to toggle the logic in compute_generation_from_max() for computing the corrected commit date based on the corrected commit dates of the parent commits (and the commit date of the current commit). It also uses different methods for (get|set)_generation in the vtable in order to store and access the value in the correct places. Co-authored-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-20commit-graph: refactor compute_topological_levels()Derrick Stolee1-23/+83
This patch extracts the common code used to compute topological levels and corrected committer dates into a common routine, compute_reachable_generation_numbers(). For ease of reading, it only modifies compute_topological_levels() to use this new routine, leaving compute_generation_numbers() to be modified in the next change. This new routine dispatches to call the necessary functions to get and set the generation number for a given commit through a vtable (the compute_generation_info struct). Computing the generation number itself is done in compute_generation_from_max(), which dispatches its implementation based on the generation version requested, or issuing a BUG() for unrecognized generation versions. This does not use a vtable because the logic depends only on the generation number version, not where the data is being loaded from or being stored to. This is a subtle point that will make more sense in a future change that modifies the in-memory generation values instead of just preparing values for writing to a commit-graph file. This change looks like it adds a lot of new code. However, two upcoming changes will be quite small due to the work being done in this change. Co-authored-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-20for-each-ref: explicitly test no matchesDerrick Stolee1-0/+13
The for-each-ref builtin can take a list of ref patterns, but if none match, it still succeeds (but with no output). Add an explicit test that demonstrates that behavior. Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-20for-each-ref: add --stdin optionDerrick Stolee3-2/+65
When a user wishes to input a large list of patterns to 'git for-each-ref' (likely a long list of exact refs) there are frequently system limits on the number of command-line arguments. Add a new --stdin option to instead read the patterns from standard input. Add tests that check that any unrecognized arguments are considered an error when --stdin is provided. Also, an empty pattern list is interpreted as the complete ref set. When reading from stdin, we populate the filter.name_patterns array dynamically as opposed to pointing to the 'argv' array directly. This is simple when using a strvec, as it is NULL-terminated in the same way. We then free the memory directly from the strvec. Helped-by: Phillip Wood <phillip.wood123@gmail.com> Signed-off-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-03-01Merge branch 'rs/range-diff-custom-abbrev-fix'Junio C Hamano1-1/+1
Hotfix for a topic that is already in 'master'. * rs/range-diff-custom-abbrev-fix: range-diff: avoid compiler warning when char is unsigned
2023-03-01Git 2.40-rc1v2.40.0-rc1Junio C Hamano1-1/+1
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-28A bit more before 2.40-rc1Junio C Hamano1-0/+9
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-28Merge branch 'ar/test-lib-remove-stale-comment'Junio C Hamano1-6/+0
Test library clean-up. * ar/test-lib-remove-stale-comment: test-lib: drop comment about test_description
2023-02-28Merge branch 'zy/t9700-style'Junio C Hamano1-31/+30
Test style fixes. * zy/t9700-style: t9700: modernize test scripts
2023-02-28Merge branch 'pw/rebase-i-parse-fix'Junio C Hamano5-18/+56
Fixes to code that parses the todo file used in "rebase -i". * pw/rebase-i-parse-fix: rebase -i: fix parsing of "fixup -C<commit>" rebase -i: match whole word in is_command()
2023-02-28Merge branch 'jk/http-test-fixes'Junio C Hamano5-114/+122
Various fix-ups on HTTP tests. * jk/http-test-fixes: t5559: make SSL/TLS the default t5559: fix test failures with LIB_HTTPD_SSL t/lib-httpd: enable HTTP/2 "h2" protocol, not just h2c t/lib-httpd: respect $HTTPD_PROTO in expect_askpass() t5551: drop curl trace lines without headers t5551: handle v2 protocol in cookie test t5551: simplify expected cookie file t5551: handle v2 protocol in upload-pack service test t5551: handle v2 protocol when checking curl trace t5551: stop forcing clone to run with v0 protocol t5551: handle HTTP/2 when checking curl trace t5551: lower-case headers in expected curl trace t5551: drop redundant grep for Accept-Language t5541: simplify and move "no empty path components" test t5541: stop marking "used receive-pack service" test as v0 only t5541: run "used receive-pack service" test earlier
2023-02-28range-diff: avoid compiler warning when char is unsignedRené Scharfe1-1/+1
Since 2b15969f61 (range-diff: let '--abbrev' option takes effect, 2023-02-20), GCC 11.3 on Ubuntu 22.04 on aarch64 warns (and errors out if the make variable DEVELOPER is set): range-diff.c: In function ‘output_pair_header’: range-diff.c:388:20: error: comparison is always false due to limited range of data type [-Werror=type-limits] 388 | if (abbrev < 0) | ^ cc1: all warnings being treated as errors That's because char is unsigned on that platform. Use int instead, just like in struct diff_options, to copy the value faithfully. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-27A bit more before 2.40-rc1Junio C Hamano1-0/+31
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-27Merge branch 'if/simplify-trace-setup'Junio C Hamano3-6/+5
Code clean-up. * if/simplify-trace-setup: trace.c, git.c: remove unnecessary parameter to trace_repo_setup()
2023-02-27Merge branch 'jc/countermand-format-attach'Junio C Hamano3-1/+22
The format.attach configuration variable lacked a way to override a value defined in a lower-priority configuration file (e.g. the system one) by redefining it in a higher-priority configuration file. Now, setting format.attach to an empty string means show the patch inline in the e-mail message, without using MIME attachment. This is a backward incompatible change. * jc/countermand-format-attach: format.attach: allow empty value to disable multi-part messages
2023-02-27Merge branch 'jk/shorten-unambiguous-ref-wo-sscanf'Junio C Hamano2-45/+82
sscanf(3) used in "git symbolic-ref --short" implementation found to be not working reliably on macOS in UTF-8 locales. Rewrite the code to avoid sscanf() altogether to work it around. * jk/shorten-unambiguous-ref-wo-sscanf: shorten_unambiguous_ref(): avoid sscanf() shorten_unambiguous_ref(): use NUM_REV_PARSE_RULES constant shorten_unambiguous_ref(): avoid integer truncation
2023-02-27Merge branch 'mh/credential-password-expiry'Junio C Hamano6-2/+125
The credential subsystem learned that a password may have an explicit expiration. * mh/credential-password-expiry: credential: new attribute password_expiry_utc
2023-02-27Merge branch 'rs/archive-mtime'Junio C Hamano4-0/+32
"git archive HEAD^{tree}" records the paths with the current timestamp in the archive, making it harder to obtain a stable output. The command learned the --mtime option to specify an arbitrary timestamp (e.g. --mtime="@0 +0000" for the epoch). * rs/archive-mtime: archive: add --mtime
2023-02-27Merge branch 'tb/drop-dir-iterator-follow-symlink-bit'Junio C Hamano4-74/+8
Remove leftover and unused code. * tb/drop-dir-iterator-follow-symlink-bit: t0066: drop setup of "dir5" dir-iterator: drop unused `DIR_ITERATOR_FOLLOW_SYMLINKS`
2023-02-27Merge branch 'tl/range-diff-custom-abbrev'Junio C Hamano2-4/+39
"git range-diff" learned --abbrev=<num> option. * tl/range-diff-custom-abbrev: range-diff: let '--abbrev' option takes effect
2023-02-27Merge branch 'ap/t2015-style-update'Junio C Hamano1-5/+6
Test clean-up. * ap/t2015-style-update: t2015-checkout-unborn.sh: changes the style for cd
2023-02-27Merge branch 'jc/diff-algo-attribute'Junio C Hamano6-25/+140
The "diff" drivers specified by the "diff" attribute attached to paths can now specify which algorithm (e.g. histogram) to use. * jc/diff-algo-attribute: diff: teach diff to read algorithm from diff driver diff: consolidate diff algorithm option parsing
2023-02-27Merge branch 'pw/rebase-i-validate-labels-early'Junio C Hamano2-1/+61
An invalid label or ref in the "rebase -i" todo file used to trigger an runtime error. SUch an error is now diagnosed while the todo file is parsed. * pw/rebase-i-validate-labels-early: rebase -i: check labels and refs when parsing todo list
2023-02-27test-lib: drop comment about test_descriptionAndrei Rybak1-6/+0
When a comment describing how each test file should start was added in commit [1], it was the second comment of t/test-lib.sh. The comment describes how variable "test_description" is supposed to be assigned at the top of each test file and how "test-lib.sh" should be used by sourcing it. However, even in [1], the comment was ten lines away from the usage of the variable by test-lib.sh. Since then, the comment has drifted away both from the top of the file and from the usage of the variable. The comment just sits in the middle of the initialization of the test library, surrounded by unrelated code, almost one hundred lines away from the usage of "test_description". Nobody has noticed this drift during evolution of test-lib.sh, which suggests that this comment has outlived its usefulness. The assignment of "test_description", sourcing of "test-lib.sh" by tests, and the process of writing tests in general are described in detail in "t/README". So drop the obsolete comment. An alternative solution could be to move the comment either to the top of the file, or down to the usage of variable "test_description". [1] e1970ce43a ("[PATCH 1/2] Test framework take two.", 2005-05-13) Signed-off-by: Andrei Rybak <rybak.a.v@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-25t9700: modernize test scriptsZhang Yi1-31/+30
The style of t9700-perl-git.sh is old. There are 3 problems: * A title is not on the same line with test_expect_success command. * A test body is indented by whitespaces. * There are whitespaces after redirect operators. Modernize test scripts by: * Combine the title with test_expect_success command. * Replace whitespace indents with TAB. * Delete whitespaces after redirect operators. Signed-off-by: Zhang Yi <18994118902@163.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-24A few more topics post 2.40-rc0Junio C Hamano1-0/+3
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-24Merge branch 'ps/free-island-marks'Junio C Hamano2-5/+23
Fix on a previous fix already in 'master'. * ps/free-island-marks: delta-islands: fix segfault when freeing island marks
2023-02-24Merge branch 'jk/http-proxy-tests'Junio C Hamano4-0/+65
Test updates. * jk/http-proxy-tests: add basic http proxy tests
2023-02-24Merge branch 'ma/fetch-parallel-use-online-cpus'Junio C Hamano2-0/+8
"git fetch --jobs=0" used to hit a BUG(), which has been corrected to use the available CPUs. * ma/fetch-parallel-use-online-cpus: fetch: choose a sensible default with --jobs=0 again
2023-02-24Git 2.40-rc0v2.40.0-rc0Junio C Hamano2-1/+15
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-24Merge branch 'jc/genzeros-avoid-raw-write'Junio C Hamano1-5/+6
A test helper had a single write(2) of 256kB, which was too big for some platforms (e.g. NonStop), which has been corrected by using xwrite() wrapper appropriately. * jc/genzeros-avoid-raw-write: test-genzeros: avoid raw write(2)
2023-02-24Merge branch 'rd/doc-default-date-format'Junio C Hamano1-5/+5
Update --date=default documentation. * rd/doc-default-date-format: rev-list: clarify git-log default date format
2023-02-24Merge branch 'js/gpg-errors'Junio C Hamano2-2/+50
Error messages given upon a signature verification failure used to discard the errors from underlying gpg program, which has been corrected. * js/gpg-errors: gpg: do show gpg's error message upon failure t7510: add a test case that does not need gpg
2023-02-24Merge branch 'rs/ctype-test'Junio C Hamano1-2/+28
Test safe_ctype * rs/ctype-test: test-ctype: test iscntrl, ispunct, isxdigit and isprint test-ctype: test islower and isupper test-ctype: test isascii
2023-02-23rebase -i: fix parsing of "fixup -C<commit>"Phillip Wood4-6/+42
If the user omits the space between "-C" and the commit in a fixup command then it is parsed as an ordinary fixup and the commit message is not updated as it should be. Fix this by making the space between "-C" and "<commit>" optional as it is for the "merge" command. Note that set_replace_editor() is changed to set $GIT_SEQUENCE_EDITOR instead of $EDITOR in order to be able to replace the todo list and reword commits with $FAKE_COMMIT_MESSAGE. This is safe as all the existing users are using set_replace_editor() to replace the todo list. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-23rebase -i: match whole word in is_command()Phillip Wood3-12/+14
When matching an unabbreviated command is_command() only does a prefix match which means it parses "pickled" as TODO_PICK. parse_insn_line() does error out because is_command() only advances as far as the end of "pick" so it looks like the command name is not followed by a space but the error message is "missing arguments for pick" rather than telling the user that the "pickled" is not a valid command. Fix this by ensuring the match is follow by whitespace or the end of the string as we already do for abbreviated commands. The (*bol = p) at the end of the condition is a bit cute for my taste but I decided to leave it be for now. Rather than add new tests the existing tests for bad commands are adapted to use a bad command name that triggers the prefix matching bug. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-23t5559: make SSL/TLS the defaultJeff King1-0/+1
The point of t5559 is run the regular t5551 tests with HTTP/2. But it does so with the "h2c" protocol, which uses cleartext upgrades from HTTP/1.1 to HTTP/2 (rather than learning about HTTP/2 support during the TLS negotiation). This has a few problems: - it's not very indicative of the real world. In practice, most servers that support HTTP/2 will also support TLS. - support for upgrading does not seem as robust. In particular, we've run into bugs in some versions of Apache's mod_http2 that trigger only with the upgrade mode. See: https://lore.kernel.org/git/Y8ztIqYgVCPILJlO@coredump.intra.peff.net/ So the upside is that this change makes our HTTP/2 tests more robust and more realistic. The downside is that if we can't set up SSL for any reason, we'll skip the tests (even though you _might_ have been able to run the HTTP/2 tests the old way). We could probably have a conditional fallback, but it would be complicated for little gain, and it's not even clear it would help (i.e., would any test environment even have HTTP/2 but not SSL support?). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-23t5559: fix test failures with LIB_HTTPD_SSLJeff King1-5/+18
One test needs to be tweaked in order for t5559 to pass with SSL/TLS set up. When we make our initial clone, we check that the curl trace of requests is what we expected. But we need to fix two things: - along with ignoring "data" lines from the trace, we need to ignore "SSL data" lines - when TLS is used, the server is able to tell the client (via ALPN) that it supports HTTP/2 before the first HTTP request is made. So rather than request an upgrade using an HTTP header, it can just speak HTTP/2 immediately With this patch, running: LIB_HTTPD_SSL=1 ./t5559-http-fetch-smart-http2.sh works, whereas it did not before. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-23t/lib-httpd: enable HTTP/2 "h2" protocol, not just h2cJeff King1-1/+1
Commit 73c49a4474 (t: run t5551 tests with both HTTP and HTTP/2, 2022-11-11) added Apache config to enable HTTP/2. However, it only enabled the "h2c" protocol, which allows cleartext HTTP/2 (generally based on an upgrade header during an HTTP/1.1 request). This is what t5559 is generally testing, since by default we don't set up SSL/TLS. However, it should be possible to run t5559 with LIB_HTTPD_SSL set. In that case, Apache will advertise support for HTTP/2 via ALPN during the TLS handshake. But we need to tell it support "h2" (the non-cleartext version) to do so. Without that, then curl does not even try to do the HTTP/1.1 upgrade (presumably because after seeing that we did TLS but didn't get the ALPN indicator, it assumes it would be fruitless). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-23t/lib-httpd: respect $HTTPD_PROTO in expect_askpass()Jeff King1-3/+3
When the HTTP tests are run with LIB_HTTPD_SSL in the environment, then we access the test server as https://. This causes expect_askpass to complain, because it tries to blindly match "http://" in the prompt shown to the user. We can adjust this to use $HTTPD_PROTO, which is set during the setup phase. Note that this is enough for t5551 and t5559 to pass when run with https, but there are similar problems in other scripts that will need to be fixed before the whole suite can run with LIB_HTTPD_SSL. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-23t5551: drop curl trace lines without headersJeff King1-1/+1
We pick apart a curl trace, looking for "=> Send header:" and so on, and matching against an expected set of requests and responses. We remove "== Info" lines entirely. However, our parser is fooled when running the test with LIB_HTTPD_SSL on Ubuntu 20.04 (as found in our linux-gcc CI job), as curl hands us an "Info" buffer with a newline, and we get: == Info: successfully set certificate verify locations: == Info: CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs => Send SSL data[...] which results in the "CApath" line ending up in the cleaned-up output, causing the test to fail. Arguably the tracing code should detect this and put it on two separate "== Info" lines. But this is actually a curl bug, fixed by their 80d73bcca (tls: provide the CApath verbose log on its own line, 2020-08-18). It's simpler to just work around it here. Since we are using GIT_TRACE_CURL, every line should just start with one of "<=", "==", or "=>", and we can throw away anything else. In fact, we can just replace the pattern for deleting "*" lines. Those were from the old GIT_CURL_VERBOSE output, but we switched over in 14e24114d9 (t5551-http-fetch-smart.sh: use the GIT_TRACE_CURL environment var, 2016-09-05). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-23t5551: handle v2 protocol in cookie testJeff King1-8/+11
After making a request, we check that it stored the expected cookies. This depends on the protocol version, because the cookies we store depend on the exact requests we made (and for ls-remote, v2 will always hit /git-upload-pack to get the refs, whereas v0 is happy with the initial ref advertisement). As a result, hardly anybody runs this test, as you'd have to manually set GIT_TEST_PROTOCOL_VERSION=0 to do so. Let's teach it to handle both protocol versions. One way to do this would be to make the expectation conditional on the protocol used. But there's a simpler solution. The reason that v0 doesn't hit /git-upload-pack is that ls-remote doesn't fetch any objects. If we instead do a fetch (making sure there's an actual object to grab), then both v0 and v2 will hit the same endpoints and set the same cookies. Note that we do have to clean up our new tag here; otherwise it confuses the later "clone 2,000 tags" test. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-23t5551: simplify expected cookie fileJeff King1-3/+2
After making an HTTP request that should store cookies, we check that the expected values are in the cookie file. We don't want to look at the whole file, because it has noisy comments at the top that we shouldn't depend on. But we strip out the interesting bits using "tail -3", which is brittle. It requires us to put an extra blank line in our expected output, and it would fail to notice any reordering or extra content in the cookie file. Instead, let's just grep for non-blank lines that are not comments, which more directly describes what we're interested in. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-23t5551: handle v2 protocol in upload-pack service testJeff King1-13/+3
We perform a clone and a fetch, and then check that we saw the expected requests in Apache's access log. In the v2 protocol, there will be one extra request to /git-upload-pack for each operation (since the initial /info/refs probe is just used to upgrade the protocol). As a result, this test is a noop unless the use of the v0 protocol is forced. Which means that hardly anybody runs it, since you have to do so manually. Let's update it to handle v2 and run it always. We could do this by just conditionally adding in the extra POST lines. But if we look at the origin of the test in 7da4e2280c (test smart http fetch and push, 2009-10-30), the point is really just to make sure that the smart git-upload-pack service was used at all. So rather than counting up the individual requests, let's just make sure we saw each of the expected types. This is a bit looser, but makes maintenance easier. Since we're now matching with grep, we can also loosen the HTTP/1.1 match, which allows this test to pass when run with HTTP/2 via t5559. That lets: GIT_TEST_PROTOCOL_VERSION=0 ./t5559-http-fetch-smart-http2.sh run to completion, which previously failed (and of course it works if you use v2, as well). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>