Alexandr Miloslavskiy [Mon, 17 Feb 2020 18:01:26 +0000 (18:01 +0000)]
mingw: workaround for hangs when sending STDIN
Explanation
-----------
The problem here is flawed `poll()` implementation. When it tries to
see if pipe can be written without blocking, it eventually calls
`NtQueryInformationFile()` and tests `WriteQuotaAvailable`. However,
the meaning of quota was misunderstood. The value of quota is reduced
when either some data was written to a pipe, *or* there is a pending
read on the pipe. Therefore, if there is a pending read of size >= than
the pipe's buffer size, poll() will think that pipe is not writable and
will hang forever, usually that means deadlocking both pipe users.
I have studied the problem and found that Windows pipes track two values:
`QuotaUsed` and `BytesInQueue`. The code in `poll()` apparently wants to
know `BytesInQueue` instead of quota. Unfortunately, `BytesInQueue` can
only be requested from read end of the pipe, while `poll()` receives
write end.
The git's implementation of `poll()` was copied from gnulib, which also
contains a flawed implementation up to today.
I also had a look at implementation in cygwin, which is also broken in a
subtle way. It uses this code in `pipe_data_available()`:
fpli.WriteQuotaAvailable = (fpli.OutboundQuota - fpli.ReadDataAvailable)
However, `ReadDataAvailable` always returns 0 for the write end of the pipe,
turning the code into an obfuscated version of returning pipe's total
buffer size, which I guess will in turn have `poll()` always say that pipe
is writable. The commit that introduced the code doesn't say anything about
this change, so it could be some debugging code that slipped in.
These are the typical sizes used in git:
0x2000 - default read size in `strbuf_read()`
0x1000 - default read size in CRT, used by `strbuf_getwholeline()`
0x2000 - pipe buffer size in compat\mingw.c
As a consequence, as soon as child process uses `strbuf_read()`,
`poll()` in parent process will hang forever, deadlocking both
processes.
This results in two observable behaviors:
1) If parent process begins sending STDIN quickly (and usually that's
the case), then first `poll()` will succeed and first block will go
through. MAX_IO_SIZE_DEFAULT is 8MB, so if STDIN exceeds 8MB, then
it will deadlock.
2) If parent process waits a little bit for any reason (including OS
scheduler) and child is first to issue `strbuf_read()`, then it will
deadlock immediately even on small STDINs.
The problem is illustrated by `git stash push`, which will currently
read the entire patch into memory and then send it to `git apply` via
STDIN. If patch exceeds 8MB, git hangs on Windows.
Possible solutions
------------------
1) Somehow obtain `BytesInQueue` instead of `QuotaUsed`
I did a pretty thorough search and didn't find any ways to obtain
the value from write end of the pipe.
2) Also give read end of the pipe to `poll()`
That can be done, but it will probably invite some dirty code,
because `poll()`
* can accept multiple pipes at once
* can accept things that are not pipes
* is expected to have a well known signature.
3) Make `poll()` always reply "writable" for write end of the pipe
Afterall it seems that cygwin (accidentally?) does that for years.
Also, it should be noted that `pump_io_round()` writes 8MB blocks,
completely ignoring the fact that pipe's buffer size is only 8KB,
which means that pipe gets clogged many times during that single
write. This may invite a deadlock, if child's STDERR/STDOUT gets
clogged while it's trying to deal with 8MB of STDIN. Such deadlocks
could be defeated with writing less than pipe's buffer size per
round, and always reading everything from STDOUT/STDERR before
starting next round. Therefore, making `poll()` always reply
"writable" shouldn't cause any new issues or block any future
solutions.
4) Increase the size of the pipe's buffer
The difference between `BytesInQueue` and `QuotaUsed` is the size
of pending reads. Therefore, if buffer is bigger than size of reads,
`poll()` won't hang so easily. However, I found that for example
`strbuf_read()` will get more and more hungry as it reads large inputs,
eventually surpassing any reasonable pipe buffer size.
Chosen solution
---------------
Make `poll()` always reply "writable" for write end of the pipe.
Hopefully one day someone will find a way to implement it properly.
Reproduction
------------
printf "%8388608s" X >large_file.txt
git stash push --include-untracked -- large_file.txt
I have decided not to include this as test to avoid slowing down the
test suite. I don't expect the specific problem to come back, and
chances are that `git stash push` will be reworked to avoid sending the
entire patch via STDIN.
Signed-off-by: Alexandr Miloslavskiy <redacted>
Signed-off-by: Junio C Hamano <redacted>
Junio C Hamano [Thu, 27 Feb 2020 16:10:20 +0000 (08:10 -0800)]
Documentation: clarify that `-h` alone stands for `help`
We seem to be getting new users who get confused every 20 months or
so with this "-h consistently wants to give help, but the commands
to which `-h` may feel like a good short-form option want it to mean
something else." compromise.
Let's make sure that the readers know that `git cmd -h` (with no
other arguments) is a way to get usage text, even for commands like
ls-remote and grep.
Also extend the description that is already in gitcli.txt, as it is
clear that users still get confused with the current text.
Signed-off-by: Junio C Hamano <redacted>
Elijah Newren [Thu, 27 Feb 2020 00:14:24 +0000 (00:14 +0000)]
t6020: new test with interleaved lexicographic ordering of directories
If a repository has two files:
foo/bar/baz
foo/bar-2/baz
then a simple lexicographic ordering of files and directories shows
...
foo/bar
foo/bar-2
foo/bar/baz
...
and the appearance of foo/bar-2 between foo/bar and foo/bar/baz can trip
up some codepaths. Add a test to catch such cases.
t6020 might be a slight misfit since this testcase does not test any
kind of file/directory conflict. However, it is similar in spirit to
some tests (4-6) already in t6020 that check cases where a *file* sorted
between a directory and the files underneath that directory. This
testcase differs in that now there is a *directory* that sorts in the
middle.
Although merge-recursive currently has no problems with this simple
testcase, I discovered that it's very possible to accidentally mess it
up. Further, we have no other merge or cherry-pick or rebase testcases
in the entire testsuite that cover such a case, so I felt like it would
be a worthwhile addition to the testsuite.
Signed-off-by: Elijah Newren <redacted>
Signed-off-by: Junio C Hamano <redacted>
Elijah Newren [Thu, 27 Feb 2020 00:14:23 +0000 (00:14 +0000)]
t6022, t6046: test expected behavior instead of testing a proxy for it
In t6022, we were testing for file being overwritten (or not) based on
an output message instead of checking for the file being overwritten.
Since we can check for the file being overwritten via mtime updates,
check that instead.
In t6046, we were largely checking for both the expected behavior and a
proxy for it, which is unnecessary. The calls to test-tool also were a
bit cryptic. Make them a little clearer.
Signed-off-by: Elijah Newren <redacted>
Signed-off-by: Junio C Hamano <redacted>
Elijah Newren [Thu, 27 Feb 2020 00:14:22 +0000 (00:14 +0000)]
t3035: prefer test_must_fail to bash negation for git commands
Signed-off-by: Elijah Newren <redacted>
Signed-off-by: Junio C Hamano <redacted>
Elijah Newren [Thu, 27 Feb 2020 00:14:21 +0000 (00:14 +0000)]
t6020, t6022, t6035: update merge tests to use test helper functions
Make use of test_path_is_file, test_write_lines, and similar helpers
in these old test files.
Signed-off-by: Elijah Newren <redacted>
Signed-off-by: Junio C Hamano <redacted>
Elijah Newren [Thu, 27 Feb 2020 00:14:20 +0000 (00:14 +0000)]
t602[1236], t6034: modernize test formatting
Indent code, and include it inside test_expect* blocks.
Signed-off-by: Elijah Newren <redacted>
Signed-off-by: Junio C Hamano <redacted>
Elijah Newren [Thu, 27 Feb 2020 00:05:05 +0000 (00:05 +0000)]
merge-recursive: apply collision handling unification to recursive case
In the en/merge-path-collision topic (see commit
ac193e0e0aa5, "Merge
branch 'en/merge-path-collision'", 2019-01-04), all the "file collision"
conflict types were modified for consistency. In particular,
rename/add, rename/rename(2to1) and each rename/add piece of a
rename/rename(1to2)/add[/add] conflict were made to behave like add/add
conflicts have always been handled.
However, this consistency was not enforced when opt->priv->call_depth >
0 for rename/rename conflicts. Update rename/rename(1to2) and
rename/rename(2to1) conflicts in the recursive case to also be
consistent. As an added bonus, this simplifies the code considerably.
Signed-off-by: Elijah Newren <redacted>
Signed-off-by: Junio C Hamano <redacted>
Johannes Schindelin [Thu, 27 Feb 2020 13:23:13 +0000 (13:23 +0000)]
Azure Pipeline: switch to the latest agent pools
It would seem that at least the `vs2015-win2012r2` pool (which we use
via its old name, `Hosted`) is about to be phased out. Let's switch
before that.
While at it, use the newer pool names as suggested at
https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops#use-a-microsoft-hosted-agent
Signed-off-by: Johannes Schindelin <redacted>
Signed-off-by: Junio C Hamano <redacted>
Johannes Schindelin [Thu, 27 Feb 2020 13:23:12 +0000 (13:23 +0000)]
ci: prevent `perforce` from being quarantined
The most recent Azure Pipelines macOS agents enable what Apple calls
"System Integrity Protection". This makes `p4d -V` hang: there is some
sort of GUI dialog waiting for the user to acknowledge that the copied
binaries are legit and may be executed, but on build agents, there is no
user who could acknowledge that.
Let's ask Homebrew specifically to _not_ quarantine the Perforce
binaries.
Helped-by: Aleksandr Chebotov
Signed-off-by: Johannes Schindelin <redacted>
Signed-off-by: Junio C Hamano <redacted>
Johannes Schindelin [Thu, 27 Feb 2020 13:23:11 +0000 (13:23 +0000)]
t/lib-httpd: avoid using macOS' sed
Among other differences relative to GNU sed, macOS' sed always ends its
output with a trailing newline, even if the input did not have such a
trailing newline.
Surprisingly, this makes three httpd-based tests fail on macOS: t5616,
t5702 and t5703. ("Surprisingly" because those tests have been around
for some time, but apparently nobody runs them on macOS with a working
Apache2 setup.)
The reason is that we use `sed` in those tests to filter the response of
the web server. Apart from the fact that we use GNU constructs (such as
using a space after the `c` command instead of a backslash and a
newline), we have another problem: macOS' sed LF-only newlines while
webservers are supposed to use CR/LF ones.
Even worse, t5616 uses `sed` to replace a binary part of the response
with a new binary part (kind of hoping that the replaced binary part
does not contain a 0x0a byte which would be interpreted as a newline).
To that end, it calls on Perl to read the binary pack file and
hex-encode it, then calls on `sed` to prefix every hex digit pair with a
`\x` in order to construct the text that the `c` statement of the `sed`
invocation is supposed to insert. So we call Perl and sed to construct a
sed statement. The final nail in the coffin is that macOS' sed does not
even interpret those `\x<hex>` constructs.
Let's just replace all of that by Perl snippets. With Perl, at least, we
do not have to deal with GNU vs macOS semantics, we do not have to worry
about unwanted trailing newlines, and we do not have to spawn commands
to construct arguments for other commands to be spawned (i.e. we can
avoid a whole lot of shell scripting complexity).
The upshot is that this fixes t5616, t5702 and t5703 on macOS with
Apache2.
Signed-off-by: Johannes Schindelin <redacted>
Signed-off-by: Junio C Hamano <redacted>
René Scharfe [Thu, 20 Feb 2020 18:49:18 +0000 (19:49 +0100)]
commit-graph: use progress title directly
merge_commit_graphs() copies the (translated) progress message into a
strbuf and passes the copy to start_delayed_progress() at each loop
iteration. The latter function takes a string pointer, so let's avoid
the detour and hand the string to it directly. That's shorter, simpler
and slightly more efficient.
Signed-off-by: René Scharfe <redacted>
Acked-by: Derrick Stolee <redacted>
Signed-off-by: Junio C Hamano <redacted>
Benno Evers [Wed, 26 Feb 2020 17:48:53 +0000 (18:48 +0100)]
describe: don't abort too early when searching tags
When searching the commit graph for tag candidates, `git-describe`
will stop as soon as there is only one active branch left and
it already found an annotated tag as a candidate.
This works well as long as all branches eventually connect back
to a common root, but if the tags are found across branches
with no common ancestor
B
o----.
\
o-----o---o----x
A
it can happen that the search on one branch terminates prematurely
because a tag was found on another, independent branch. This scenario
isn't quite as obscure as it sounds, since cloning with a limited
depth often introduces many independent "dead ends" into the commit
graph.
The help text of `git-describe` states pretty clearly that when
describing a commit D, the number appended to the emitted tag X should
correspond to the number of commits found by `git log X..D`.
Thus, this commit modifies the stopping condition to only abort
the search when only one branch is left to search *and* all current
best candidates are descendants from that branch.
For repositories with a single root, this condition is always
true: When the search is reduced to a single active branch, the
current commit must be an ancestor of *all* tag candidates. This
means that in the common case, this change will have no negative
performance impact since the same number of commits as before will
be traversed.
Signed-off-by: Benno Evers <redacted>
Signed-off-by: Junio C Hamano <redacted>
Alban Gruin [Tue, 21 Jan 2020 19:32:26 +0000 (20:32 +0100)]
builtin/rebase: remove a call to get_oid() on `options.switch_to'
When `options.switch_to' is set, `options.orig_head' is populated right
after with the object name the ref/commit argument points at.
Therefore, there is no need to parse `switch_to' again.
Signed-off-by: Alban Gruin <redacted>
Acked-by: Johannes Schindelin <redacted>
Signed-off-by: Junio C Hamano <redacted>
Junio C Hamano [Tue, 25 Feb 2020 19:17:41 +0000 (11:17 -0800)]
The seventh batch for 2.26
Signed-off-by: Junio C Hamano <redacted>
Junio C Hamano [Tue, 25 Feb 2020 19:18:32 +0000 (11:18 -0800)]
Merge branch 'es/doc-mentoring'
Doc for new contributors.
* es/doc-mentoring:
MyFirstContribution: rephrase contact info
MyFirstContribution: add avenues for getting help
Junio C Hamano [Tue, 25 Feb 2020 19:18:32 +0000 (11:18 -0800)]
Merge branch 'es/bright-colors'
The basic 7 colors learned the brighter counterparts
(e.g. "brightred").
* es/bright-colors:
color.c: alias RGB colors 8-15 to aixterm colors
color.c: support bright aixterm colors
color.c: refactor color_output arguments
Junio C Hamano [Tue, 25 Feb 2020 19:18:32 +0000 (11:18 -0800)]
Merge branch 'bw/remote-rename-update-config'
"git remote rename X Y" needs to adjust configuration variables
(e.g. branch.<name>.remote) whose value used to be X to Y.
branch.<name>.pushRemote is now also updated.
* bw/remote-rename-update-config:
remote rename/remove: gently handle remote.pushDefault config
config: provide access to the current line number
remote rename/remove: handle branch.<name>.pushRemote config values
remote: clean-up config callback
remote: clean-up by returning early to avoid one indentation
pull --rebase/remote rename: document and honor single-letter abbreviations rebase types
Emily Shaffer [Fri, 21 Feb 2020 03:10:27 +0000 (19:10 -0800)]
clone: pass --single-branch during --recurse-submodules
Previously, performing "git clone --recurse-submodules --single-branch"
resulted in submodules cloning all branches even though the superproject
cloned only one branch. Pipe --single-branch through the submodule
helper framework to make it to 'clone' later on.
Signed-off-by: Emily Shaffer <redacted>
Acked-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Emily Shaffer [Fri, 21 Feb 2020 03:10:26 +0000 (19:10 -0800)]
submodule--helper: use C99 named initializer
Start using a named initializer list for SUBMODULE_UPDATE_CLONE_INIT, as
the struct is becoming cumbersome for a typical struct initializer list.
Signed-off-by: Emily Shaffer <redacted>
Acked-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Abhishek Kumar [Mon, 24 Feb 2020 13:38:14 +0000 (19:08 +0530)]
lib-log-graph: consolidate colored graph cmp logic
Signed-off-by: Abhishek Kumar <redacted>
Signed-off-by: Junio C Hamano <redacted>
Abhishek Kumar [Mon, 24 Feb 2020 13:38:13 +0000 (19:08 +0530)]
lib-log-graph: consolidate test_cmp_graph logic
Log graph comparision logic is duplicated many times in:
- t3430-rebase-merges.sh
- t4202-log.sh
- t4214-log-graph-octopus.sh
- t4215-log-skewed-merges.sh
Consolidate the core of the comparision and sanitization logic in
lib-log-graph, and use it to replace the existing tests.
While at it, lose the singular/plural transition magic from the
sanitize_output helper, which was necessary around
7f814632 ("Use
correct grammar in diffstat summary line", 2012-02-01), that has
long outlived its usefulness.
Signed-off-by: Abhishek Kumar <redacted>
Signed-off-by: Junio C Hamano <redacted>
Eric Sunshine [Mon, 24 Feb 2020 09:08:48 +0000 (04:08 -0500)]
worktree: don't allow "add" validation to be fooled by suffix matching
"git worktree add <path>" performs various checks before approving
<path> as a valid location for the new worktree. Aside from ensuring
that <path> does not already exist, one of the questions it asks is
whether <path> is already a registered worktree. To perform this check,
it queries find_worktree() and disallows the "add" operation if
find_worktree() finds a match for <path>. As a convenience, however,
find_worktree() casts an overly wide net to allow users to identify
worktrees by shorthand in order to keep typing to a minimum. For
instance, it performs suffix matching which, given subtrees "foo/bar"
and "foo/baz", can correctly select the latter when asked only for
"baz".
"add" validation knows the exact path it is interrogating, so this sort
of heuristic-based matching is, at best, questionable for this use-case
and, at worst, may may accidentally interpret <path> as matching an
existing worktree and incorrectly report it as already registered even
when it isn't. (In fact, validate_worktree_add() already contains a
special case to avoid accidentally matching against the main worktree,
precisely due to this problem.)
Avoid the problem of potential accidental matching against an existing
worktree by instead taking advantage of find_worktree_by_path() which
matches paths deterministically, without applying any sort of magic
shorthand matching performed by find_worktree().
Reported-by: Cameron Gunnin <redacted>
Signed-off-by: Eric Sunshine <redacted>
Signed-off-by: Junio C Hamano <redacted>
Eric Sunshine [Mon, 24 Feb 2020 09:08:47 +0000 (04:08 -0500)]
worktree: add utility to find worktree by pathname
find_worktree() employs heuristics to match user provided input -- which
may be a pathname or some sort of shorthand -- with an actual worktree.
Although this convenience allows a user to identify a worktree with
minimal typing, the black-box nature of these heuristics makes it
potentially difficult for callers which already know the exact path of a
worktree to be confident that the correct worktree will be returned for
any specific pathname (particularly a relative one), especially as the
heuristics are enhanced and updated.
Therefore, add a companion function, find_worktree_by_path(), which
deterministically identifies a worktree strictly by pathname with no
interpretation and no magic matching.
Signed-off-by: Eric Sunshine <redacted>
Signed-off-by: Junio C Hamano <redacted>
Eric Sunshine [Mon, 24 Feb 2020 09:08:46 +0000 (04:08 -0500)]
worktree: improve find_worktree() documentation
Do a better job of explaining that find_worktree()'s main purpose is to
locate a worktree based upon input from a user which may be some sort of
shorthand for identifying a worktree rather than an actual path. For
instance, one shorthand a user can use to identify a worktree is by
unique path suffix (i.e. given worktrees at paths "foo/bar" and
"foo/baz", the latter can be identified simply as "baz"). The actual
heuristics find_worktree() uses to select a worktree may be expanded in
the future (for instance, one day it may allow worktree selection by
<id> of the .git/worktrees/<id>/ administrative directory), thus the
documentation does not provide a precise description of how matching is
performed, instead leaving it open-ended to allow for future
enhancement.
While at it, drop mention of the non-NULL requirement of `prefix` since
NULL has long been allowed. For instance, prefix_filename() has
explicitly allowed NULL since
116fb64e43 (prefix_filename: drop length
parameter, 2017-03-20), and find_worktree() itself since
e4da43b1f0
(prefix_filename: return newly allocated string, 2017-03-20).
Signed-off-by: Eric Sunshine <redacted>
Signed-off-by: Junio C Hamano <redacted>
Jeff King [Mon, 24 Feb 2020 04:37:54 +0000 (23:37 -0500)]
packfile: drop nth_packed_object_sha1()
Once upon a time, nth_packed_object_sha1() was the primary way to get
the oid of a packfile's index position. But these days we have the more
type-safe nth_packed_object_id() wrapper, and all callers have been
converted.
Let's drop the "sha1" version (turning the safer wrapper into a single
function) so that nobody is tempted to introduce new callers.
Signed-off-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Jeff King [Mon, 24 Feb 2020 04:37:31 +0000 (23:37 -0500)]
packed_object_info(): use object_id internally for delta base
The previous commit changed the public interface of packed_object_info()
to return a struct object_id rather than a bare hash. That enables us to
convert our internal helper, as well. We can use nth_packed_object_id()
directly for OFS_DELTA, but we'll still have to use oidread() to pull
the hash for a REF_DELTA out of the packfile.
There should be no additional cost, since we're copying directly into
the object_id the caller provided us (just as we did before; it's just
happening now via nth_packed_object_id()).
Signed-off-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Jeff King [Mon, 24 Feb 2020 04:36:56 +0000 (23:36 -0500)]
packed_object_info(): use object_id for returning delta base
If a caller sets the object_info.delta_base_sha1 to a non-NULL pointer,
we'll write the oid of the object's delta base to it. But we can
increase our type safety by switching this to a real object_id struct.
All of our callers are just pointing into the hash member of an
object_id anyway, so there's no inconvenience.
Note that we do still keep it as a pointer-to-struct, because the NULL
sentinel value tells us whether the caller is even interested in the
information.
Signed-off-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Jeff King [Mon, 24 Feb 2020 04:36:31 +0000 (23:36 -0500)]
pack-check: push oid lookup into loop
When we're checking a pack with fsck or verify-pack, we first sort the
idx entries by offset, since accessing them in pack order is more
efficient. To do so, we loop over them and fill in an array of structs
with the offset, object_id, and index position of each, sort the result,
and only then do we iterate over the sorted array and process each
entry.
In order to avoid the memory cost of storing the hash of each object, we
just store a pointer into the copy in the mmap'd pack index file. To
keep that property even as the rest of the code converted to "struct
object_id", commit
9fd750461b (Convert the verify_pack callback to
struct object_id, 2017-05-06) introduced a union in order to type-pun
the pointer-to-hash into an object_id struct.
But we can make this even simpler by observing that the sort operation
doesn't need the object id at all! We only need them one at a time while
we actually process each entry. So we can just omit the oid from the
struct entirely and load it on the fly into a local variable in the
second loop.
This gets rid of the type-punning, and lets us directly use the more
type-safe nth_packed_object_id(), simplifying the code. And as a bonus,
it saves 8 bytes of memory per object.
Note that this does mean we'll do the offset lookup for each object
before the oid lookup. The oid lookup has more safety checks in it
(e.g., for looking past p->num_objects) which in theory protected the
offset lookup. But since violating those checks was already a BUG()
condition (as described in the previous commit), it's not worth worrying
about.
Signed-off-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Jeff King [Mon, 24 Feb 2020 04:33:18 +0000 (23:33 -0500)]
pack-check: convert "internal error" die to a BUG()
If we fail to load the oid from the index of a packfile, we'll die()
with an "internal error". But this should never happen: we'd fail here
only if the idx needed to be lazily opened (but we've already opened it)
or if we asked for an out-of-range index (but we're iterating using the
same count that we'd check the range against). A corrupted index might
have a bogus count (e.g., too large for its size), but we'd have
complained and aborted already when opening the index initially.
While we're here, we can add a few details so that if this bug ever
_does_ trigger, we'll have a bit more information.
Signed-off-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Jeff King [Mon, 24 Feb 2020 04:32:27 +0000 (23:32 -0500)]
pack-bitmap: use object_id when loading on-disk bitmaps
A pack bitmap file contains the index position of the commit for each
bitmap, which we then translate into an object id via
nth_packed_object_sha1(). In preparation for that function going away,
we can switch to the more type-safe nth_packed_object_id().
Note that even though the result ends up in an object_id this does incur
an extra copy of the hash (into our temporary object_id, and then into
the final malloc'd stored_bitmap struct). This shouldn't make any
measurable difference. If it did, we could avoid this copy _and_ the
copy of the rest of the items by allocating the stored_bitmap struct
beforehand and reading directly into it from the bitmap file. Or better
still, if this is a bottleneck, we could introduce an on-disk index to
the bitmap file so we don't have to read every single entry to use just
one of them. So it's not worth worrying about micro-optimizing out this
one hash copy.
Signed-off-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Jeff King [Mon, 24 Feb 2020 04:31:22 +0000 (23:31 -0500)]
pack-objects: use object_id struct in pack-reuse code
When the pack-reuse code is dumping an OFS_DELTA entry to a client that
doesn't support it, we re-write it as a REF_DELTA. To do so, we use
nth_packed_object_sha1() to get the oid, but that function is soon going
away in favor of the more type-safe nth_packed_object_id(). Let's switch
now in preparation.
Note that this does incur an extra hash copy (from the pack idx mmap to
the object_id and then to the output, rather than straight from mmap to
the output). But this is not worth worrying about. It's probably not
measurable even when it triggers, and this is fallback code that we
expect to trigger very rarely (since everybody supports OFS_DELTA these
days anyway).
Signed-off-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Jeff King [Mon, 24 Feb 2020 04:30:07 +0000 (23:30 -0500)]
pack-objects: convert oe_set_delta_ext() to use object_id
We already store an object_id internally, and now our sole caller also
has one. Let's stop passing around the internal hash array, which adds a
bit of type safety.
Signed-off-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Jeff King [Mon, 24 Feb 2020 04:29:44 +0000 (23:29 -0500)]
pack-objects: read delta base oid into object_id struct
When we're considering reusing an on-disk delta, we get the oid of the
base as a pointer to unsigned char bytes of the hash, either into the
packfile itself (for REF_DELTA) or into the pack idx (using the revindex
to convert the offset into an index entry).
Instead, we'd prefer to use a more type-safe object_id as much as
possible. We can get the pack idx using nth_packed_object_id() instead.
For the packfile bytes, we can copy them out using oidread().
This doesn't even incur an extra copy overall, since the next thing we'd
always do with that pointer is pass it to can_reuse_delta(), which needs
an object_id anyway (and called oidread() itself). So this patch also
converts that function to take the object_id directly.
Note that we did previously use NULL as a sentinel value when the object
isn't a delta. We could probably get away with using the null oid for
this, but instead we'll use an explicit boolean flag, which should make
things more obvious for people reading the code later.
Signed-off-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Jeff King [Mon, 24 Feb 2020 04:27:36 +0000 (23:27 -0500)]
nth_packed_object_oid(): use customary integer return
Our nth_packed_object_sha1() function returns NULL for error. So when we
wrapped it with nth_packed_object_oid(), we kept the same semantics. But
it's a bit funny, because the caller actually passes in an out
parameter, and the pointer we return is just that same struct they
passed to us (or NULL).
It's not too terrible, but it does make the interface a little
non-idiomatic. Let's switch to our usual "0 for success, negative for
error" return value. Most callers either don't check it, or are
trivially converted. The one that requires the biggest change is
actually improved, as we can ditch an extra aliased pointer variable.
Since we are changing the interface in a subtle way that the compiler
wouldn't catch, let's also change the name to catch any topics in
flight. We can drop the 'o' and make it nth_packed_object_id(). That's
slightly shorter, but also less redundant since the 'o' stands for
"object" already.
Signed-off-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Eric Sunshine [Mon, 24 Feb 2020 01:59:35 +0000 (20:59 -0500)]
worktree: drop unused code from get_main_worktree()
This code has been unused since
fa099d2322 (worktree.c: kill parse_ref()
in favor of refs_resolve_ref_unsafe(), 2017-04-24), so drop it.
Signed-off-by: Eric Sunshine <redacted>
Signed-off-by: Junio C Hamano <redacted>
René Scharfe [Sun, 23 Feb 2020 16:56:31 +0000 (17:56 +0100)]
blame: provide type of fingerprints pointer
The fingerprints member of struct blame_origin is a void pointer that is
only ever used to reference objects of type struct fingerprint. Declare
its type to allow the compiler to do type checks. We can keep its type
opaque in blame.h, though -- only functions in blame.c need to know the
actual definition of struct fingerprint.
Signed-off-by: René Scharfe <redacted>
Reviewed-by: Barret Rhoden <redacted>
Signed-off-by: Junio C Hamano <redacted>
Eric Sunshine [Sun, 23 Feb 2020 10:14:07 +0000 (05:14 -0500)]
rebase: refuse to switch to branch already checked out elsewhere
The invocation "git rebase <upstream> <branch>" switches to <branch>
before performing the rebase operation. However, unlike git-switch,
git-checkout, and git-worktree which all refuse to switch to a branch
that is already checked out in some other worktree, git-rebase switches
to <branch> unconditionally. Curb this careless behavior by making
git-rebase also refuse to switch to a branch checked out elsewhere.
Reported-by: Mike Hommey <redacted>
Signed-off-by: Eric Sunshine <redacted>
Signed-off-by: Junio C Hamano <redacted>
Eric Sunshine [Sun, 23 Feb 2020 10:14:06 +0000 (05:14 -0500)]
t3400: make test clean up after itself
This test intentionally creates a file which causes rebase to fail, thus
it is important that this file be deleted before subsequent tests are
run which are not expecting such a failure. In the past, the common way
to ensure cleanup (regardless of whether the test succeeded or failed)
was either for the next test to perform the previous test's cleanup as
its first step or to do the cleanup at global scope outside of any
tests. With the introduction of 'test_when_finished', however, tests can
be responsible for their own cleanup. Therefore, update this test to
clean up after itself.
A bit of history: This 'rm' invocation was moved from within the body of
the following test to global scope by
bffd750adf (rebase: improve error
message when upstream argument is missing, 2010-05-31), which postdates,
by about a month, introduction of 'test_when_finished' in
3bf7886705
(test-lib: Let tests specify commands to be run at end of test,
2010-05-02).
Signed-off-by: Eric Sunshine <redacted>
Signed-off-by: Junio C Hamano <redacted>
Martin Ågren [Sun, 23 Feb 2020 08:48:36 +0000 (09:48 +0100)]
t: drop debug `cat` calls
We `cat` files, but don't inspect or grab the contents in any way.
Unlike in an earlier commit, there is no reason to suspect that these
files could be missing, so `cat`-ing them is just wasted effort.
Signed-off-by: Martin Ågren <redacted>
Signed-off-by: Junio C Hamano <redacted>
Martin Ågren [Sun, 23 Feb 2020 08:48:35 +0000 (09:48 +0100)]
t9810: drop debug `cat` call
We `cat` kwdelfile.c, but don't inspect or grab the contents in any way.
This looks like a remnant from a debug session. Similar to the previous
commit, one could argue that `cat`-ing the file verifies that it didn't
disappear somehow. But because the very next thing we do after `cat`-ing
the file is to `grep` in it, we can safely drop the call to `cat`.
Signed-off-by: Martin Ågren <redacted>
Signed-off-by: Junio C Hamano <redacted>
Martin Ågren [Sun, 23 Feb 2020 08:48:34 +0000 (09:48 +0100)]
t4117: check for files using `test_path_is_file`
We `cat` files, but don't inspect or grab the contents in any way. These
`cat` calls look like remnants from a debug session, so it's tempting to
get rid of them. But they do actually verify that the files exist, which
might not necessarily be the case for some failure modes of `git apply
--reject`. Let's not lose that.
Convert the `cat` calls to use `test_path_is_file` instead. This is of
course still a minor change since we no longer verify that the files can
be opened for reading, but that is not something we usually worry about.
Signed-off-by: Martin Ågren <redacted>
Signed-off-by: Junio C Hamano <redacted>
Hariom Verma [Sun, 23 Feb 2020 18:57:10 +0000 (18:57 +0000)]
receive.denyCurrentBranch: respect all worktrees
The receive.denyCurrentBranch config option controls what happens if
you push to a branch that is checked out into a non-bare repository.
By default, it rejects it. It can be disabled via `ignore` or `warn`.
Another yet trickier option is `updateInstead`.
However, this setting was forgotten when the git worktree command was
introduced: only the main worktree's current branch is respected.
With this change, all worktrees are respected.
That change also leads to revealing another bug,
i.e. `receive.denyCurrentBranch = true` was ignored when pushing into a
non-bare repository's unborn current branch using ref namespaces. As
`is_ref_checked_out()` returns 0 which means `receive-pack` does not get
into conditional statement to switch `deny_current_branch` accordingly
(ignore, warn, refuse, unconfigured, updateInstead).
receive.denyCurrentBranch uses the function `refs_resolve_ref_unsafe()`
(called via `resolve_refdup()`) to resolve the symbolic ref HEAD, but
that function fails when HEAD does not point at a valid commit.
As we replace the call to `refs_resolve_ref_unsafe()` with
`find_shared_symref()`, which has no problem finding the worktree for a
given branch even if it is unborn yet, this bug is fixed at the same
time: receive.denyCurrentBranch now also handles worktrees with unborn
branches as intended even while using ref namespaces.
Helped-by: Johannes Schindelin <redacted>
Signed-off-by: Hariom Verma <redacted>
Signed-off-by: Junio C Hamano <redacted>
Hariom Verma [Sun, 23 Feb 2020 18:57:09 +0000 (18:57 +0000)]
t5509: use a bare repository for test push target
`receive.denyCurrentBranch` currently has a bug where it allows pushing
into non-bare repository using namespaces as long as it does not have any
commits. This would cause t5509 to fail once that bug is fixed because it
pushes into an unborn current branch.
In t5509, no operations are performed inside `pushee`, as it is only a
target for `git push` and `git ls-remote` calls. Therefore it does not
need to have a worktree. So, it is safe to change `pushee` to a bare
repository.
Helped-by: Johannes Schindelin <redacted>
Signed-off-by: Hariom Verma <redacted>
Signed-off-by: Junio C Hamano <redacted>
Hariom Verma [Sun, 23 Feb 2020 18:57:08 +0000 (18:57 +0000)]
get_main_worktree(): allow it to be called in the Git directory
When called in the Git directory of a non-bare repository, this function
would not return the directory of the main worktree, but of the Git
directory instead.
The reason: when the Git directory is the current working directory, the
absolute path of the common directory will be reported with a trailing
`/.git/.`, which the code of `get_main_worktree()` does not handle
correctly.
Let's fix this.
Helped-by: Johannes Schindelin <redacted>
Signed-off-by: Hariom Verma <redacted>
Signed-off-by: Junio C Hamano <redacted>
Kir Kolyshkin [Fri, 21 Feb 2020 20:15:45 +0000 (12:15 -0800)]
completion: add diff --color-moved[-ws]
These options are available since git v2.15, but somehow
eluded from the completion script.
Note that while --color-moved-ws= accepts comma-separated
list of values, there is no (easy?) way to make it work
with completion (see e.g. [1]).
[1]: https://github.com/scop/bash-completion/issues/240
Acked-by: Matheus Tavares Bernardino <redacted>
Signed-off-by: Kir Kolyshkin <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:42 +0000 (20:17 +0000)]
commit: use expected signature header for SHA-256
The transition plan anticipates that we will allow signatures using
multiple algorithms in a single commit. In order to do so, we need to
use a different header per algorithm so that it will be obvious over
which data to compute the signature.
The transition plan specifies that we should use "gpgsig-sha256", so
wire up the commit code such that it can write and parse the current
algorithm, and it can remove the headers for any algorithm when creating
a new commit. Add tests to ensure that we write using the right header
and that git fsck doesn't reject these commits.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:41 +0000 (20:17 +0000)]
worktree: allow repository version 1
Git supports both repository versions 0 and 1. These formats are
identical except for the presence of extensions. When using an
extension, such as for a different hash algorithm, a check for only
version 0 causes the check to fail. Instead, call
verify_repository_format to verify that we have an appropriate version
and no unknown extensions.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:40 +0000 (20:17 +0000)]
init-db: move writing repo version into a function
When we perform a clone, we won't know the remote side's hash algorithm
until we've read the heads. Consequently, we'll need to rewrite the
repository format version and hash algorithm once we know what the
remote side has. Move the code that does this into its own function so
that we can call it from clone in the future.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:39 +0000 (20:17 +0000)]
builtin/init-db: add environment variable for new repo hash
For the foreseeable future, SHA-1 will be the default algorithm for Git.
However, when running the testsuite, we want to be able to test an
arbitrary algorithm. It would be quite burdensome and very untidy to
have to specify the algorithm we'd like to test every time we
initialized a new repository somewhere in the testsuite, so add an
environment variable to allow us to specify the default hash algorithm
for Git.
This has the benefit that we can set it once for the entire testsuite
and not have to think about it. In the future, users can also use it to
set the default for their repositories if they would like to do so.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:38 +0000 (20:17 +0000)]
builtin/init-db: allow specifying hash algorithm on command line
Allow the user to specify the hash algorithm on the command line by
using the --object-format option to git init. Validate that the user is
not attempting to reinitialize a repository with a different hash
algorithm. Ensure that if we are writing a non-SHA-1 repository that we
set the repository version to 1 and write the objectFormat extension.
Restrict this option to work only when ENABLE_SHA256 is set until the
codebase is in a situation to fully support this.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:37 +0000 (20:17 +0000)]
setup: allow check_repository_format to read repository format
In some cases, we will want to not only check the repository format, but
extract the information that we've gained. To do so, allow
check_repository_format to take a pointer to struct repository_format.
Allow passing NULL for this argument if we're not interested in the
information, and pass NULL for all existing callers. A future patch
will make use of this information.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:36 +0000 (20:17 +0000)]
t/helper: make repository tests hash independent
This test currently hard-codes the hash algorithm as SHA-1 when calling
repo_set_hash_algo so that the_hash_algo is properly initialized.
However, this does not work with SHA-256 repositories. Read the
repository value that repo_init has read into the local repository
variable and set the algorithm based on that value.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:35 +0000 (20:17 +0000)]
t/helper: initialize repository if necessary
The repository helper is used in t5318 to read commit graphs whether
we're in a repository or not. However, without a repository, we have no
way to properly initialize the hash algorithm, meaning that the file is
misread.
Fix this by calling setup_git_directory_gently, which will read the
environment variable the testsuite sets to ensure that the correct hash
algorithm is set.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:34 +0000 (20:17 +0000)]
t/helper/test-dump-split-index: initialize git repository
In this test helper, we read the index. In order to have the proper
hash algorithm set up, we must call setup_git_directory. Do so, so that
the test works when extensions.objectFormat is set.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:33 +0000 (20:17 +0000)]
t6300: make hash algorithm independent
One of the git for-each-ref tests asks to sort by object ID. However,
when sorted, the order of the refs differs between SHA-1 and SHA-256.
Sort the expected output so that the test passes.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:32 +0000 (20:17 +0000)]
t6300: abstract away SHA-1-specific constants
Adjust the test so that it computes variables for object IDs instead of
using hard-coded hashes.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:31 +0000 (20:17 +0000)]
t: use hash-specific lookup tables to define test constants
In the future, we'll allow developers to run the testsuite with a hash
algorithm of their choice. To make this easier, compute the fixed
constants using test_oid. Move the constant initialization down below
the point where test-lib-functions.sh is loaded so the functions are
defined.
Note that we don't provide a value for the OID_REGEX value directly
because writing a large number of instances of "[0-9a-f]" in the
oid-info files is unwieldy and there isn't a way to compute it based on
those values. Instead, compute it based on ZERO_OID.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:30 +0000 (20:17 +0000)]
repository: require a build flag to use SHA-256
At this point, SHA-256 support is experimental and some behavior may
change. To avoid surprising unsuspecting users, require a build flag,
ENABLE_SHA256, to allow use of a non-SHA-1 algorithm. Enable this flag
by default when the DEVELOPER make flag is set so that contributors can
test this case adequately.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:29 +0000 (20:17 +0000)]
hex: add functions to parse hex object IDs in any algorithm
There are some places where we need to parse a hex object ID in any
algorithm without knowing beforehand which algorithm is in use. An
example is when parsing fast-import marks.
Add a get_oid_hex_any to parse an object ID and return the algorithm it
belongs to, and additionally add parse_oid_hex_any which is the
equivalent change for parse_oid_hex. If the object is not parseable, we
return GIT_HASH_UNKNOWN.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:28 +0000 (20:17 +0000)]
hex: introduce parsing variants taking hash algorithms
Introduce variants of get_oid_hex and parse_oid_hex that parse an
arbitrary hash algorithm, implementing internal functions to avoid
duplication. These functions can be used in the transport code to parse
refs properly.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:27 +0000 (20:17 +0000)]
hash: implement and use a context cloning function
For all of our SHA-1 implementations and most of our SHA-256
implementations, the hash context we use is a real struct. For these
implementations, it's possible to copy a hash context by making a copy
of the struct.
However, for our libgcrypt implementation, our hash context is a
pointer. Consequently, copying it does not lead to an independent hash
context like we intended.
Fortunately, however, libgcrypt provides us with a handy function to
copy hash contexts. Let's add a cloning function to the hash algorithm
API, and use it in the one place we need to make a hash context copy.
With this change, our libgcrypt SHA-256 implementation is fully
functional with all of our other hash implementations.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Sat, 22 Feb 2020 20:17:26 +0000 (20:17 +0000)]
builtin/pack-objects: make hash agnostic
Avoid hard-coding a hash size, instead preferring to use the_hash_algo.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
René Scharfe [Sat, 22 Feb 2020 18:51:19 +0000 (19:51 +0100)]
use strpbrk(3) to search for characters from a given set
We can check if certain characters are present in a string by calling
strchr(3) on each of them, or we can pass them all to a single
strpbrk(3) call. The latter is shorter, less repetitive and slightly
more efficient, so let's do that instead.
Signed-off-by: René Scharfe <redacted>
Signed-off-by: Junio C Hamano <redacted>
René Scharfe [Sat, 22 Feb 2020 18:51:13 +0000 (19:51 +0100)]
quote: use isalnum() to check for alphanumeric characters
isalnum(c) is equivalent to isalpha(c) || isdigit(c), so use the
former instead. The result is shorter, simpler and slightly more
efficient.
Signed-off-by: René Scharfe <redacted>
Signed-off-by: Junio C Hamano <redacted>
Rasmus Jonsson [Sun, 23 Feb 2020 00:50:49 +0000 (01:50 +0100)]
t1050: replace test -f with test_path_is_file
Use test_path_is_file() instead of 'test -f' for better debugging
information.
Signed-off-by: Rasmus Jonsson <redacted>
Signed-off-by: Junio C Hamano <redacted>
Derrick Stolee [Fri, 21 Feb 2020 21:47:28 +0000 (21:47 +0000)]
partial-clone: avoid fetching when looking for objects
When using partial clone, find_non_local_tags() in builtin/fetch.c
checks each remote tag to see if its object also exists locally. There
is no expectation that the object exist locally, but this function
nevertheless triggers a lazy fetch if the object does not exist. This
can be extremely expensive when asking for a commit, as we are
completely removed from the context of the non-existent object and
thus supply no "haves" in the request.
6462d5eb9a (fetch: remove fetch_if_missing=0, 2019-11-05) removed a
global variable that prevented these fetches in favor of a bitflag.
However, some object existence checks were not updated to use this flag.
Update find_non_local_tags() to use OBJECT_INFO_SKIP_FETCH_OBJECT in
addition to OBJECT_INFO_QUICK. The _QUICK option only prevents
repreparing the pack-file structures. We need to be extremely careful
about supplying _SKIP_FETCH_OBJECT when we expect an object to not exist
due to updated refs.
This resolves a broken test in t5616-partial-clone.sh.
Signed-off-by: Derrick Stolee <redacted>
Signed-off-by: Junio C Hamano <redacted>
Derrick Stolee [Fri, 21 Feb 2020 21:47:27 +0000 (21:47 +0000)]
partial-clone: demonstrate bugs in partial fetch
While testing partial clone, I noticed some odd behavior. I was testing
a way of running 'git init', followed by manually configuring the remote
for partial clone, and then running 'git fetch'. Astonishingly, I saw
the 'git fetch' process start asking the server for multiple rounds of
pack-file downloads! When tweaking the situation a little more, I
discovered that I could cause the remote to hang up with an error.
Add two tests that demonstrate these two issues.
In the first test, we find that when fetching with blob filters from
a repository that previously did not have any tags, the 'git fetch
--tags origin' command fails because the server sends "multiple
filter-specs cannot be combined". This only happens when using
protocol v2.
In the second test, we see that a 'git fetch origin' request with
several ref updates results in multiple pack-file downloads. This must
be due to Git trying to fault-in the objects pointed by the refs. What
makes this matter particularly nasty is that this goes through the
do_oid_object_info_extended() method, so there are no "haves" in the
negotiation. This leads the remote to send every reachable commit and
tree from each new ref, providing a quadratic amount of data transfer!
This test is fixed if we revert
6462d5eb9a (fetch: remove
fetch_if_missing=0, 2019-11-05), but that revert causes other test
failures. The real fix will need more care.
The tests are ordered in this way because if I swap the test order the
tag test will succeed instead of fail. I believe this is because somehow
we need the srv.bare repo to not have any tags when we clone, but then
have tags in our next fetch.
Signed-off-by: Derrick Stolee <redacted>
Signed-off-by: Junio C Hamano <redacted>
Jeff King [Fri, 21 Feb 2020 02:56:37 +0000 (21:56 -0500)]
run-command.h: fix mis-indented struct member
An accidental conversion of a tab to 4 spaces snuck into
4c4066d95d
(run-command: move doc to run-command.h, 2019-11-17), messing up the
alignment when you have the project-recommended 8-width tabstops. Let's
revert that line.
Signed-off-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Junio C Hamano [Thu, 20 Feb 2020 17:34:36 +0000 (09:34 -0800)]
describe: force long format for a name based on a mislocated tag
An annotated tag has two names: where it sits in the refs/tags
hierarchy and the tagname recorded in the "tag" field in the object
itself. They usually should match.
Since
212945d4 ("Teach git-describe to verify annotated tag names
before output", 2008-02-28), a commit described using an annotated
tag bases its name on the tagname from the object. While this was a
deliberate design decision to make it easier to converse about tags
with others, even if the tags happen to be fetched to a different
name than it was given by its creator, it had one downside.
The output from "git describe", at least in the modern Git, should
be usable as an object name to name the exact commit given to the
"git describe" command. Using the tagname, when two names differ,
breaks this property, when describing a commit that is directly
pointed at by such a tag. An annotated tag Bob made as "v1.0" may
sit at "refs/tags/v1.0-bob" in the ref hierarchy, and output from
"git describe v1.0-bob^0" would say "v1.0", but there may not be
any tag at "refs/tags/v1.0" locally or there may be another tag that
points at a different object.
Note that this won't be a problem if a commit being described is not
directly pointed at by such a mislocated tag. In the example in the
previous paragraph, describing a commit whose parent is v1.0-bob
would result in "v1.0" (i.e. the tagname taken from the tag object)
followed by "-1-gXXXXX" where XXXXX is the abbreviated object name,
and a string that ends with "-g" followed by a hexadecimal string is
an object name for the object whose name begins with hexadecimal
string (as long as it is unique), so it does not matter if the
leading part is "v1.0" or "v1.0-bob".
Show the name in the long format, i.e. with "-0-gXXXXX" suffix, when
the name we give is based on a mislocated annotated tag to ensure
that the output can be used as the object name for the object
originally given to the command to fix the issue.
While at it, remove an overly cautious dead code to protect against
an annotated tag object without the tagname. Such a tag is filtered
out much earlier in the codeflow, and will not reach this part of
the code.
Helped-by: Matheus Tavares <redacted>
Helped-by: Jeff King <redacted>
Signed-off-by: Junio C Hamano <redacted>
Derrick Stolee [Thu, 20 Feb 2020 20:07:06 +0000 (20:07 +0000)]
sparse-checkout: allow one-character directories in cone mode
In
9e6d3e64 (sparse-checkout: detect short patterns, 2020-01-24), a
condition on the minimum length of a cone-mode pattern was introduced.
However, this condition was off-by-one.
If we have a directory with a single character, say "b", then the
command
git sparse-checkout set b
will correctly add the pattern "/b/" to the sparse-checkout file. When
this is interpeted in dir.c, the pattern is "/b" with the
PATTERN_FLAG_MUSTBEDIR flag. This string has length two, which satisfies
our inclusive inequality (<= 2).
The reason for this inequality is that we will start to read the pattern
string character-by-character using three char pointers: prev, cur,
next. In particular, next is set to the current pattern plus two. The
mistake was that next will still be a valid pointer when the pattern
length is two, since the string is null-terminated.
Make this inequality strict so these patterns work.
Signed-off-by: Derrick Stolee <redacted>
Signed-off-by: Junio C Hamano <redacted>
Paolo Bonzini [Thu, 20 Feb 2020 14:15:19 +0000 (15:15 +0100)]
am: support --show-current-patch=diff to retrieve .git/rebase-apply/patch
When "git am --show-current-patch" was added in commit
984913a210 ("am:
add --show-current-patch", 2018-02-12), "git am" started recommending it
as a replacement for .git/rebase-merge/patch. Unfortunately the suggestion
is somewhat misguided; for example, the output of "git am --show-current-patch"
cannot be passed to "git apply" if it is encoded as quoted-printable
or base64. Add a new mode to "git am --show-current-patch" in order to
straighten the suggestion.
Reported-by: J. Bruce Fields <redacted>
Signed-off-by: Paolo Bonzini <redacted>
Signed-off-by: Junio C Hamano <redacted>
Paolo Bonzini [Thu, 20 Feb 2020 14:15:18 +0000 (15:15 +0100)]
am: support --show-current-patch=raw as a synonym for--show-current-patch
When "git am --show-current-patch" was added in commit
984913a210 ("am:
add --show-current-patch", 2018-02-12), "git am" started recommending it
as a replacement for .git/rebase-merge/patch. Unfortunately the suggestion
is somewhat misguided; for example, the output "git am --show-current-patch"
cannot be passed to "git apply" if it is encoded as quoted-printable or
base64. To simplify worktree operations and to avoid that users poke into
.git, it would be better if "git am" also provided a mode that copies
.git/rebase-merge/patch to stdout.
One possibility could be to have completely separate options, introducing
for example --show-current-message (for .git/rebase-apply/NNNN)
and --show-current-diff (for .git/rebase-apply/patch), while possibly
deprecating --show-current-patch.
That would even remove the need for the first two patches in the series.
However, the long common prefix would have prevented using an abbreviated
option such as "--show". Therefore, I chose instead to add a string
argument to --show-current-patch. The new argument is optional, so that
"git am --show-current-patch"'s behavior remains backwards-compatible.
The next choice to make is how to handle multiple --show-current-patch
options. Right now, something like "git am --abort --show-current-patch"
is rejected, and the previous suggestion would likewise have naturally
rejected a command line like
git am --show-current-message --show-current-diff
Therefore, I decided to also reject for example
git am --show-current-patch=diff --show-current-patch=raw
In other words the whole of --show-current-patch=xxx (including the
optional argument) is treated as the command mode. I found this to be
more consistent and intuitive, even though it differs from the usual
"last one wins" semantics of the git command line.
Add the code to parse submodes based on the above design, where for now
"raw" is the only valid submode. "raw" prints the full e-mail message
just like "git am --show-current-patch".
Signed-off-by: Paolo Bonzini <redacted>
Signed-off-by: Junio C Hamano <redacted>
Paolo Bonzini [Thu, 20 Feb 2020 14:15:17 +0000 (15:15 +0100)]
am: convert "resume" variable to a struct
This will allow stashing the submode of --show-current-patch from a
callback function. Using a struct will allow accessing both fields from
outside cmd_am (through container_of).
Signed-off-by: Paolo Bonzini <redacted>
Signed-off-by: Junio C Hamano <redacted>
Paolo Bonzini [Thu, 20 Feb 2020 14:15:16 +0000 (15:15 +0100)]
parse-options: convert "command mode" to a flag
OPTION_CMDMODE is essentially OPTION_SET_INT plus an extra check that
the variable had not set before. In order to allow custom processing
of the option, for example a "command mode" option that also has an
argument, it would be nice to use OPTION_CALLBACK and not have to rewrite
the extra check on incompatible options. In other words, making the
processing of the option orthogonal to the "only one of these" behavior
provided by OPTION_CMDMODE.
Add a new flag that takes care of the check, and modify OPT_CMDMODE to
use it together with OPTION_SET_INT. The new flag still requires that the
option value points to an int, but any OPTION_* value can be specified as
long as it does not require a non-int type for opt->value.
Signed-off-by: Paolo Bonzini <redacted>
Signed-off-by: Junio C Hamano <redacted>
Paolo Bonzini [Thu, 20 Feb 2020 14:15:15 +0000 (15:15 +0100)]
parse-options: add testcases for OPT_CMDMODE()
Before modifying the implementation, ensure that general operation of
OPT_CMDMODE() and detection of incompatible options are covered.
Signed-off-by: Paolo Bonzini <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Thu, 20 Feb 2020 02:24:13 +0000 (02:24 +0000)]
credential: allow wildcard patterns when matching config
In some cases, a user will want to use a specific credential helper for
a wildcard pattern, such as https://*.corp.example.com. We have code
that handles this already with the urlmatch code, so let's use that
instead of our custom code.
Since the urlmatch code is a superset of our current matching in terms
of capabilities, there shouldn't be any cases of things that matched
previously that don't match now. However, in addition to wildcard
matching, we now use partial path matching, which can cause slightly
different behavior in the case that a helper applies to the prefix
(considering path components) of the remote URL. While different, this
is probably the behavior people were wanting anyway.
Since we're using the urlmatch code, we need to encode the components
we've gotten into a URL to match, so add a function to percent-encode
data and format the URL with it. We now also no longer need to the
custom code to match URLs, so let's remove it.
Additionally, the urlmatch code always looks for the best match, whereas
we want all matches for credential helpers to preserve existing
behavior. Let's add an optional field, select_fn, that lets us control
which items we want (in this case, all of them) and default it to the
best-match code that already exists for other users.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Thu, 20 Feb 2020 02:24:12 +0000 (02:24 +0000)]
credential: use the last matching username in the config
Everywhere else in the codebase, we use the rule that the last matching
configuration option is the one that takes effect. This is helpful
because it allows more specific configuration settings (e.g., per-repo
configuration) to override less specific settings (e.g., per-user
configuration).
However, in the credential code, we didn't honor this setting, and
instead picked the first setting we had, and stuck with it. This was
likely to ensure we picked the value from the URL, which we want to
honor over the configuration.
It's possible to do both, though, so let's check if the value is the one
we've gotten over our protocol connection, which if present will have
come from the URL, and keep it if so. Otherwise, let's overwrite the
value with the latest version we've got from the configuration, so we
keep the last configuration value.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Thu, 20 Feb 2020 02:24:11 +0000 (02:24 +0000)]
t0300: add tests for some additional cases
There are some tricky cases in our credential helpers that we don't have
test cases for. To help prevent regressions, let's add some for these
cases:
* If there are multiple configured credential helpers, one without a
path and one with a path, we want to invoke both of them.
* If there are percent-encoded values in the URL, we handle them
properly.
* And finally, if there is a username in the remote URL, we want to
honor that over what the configuration tells us.
Finally, there's an additional case that we'd like to test for as well,
but that currently fails. In all other situations in our configuration,
we pick the last configuration setting that's provided. However, we
fail to do that for credential.username, where we pick the first setting
instead. Let's add a failing test that we have the consistent behavior
here, since that's the documented, expected behavior.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Thu, 20 Feb 2020 02:24:10 +0000 (02:24 +0000)]
t1300: add test for urlmatch with multiple wildcards
Our urlmatch code handles multiple wildcards, but we don't currently
have a test that checks this code path. Add a test that we handle this
case correctly to avoid any regressions.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
brian m. carlson [Thu, 20 Feb 2020 02:24:09 +0000 (02:24 +0000)]
mailmap: add an additional email address for brian m. carlson
To more accurately track the provenance of contributions, brian uses a
work email address for commits created at work. Add this email address
to .mailmap so that contributions are properly attributed to the same
person.
Signed-off-by: brian m. carlson <redacted>
Signed-off-by: Junio C Hamano <redacted>
Philippe Blain [Mon, 17 Feb 2020 04:53:06 +0000 (04:53 +0000)]
t/lib-submodule-update: add test removing nested submodules
The previous commit fixed a bug with the (no submodule) -> (nested
submodules) transition for commands in the unpack-trees machinery.
Let's add a test for the reverse transition (going from nested
submodules to no submodule), as it is not being tested currently.
While at it, uniformize the capitalization in the list of tests.
Signed-off-by: Philippe Blain <redacted>
Signed-off-by: Junio C Hamano <redacted>
Philippe Blain [Mon, 17 Feb 2020 04:53:05 +0000 (04:53 +0000)]
unpack-trees: check for missing submodule directory in merged_entry
Using `git checkout --recurse-submodules` to switch between a
branch with no submodules and a branch with initialized nested
submodules currently causes a fatal error:
$ git checkout --recurse-submodules branch-with-nested-submodules
fatal: exec '--super-prefix=submodule/nested/': cd to 'nested'
failed: No such file or directory
error: Submodule 'nested' could not be updated.
error: Submodule 'submodule/nested' cannot checkout new HEAD.
error: Submodule 'submodule' could not be updated.
M submodule
Switched to branch 'branch-with-nested-submodules'
The checkout succeeds but the worktree and index of the first level
submodule are left empty:
$ cd submodule
$ git -c status.submoduleSummary=1 status
HEAD detached at
b3ce885
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: .gitmodules
deleted: first.t
deleted: nested
fatal: not a git repository: 'nested/.git'
Submodule changes to be committed:
* nested
1e96f59...
0000000:
$ git ls-files -s
$ # empty
$ ls -A
.git
The reason for the fatal error during the checkout is that a child git
process tries to cd into the yet unexisting nested submodule directory.
The sequence is the following:
1. The main git process (the one running in the superproject) eventually
reaches write_entry() in entry.c, which creates the first level
submodule directory and then calls submodule_move_head() in submodule.c,
which spawns `git read-tree` in the submodule directory.
2. The first child git process (the one in the submodule of the
superproject) eventually calls check_submodule_move_head() at
unpack_trees.c:2021, which calls submodule_move_head in dry-run mode,
which spawns `git read-tree` in the nested submodule directory.
3. The second child git process tries to chdir() in the yet unexisting
nested submodule directory in start_command() at run-command.c:829 and
dies before exec'ing.
The reason why check_submodule_move_head() is reached in the first child
and not in the main process is that it is inside an
if(submodule_from_ce()) construct, and submodule_from_ce() returns a
valid struct submodule pointer, whereas it returns a null pointer in the
main git process.
The reason why submodule_from_ce() returns a null pointer in the main
git process is because the call to cache_lookup_path() in config_from()
(called from submodule_from_path() in submodule_from_ce()) returns a
null pointer since the hashmap "for_path" in the submodule_cache of
the_repository is not yet populated. It is not populated because both
repo_get_oid(repo, GITMODULES_INDEX, &oid) and repo_get_oid(repo,
GITMODULES_HEAD, &oid) in config_from_gitmodules() at
submodule-config.c:639-640 return -1, as at this stage of the operation,
neither the HEAD of the superproject nor its index contain any
.gitmodules file.
In contrast, in the first child the hashmap is populated because
repo_get_oid(repo, GITMODULES_HEAD, &oid) returns 0 as the HEAD of the
first level submodule, i.e. .git/modules/submodule/HEAD, points to a
commit where .gitmodules is present and records 'nested' as a submodule.
Fix this bug by checking that the submodule directory exists before
calling check_submodule_move_head() in merged_entry() in the `if(!old)`
branch, i.e. if going from a commit with no submodule to a commit with a
submodule present.
Also protect the other call to check_submodule_move_head() in
merged_entry() the same way as it is safer, even though the `else if
(!(old->ce_flags & CE_CONFLICTED))` branch of the code is not at play in
the present bug.
The other calls to check_submodule_move_head() in other functions in
unpack_trees.c are all already protected by calls to lstat() somewhere
in
the program flow so we don't need additional protection for them.
All commands in the unpack_trees machinery are affected, i.e. checkout,
reset and read-tree when called with the --recurse-submodules flag.
This bug was first reported in [1].
[1]
https://lore.kernel.org/git/
7437BB59-4605-48EC-B05E-
E2BDB2D9DABC@gmail.com/
Reported-by: Philippe Blain <redacted>
Reported-by: Damien Robert <redacted>
Signed-off-by: Philippe Blain <redacted>
Signed-off-by: Junio C Hamano <redacted>
Philippe Blain [Mon, 17 Feb 2020 04:53:04 +0000 (04:53 +0000)]
unpack-trees: remove outdated description for verify_clean_submodule
The function verify_clean_submodule() learned to verify if a submodule
working tree is clean in
a7bc845a9a (unpack-trees: check if we can
perform the operation for submodules, 2017-03-14), but the commented
description above it was not updated to reflect that, such that this
description has been outdated since then.
Since Git has now learned to optionnally recursively check out
submodules during a superproject checkout, remove this outdated
description.
Signed-off-by: Philippe Blain <redacted>
Signed-off-by: Junio C Hamano <redacted>
Philippe Blain [Mon, 17 Feb 2020 04:53:03 +0000 (04:53 +0000)]
t/lib-submodule-update: move a test to the right section
The test "$command: submodule branch is not changed, detach HEAD
instead" is in the "Appearing submodule" section of
test_submodule_recursing_with_args_common(), but this test updates a
submodule; it does not test a transition from a state with no submodule
to a state with a submodule.
As such, for consistency, move it to the "Modified submodule" section of
the same function. While at it, add a comment describing the test.
Signed-off-by: Philippe Blain <redacted>
Signed-off-by: Junio C Hamano <redacted>
Philippe Blain [Mon, 17 Feb 2020 04:53:02 +0000 (04:53 +0000)]
t/lib-submodule-update: remove outdated test description
The commands in the unpack_trees machinery (checkout, reset, read-tree)
were fixed in
218c883783 (submodule: properly recurse for read-tree and
checkout, 2017-05-02) to correctly update nested submodules when called
with the `--recurse-submodules` flag.
However, a comment in t/lib-submodule-update.sh mentions that this use
case still doesn't work.
Remove this outdated comment.
Signed-off-by: Philippe Blain <redacted>
Signed-off-by: Junio C Hamano <redacted>
Philippe Blain [Mon, 17 Feb 2020 04:53:01 +0000 (04:53 +0000)]
t7112: remove mention of KNOWN_FAILURE_SUBMODULE_RECURSIVE_NESTED
The known failure mode KNOWN_FAILURE_SUBMODULE_RECURSIVE_NESTED was
removed from lib-submodule-update.sh in
218c883783 (submodule: properly
recurse for read-tree and checkout, 2017-05-02) but at that time this
change was not ported over to topic sb/reset-recurse-submodules, such
that when this topic was merged in
5f074ca7e8 (Merge branch
'sb/reset-recurse-submodules', 2017-05-29), t7112-reset-submodules.sh
kept a mention of this removed failure mode.
Remove it now, as it does not mean anything anymore.
Signed-off-by: Philippe Blain <redacted>
Signed-off-by: Junio C Hamano <redacted>
Alexandr Miloslavskiy [Mon, 17 Feb 2020 17:25:22 +0000 (17:25 +0000)]
stash push: support the --pathspec-from-file option
Decisions taken for simplicity:
1) For now, `--pathspec-from-file` is declared incompatible with
`--patch`, even when <file> is not `-`. Such use case is not
really expected.
2) It is not allowed to pass pathspec in both args and file.
Signed-off-by: Alexandr Miloslavskiy <redacted>
Signed-off-by: Junio C Hamano <redacted>
Alexandr Miloslavskiy [Mon, 17 Feb 2020 17:25:21 +0000 (17:25 +0000)]
stash: eliminate crude option parsing
Eliminate crude option parsing and rely on real parsing instead, because
1) Crude parsing is crude, for example it's not capable of
handling things like `git stash -m Message`
2) Adding options in two places is inconvenient and prone to bugs
As a side result, the case of `git stash -m Message` gets fixed.
Also give a good error message instead of just throwing usage at user.
----
Some review of what's been happening to this code:
Before [1], `git-stash.sh` only verified that all args begin with `-` :
# The default command is "push" if nothing but options are given
seen_non_option=
for opt
do
case "$opt" in
--) break ;;
-*) ;;
*) seen_non_option=t; break ;;
esac
done
Later, [1] introduced the duplicate code I'm now removing, also making
the previous test more strict by white-listing options.
----
[1] Commit
40af1468 ("stash: convert `stash--helper.c` into `stash.c`" 2019-02-26)
Signed-off-by: Alexandr Miloslavskiy <redacted>
Signed-off-by: Junio C Hamano <redacted>
Alexandr Miloslavskiy [Mon, 17 Feb 2020 17:25:20 +0000 (17:25 +0000)]
doc: stash: synchronize <pathspec> description
This patch continues the effort that is already applied to
`git commit`, `git reset`, `git checkout` etc.
1) Added reference to 'linkgit:gitglossary[7]'.
2) Fixed mentions of incorrectly plural "pathspecs".
Signed-off-by: Alexandr Miloslavskiy <redacted>
Signed-off-by: Junio C Hamano <redacted>
Alexandr Miloslavskiy [Mon, 17 Feb 2020 17:25:19 +0000 (17:25 +0000)]
doc: stash: document more options
Signed-off-by: Alexandr Miloslavskiy <redacted>
Signed-off-by: Junio C Hamano <redacted>
Alexandr Miloslavskiy [Mon, 17 Feb 2020 17:25:18 +0000 (17:25 +0000)]
doc: stash: split options from description (2)
Together with the previous patch, this brings docs for `git stash` to
the common layout used for most other commands (see for example docs
for `git add`, `git commit`, `git checkout`, `git reset`) where all
options are documented in a separate list.
After some thinking and having a look at docs for `git svn` and
`git `submodule`, I have arrived at following conclusions:
* Options should be described in a list rather then text to
facilitate lookup for user.
* Single list is better then multiple lists because it avoids
copy&pasting descriptions between subcommands (or, without
copy&pasting, user will have to look up missing options in other
subcommands).
* As a consequence, commands section should only give brief info and
list possible options. Since options have good enough names, user
will only need to look up the "interesting" options.
* Every option should list which subcommands support it.
I have decided to use alphabetical sorting in the list of options to
facilitate lookup for user.
There is some text editing done to make old descriptions better fit
into the list-style format.
Signed-off-by: Alexandr Miloslavskiy <redacted>
Signed-off-by: Junio C Hamano <redacted>
Alexandr Miloslavskiy [Mon, 17 Feb 2020 17:25:17 +0000 (17:25 +0000)]
doc: stash: split options from description (1)
This patch moves blocks of text as-is to make it easier to review the
next patch.
Signed-off-by: Alexandr Miloslavskiy <redacted>
Signed-off-by: Junio C Hamano <redacted>
Alexandr Miloslavskiy [Mon, 17 Feb 2020 17:25:16 +0000 (17:25 +0000)]
rm: support the --pathspec-from-file option
Decisions taken for simplicity:
1) It is not allowed to pass pathspec in both args and file.
Adjustments were needed for `if (!argc)` block:
This code actually means "pathspec is not present". Previously, pathspec
could only come from commandline arguments, so testing for `argc` was a
valid way of testing for the presence of pathspec. But this is no longer
true with `--pathspec-from-file`.
During the entire `--pathspec-from-file` story, I tried to keep its
behavior very close to giving pathspec on commandline, so that switching
from one to another doesn't involve any surprises.
However, throwing usage at user in the case of empty
`--pathspec-from-file` would puzzle because there's nothing wrong with
"usage" (that is, argc/argv array).
On the other hand, throwing usage in the old case also feels bad to me.
While it's less of a puzzle, I (as user) never liked the experience of
comparing my commandline to "usage", trying to spot a difference. Since
it's already known what the error is, it feels a lot better to give that
specific error to user.
Judging from [1] it doesn't seem that showing usage in this case was
important (the patch was to avoid segfault), and it doesn't fit into how
other commands react to empty pathspec (see for example `git add` with a
custom message).
Therefore, I decided to show new error text in both cases. In order to
continue testing for error early, I moved `parse_pathspec()` higher. Now
it happens before `read_cache()` / `hold_locked_index()` /
`setup_work_tree()`, which shouldn't cause any issues.
[1] Commit
7612a1ef ("git-rm: honor -n flag" 2006-06-09)
Signed-off-by: Alexandr Miloslavskiy <redacted>
Signed-off-by: Junio C Hamano <redacted>
Elijah Newren [Wed, 19 Feb 2020 17:04:07 +0000 (17:04 +0000)]
merge-recursive: fix the refresh logic in update_file_flags
If we need to delete a higher stage entry in the index to place the file
at stage 0, then we'll lose that file's stat information. In such
situations we may still be able to detect that the file on disk is the
version we want (as noted by our comment in the code:
/* do not overwrite file if already present */
), but we do still need to update the mtime since we are creating a new
cache_entry for that file. Update the logic used to determine whether
we refresh a file's mtime.
Signed-off-by: Elijah Newren <redacted>
Signed-off-by: Junio C Hamano <redacted>
Elijah Newren [Wed, 19 Feb 2020 17:04:06 +0000 (17:04 +0000)]
t3433: new rebase testcase documenting a stat-dirty-like failure
A user discovered a case where they had a stack of 20 simple commits to
rebase, and the rebase would succeed in picking the first commit and
then error out with a pair of "Could not execute the todo command" and
"Your local changes to the following files would be overwritten by
merge" messages.
Their steps actually made use of the -i flag, but I switched it over to
-m to make it simpler to trigger the bug. With that flag, it bisects
back to commit
68aa495b590d (rebase: implement --merge via the
interactive machinery, 2018-12-11), but that's misleading. If you
change the -m flag to --keep-empty, then the problem persists and will
bisect back to
356ee4659bb5 (sequencer: try to commit without forking
'git commit', 2017-11-24)
After playing with the testcase for a bit, I discovered that added
--exec "sleep 1" to the command line makes the rebase succeed, making me
suspect there is some kind of discard and reloading of caches that lead
us to believe that something is stat dirty, but I didn't succeed in
digging any further than that.
Signed-off-by: Elijah Newren <redacted>
Signed-off-by: Junio C Hamano <redacted>
Pranit Bauva [Mon, 17 Feb 2020 08:40:39 +0000 (09:40 +0100)]
bisect: libify `bisect_next_all`
Since we want to get rid of git-bisect.sh, it would be necessary to
convert those exit() calls to return statements so that errors can be
reported.
Emulate try catch in C by converting `exit(<positive-value>)` to
`return <negative-value>`. Follow POSIX conventions to return
<negative-value> to indicate error.
All the functions calling `bisect_next_all()` are already able to
handle return values from it.
Mentored-by: Christian Couder <redacted>
Mentored-by: Johannes Schindelin <redacted>
Signed-off-by: Pranit Bauva <redacted>
Signed-off-by: Tanushree Tumane <redacted>
Signed-off-by: Miriam Rubio <redacted>
Signed-off-by: Junio C Hamano <redacted>
Pranit Bauva [Mon, 17 Feb 2020 08:40:38 +0000 (09:40 +0100)]
bisect: libify `handle_bad_merge_base` and its dependents
Since we want to get rid of git-bisect.sh, it would be necessary to
convert those exit() calls to return statements so that errors can be
reported.
Emulate try catch in C by converting `exit(<positive-value>)` to
`return <negative-value>`. Follow POSIX conventions to return
<negative-value> to indicate error.
Update all callers to handle the error returns.
Mentored-by: Christian Couder <redacted>
Mentored-by: Johannes Schindelin <redacted>
Signed-off-by: Pranit Bauva <redacted>
Signed-off-by: Tanushree Tumane <redacted>
Signed-off-by: Miriam Rubio <redacted>
Signed-off-by: Junio C Hamano <redacted>
Pranit Bauva [Mon, 17 Feb 2020 08:40:37 +0000 (09:40 +0100)]
bisect: libify `check_good_are_ancestors_of_bad` and its dependents
Since we want to get rid of git-bisect.sh, it would be necessary to
convert those exit() calls to return statements so that errors can be
reported.
Emulate try catch in C by converting `exit(<positive-value>)` to
`return <negative-value>`. Follow POSIX conventions to return
<negative-value> to indicate error.
Code that turns BISECT_INTERNAL_SUCCESS_MERGE_BASE (-11)
to BISECT_OK (0) from `check_good_are_ancestors_of_bad()` has been moved to
`cmd_bisect__helper()`.
Update all callers to handle the error returns.
Mentored-by: Christian Couder <redacted>
Mentored by: Johannes Schindelin <redacted>
Signed-off-by: Pranit Bauva <redacted>
Signed-off-by: Tanushree Tumane <redacted>
Signed-off-by: Miriam Rubio <redacted>
Signed-off-by: Junio C Hamano <redacted>
Pranit Bauva [Mon, 17 Feb 2020 08:40:36 +0000 (09:40 +0100)]
bisect: libify `check_merge_bases` and its dependents
Since we want to get rid of git-bisect.sh, it would be necessary to
convert those exit() calls to return statements so that errors can be
reported.
Emulate try catch in C by converting `exit(<positive-value>)` to
`return <negative-value>`. Follow POSIX conventions to return
<negative-value> to indicate error.
In `check_merge_bases()` there is an early success special case,
so we have introduced special error code
BISECT_INTERNAL_SUCCESS_MERGE_BASE (-11) which indicates early
success. This BISECT_INTERNAL_SUCCESS_MERGE_BASE is converted back
to BISECT_OK (0) in `check_good_are_ancestors_of_bad()`.
Update all callers to handle the error returns.
Mentored-by: Christian Couder <redacted>
Mentored by: Johannes Schindelin <redacted>
Signed-off-by: Pranit Bauva <redacted>
Signed-off-by: Tanushree Tumane <redacted>
Signed-off-by: Miriam Rubio <redacted>
Signed-off-by: Junio C Hamano <redacted>