Skip to content

Tmp#1

Closed
dscho wants to merge 891 commits into
mainfrom
tmp
Closed

Tmp#1
dscho wants to merge 891 commits into
mainfrom
tmp

Conversation

@dscho

@dscho dscho commented Mar 4, 2026

Copy link
Copy Markdown
Owner

No description provided.

mingwandroid and others added 30 commits April 9, 2025 13:37
Otherwise if globbing is allowed and we get called from a
Windows program, build_argv thinks we've been called from
a Cygwin program.
…spec

Reverts 25ba8f3. I can't figure out what
the intention was. I'm sure I'll find out soon enough when everything breaks.

This change means that input of:
  '"C:/test.exe SOME_VAR=\"literal quotes\""'

becomes:
  'C:/test.exe SOME_VAR="literal quotes"'

instead of:
  'C:/test.exe SOME_VAR=\literal quotes\'

.. which is at least consistent with the result for:
  '"no_drive_or_colon SOME_VAR=\"literal quotes\""'

The old result of course resulted in the quoted string being split into
two arguments at the space which is clearly not intended.

I *guess* backslashes in dos paths may have been the issue here?
If so I don't care since we should not use them, ever, esp. not at
the expense of sensible forward-slash-containing input.
Works very much like MSYS2_ARG_CONV_EXCL. In fact it uses the same
function, arg_heuristic_with_exclusions (). Also refactors parsing
the env. variables to use new function, string_split_delimited ().

The env. that is searched through is the merged (POSIX + Windows)
one. It remains to be seen if this should be made an option or not.

This feature was prompted because the R language (Windows exe) calls
bash to run configure.win, which then calls back into R to read its
config variables (LOCAL_SOFT) and when this happens, msys2-runtime
converts R_ARCH from "/x64" to an absolute Windows path and appends
it to another absolute path, R_HOME, forming an invalid path.
It is simply the negation of `disable_pcon`, i.e. `MSYS=enable_pcon` is
equivalent to `MSYS=nodisable_pcon` (the former is slightly more
intuitive than the latter) and likewise `MSYS=noenable_pcon` is
equivalent to `MSYS=disable_pcon` (here, the latter is definitely more
intuitive than the former).

This is needed because we just demoted the pseudo console feature to be
opt-in instead of opt-out, and it would be awkward to recommend to users
to use "nodisable_pcon"... "nodisable" is not even a verb.

Signed-off-by: Johannes Schindelin <[email protected]>
We mount /usr/bin to /bin, but in a chroot this is broken and we
have no /bin, so try to use the real path.

chroot is used by pacman to run install scripts when called with --root
and this broke programs in install scripts calling popen()
(install-info from texinfo for example)

There are more paths hardcoded to /bin in cygwin which might also be broken
in this scenario, so this maybe should be extended to all of them.
It does not work at all. For example, `rpm -E %fedora` says that there
should be version 33 of rpmsphere at
https://github.com/rpmsphere/noarch/tree/master/r, but there is only
version 32.

Another thing that is broken: Cygwin now assumes that a recent
mingw-w64-headers version is available, but Fedora apparently only
offers v7.0.0, which is definitely too old to accommodate for the
expectation of cygwin/cygwin@c1f7c4d1b6d7.

Signed-off-by: Johannes Schindelin <[email protected]>
Build with --disable-dependency-tracking because we only build once
and this saves 3-4 minutes in CI.
This will help us by automating an otherwise tedious task.

Signed-off-by: Johannes Schindelin <[email protected]>
In the Cygwin project, it was decided that the command-line of Cygwin
processes, as shown in the output of `wmic process list`, would suffer
from being truncated to 32k (and is transmitted to the child process via
a different mechanism, anyway), and therefore only the absolute path of
the executable is shown by default.

Users who would like to see the full command-line (even if it is
truncated) are expected to set `CYGWIN=wincmdln` (or, in MSYS2's case,
`MSYS=wincmdln`).

Seeing as MSYS2 tries to integrate much better with the surrounding
Win32 ecosystem than Cygwin, it makes sense to turn this on by default.

Users who wish to suppress it can still set `MSYS=nowincmdln`.

Signed-off-by: Johannes Schindelin <[email protected]>
In particular, we are interested in the address of the CtrlRoutine
and the ExitProcess functions. Since kernel32.dll is loaded first thing,
the addresses will be the same for all processes (matching the
CPU architecture, of course).

This will help us with emulating SIGINT properly (by not sending signals
to *all* processes attached to the same Console, as
GenerateConsoleCtrlEvent() would do).

Co-authored-by: Naveen M K <[email protected]>
Signed-off-by: Johannes Schindelin <[email protected]>
This patch is heavily inspired by the Git for Windows' strategy in
handling Ctrl+C.

When a process is terminated via TerminateProcess(), it has no chance to
do anything in the way of cleaning up. This is particularly noticeable
when a lengthy Git for Windows process tries to update Git's index file
and leaves behind an index.lock file. Git's idea is to remove the stale
index.lock file in that case, using the signal and atexit handlers
available in Linux. But those signal handlers never run.

Note: this is not an issue for MSYS2 processes because MSYS2 emulates
Unix' signal system accurately, both for the process sending the kill
signal and the process receiving it. Win32 processes do not have such a
signal handler, though, instead MSYS2 shuts them down via
`TerminateProcess()`.

For a while, Git for Windows tried to use a gentler method, described in
the Dr Dobb's article "A Safer Alternative to TerminateProcess()" by
Andrew Tucker (July 1, 1999),
http://www.drdobbs.com/a-safer-alternative-to-terminateprocess/184416547

Essentially, we injected a new thread into the running process that does
nothing else than running the ExitProcess() function.

However, this was still not in line with the way CMD handles Ctrl+C: it
gives processes a chance to do something upon Ctrl+C by calling
SetConsoleCtrlHandler(), and ExitProcess() simply never calls that
handler.

So for a while we tried to handle SIGINT/SIGTERM by attaching to the
console of the command to interrupt, and generating the very same event
as CMD does via GenerateConsoleCtrlEvent().

This method *still* was not correct, though, as it would interrupt
*every* process attached to that Console, not just the process (and its
children) that we wanted to signal. A symptom was that hitting Ctrl+C
while `git log` was shown in the pager would interrupt *the pager*.

The method we settled on is to emulate what GenerateConsoleCtrlEvent()
does, but on a process by process basis: inject a remote thread and call
the (private) function kernel32!CtrlRoutine.

To obtain said function's address, we use the dbghelp API to generate a
stack trace from a handler configured via SetConsoleCtrlHandler() and
triggered via GenerateConsoleCtrlEvent(). To avoid killing each and all
processes attached to the same Console as the MSYS2 runtime, we modify
the cygwin-console-helper to optionally print the address of
kernel32!CtrlRoutine to stdout, and then spawn it with a new Console.

Note that this also opens the door to handling 32-bit process from a
64-bit MSYS2 runtime and vice versa, by letting the MSYS2 runtime look
for the cygwin-console-helper.exe of the "other architecture" in a
specific place (we choose /usr/libexec/, as it seems to be the
convention for helper .exe files that are not intended for public
consumption).

The 32-bit helper implicitly links to libgcc_s_dw2.dll and
libwinpthread-1.dll, so to avoid cluttering /usr/libexec/, we look for
the helped of the "other" architecture in the corresponding mingw32/ or
mingw64/ subdirectory.

Among other bugs, this strategy to handle Ctrl+C fixes the MSYS2 side of
the bug where interrupting `git clone https://...` would send the
spawned-off `git remote-https` process into the background instead of
interrupting it, i.e. the clone would continue and its progress would be
reported mercilessly to the console window without the user being able
to do anything about it (short of firing up the task manager and killing
the appropriate task manually).

Note that this special-handling is only necessary when *MSYS2* handles
the Ctrl+C event, e.g. when interrupting a process started from within
MinTTY or any other non-cmd-based terminal emulator. If the process was
started from within `cmd.exe`'s terminal window, child processes are
already killed appropriately upon Ctrl+C, by `cmd.exe` itself.

Also, we can't trust the processes to end it's subprocesses upon receiving
Ctrl+C. For example, `pip.exe` from `python-pip` doesn't kill the python
it lauches (it tries to but fails), and I noticed that in cmd it kills python
also correctly, which mean we should kill all the process using
`exit_process_tree`.

Co-authored-by: Naveen M K <[email protected]>
Signed-off-by: Johannes Schindelin <[email protected]>
This change is the equivalent to the change to the Ctrl+C handling we
just made.

Co-authored-by: Naveen M K <[email protected]>
Signed-off-by: Johannes Schindelin <[email protected]>
This code has been causing issues with SUBST and mapped network drives,
so add an option (defaulted to on) which can be used to disable it where
needed.  MSYS=nonativeinnerlinks
The MSYS2 packages lack the infrastructure to build those.

Signed-off-by: Johannes Schindelin <[email protected]>
Before symlinking libg.a, we need the symlink source `libmsys-2.0.a`: in
MSYS2, we copy by default (if we were creating Unix-style symlinks, the
target would not have to exist before symlinking, but when copying we do
need the source _right away_).

Signed-off-by: Johannes Schindelin <[email protected]>
When calling a non-MSys2 binary, all of the environment is converted from
POSIX to Win32, including the SHELL environment variable. In Git for
Windows, for example, `SHELL=/usr/bin/bash` is converted to
`SHELL=C:\Program Files\Git\usr\bin\bash.exe` when calling the `git.exe`
binary. This is appropriate because non-MSys2 binaries would not handle
POSIX paths correctly.

Under certain circumstances, however, `git.exe` calls an *MSys2* binary in
turn, such as `git config --edit` calling `vim.exe` unless Git is
configured to use another editor specifically.

Now, when this "improved vi" calls shell commands, it uses that $SHELL
variable *without quoting*, resulting in a nasty error:

	C:\Program: No such file or directory

Many other programs behave in the same manner, assuming that $SHELL does
not contain spaces and hence needs no quoting, unfortunately including
some of Git's own scripts.

Therefore let's make sure that $SHELL gets "posified" again when entering
MSys2 programs.

Earlier attempts by Git for Windows contributors claimed that adding
`SHELL` to the `conv_envvars` array does not have the intended effect.
These reports just missed that the `conv_start_chars` array (which makes
the code more performant) needs to be adjusted, too.

Note that we set the `immediate` flag to `true` so that the environment
variable is set immediately by the MSys2 runtime, i.e. not only spawned
processes will see the POSIX-ified `SHELL` variable, but the MSys2 runtime
*itself*, too.

This fixes git-for-windows/git#542,
git-for-windows/git#498, and
git-for-windows/git#468.

Signed-off-by: Johannes Schindelin <[email protected]>
MSYS2 recently introduced that hack where the ORIGINAL_PATH variable is
set to the original PATH value in /etc/profile, unless previously set.
In Git for Windows' default mode, that ORIGINAL_PATH value is the used
to define the PATH variable explicitly.

So far so good.

The problem: when calling from inside an MSYS2 process (such as Bash) a
MINGW executable (such as git.exe) that then calls another MSYS2
executable (such as bash.exe), that latter call will try to re-convert
ORIGINAL_PATH after the previous call converted ORIGINAL_PATH from POSIX
to Windows paths. And this conversion may very well fail, e.g. when the
path list contains mixed semicolons and colons.

So let's just *force* the MSYS2 runtime to handle ORIGINAL_PATH in the
same way as the PATH variable (which conversion works, as we know).

Signed-off-by: Johannes Schindelin <[email protected]>
We are currently trying to move our cygwin build environment closer
to cygwin and some autotools/bash based build systems call "uname -s"
to figure out the OS and in many cases only handle the cygwin case, so
we have to patch them.

With this instead of patching we can set MSYSTEM=CYGWIN and change
uname output that way.

The next step would be to always output CYGWIN in an msys env by default,
but for now this allows us to get rid of all the patches without
affecting users.
There is a difference between an empty value and an unset environment
variable. We should not confuse both; If the user wants to unset an
environment variable, they can certainly do so (unsetenv(3), or in the
shell: 'unset ABC').

This fixes Git's t3301-notes.sh, which overrides environment variables
with empty values.

Signed-off-by: Johannes Schindelin <[email protected]>
We just disabled the code that skips environment variables whose values
are empty.

However, this code was introduced a long time ago into Cygwin in
d6b1ac7 (* environ.cc (build_env): Don't put an empty environment
variable into the environment.  Optimize use of "len". * errno.cc
(ERROR_MORE_DATA): Translate to EMSGSIZE rather than EAGAIN.,
2006-09-07), seemingly without any complaints.

Meaning: There might very well be use cases out there where it makes
sense to skip empty-valued environment variables.

Therefore, it seems like a good idea to have a "knob" to turn it back
on. With this commit, we introduce such a knob: by setting
`noemptyenvvalues` the `MSYS` variable (or appending it if that variable
is already set), users can tell the MSYS2 runtime to behave just like in
the olden times.

Signed-off-by: Johannes Schindelin <[email protected]>
With this commit, you can call

	MSYS=noemptyenvvalues my-command

and it does what is expected: to pass no empty-valued environment
variables to `my-command`.

Signed-off-by: Johannes Schindelin <[email protected]>
It frequently leads to problems when trying, say, to call from MSYS2's
Bash into Cygwin's or Git for Windows', merely because sharing that data
is pretty finicky.

For example, using the MSYS2' Bash using the MSYS2 runtime version that
is current at time of writing, trying to call Cygwin's programs fails
in manners like this:

    $ /c/cygwin64/bin/uname -r
      0 [main] uname (9540) child_copy: cygheap read copy failed, 0x800000000..0x800010BE0, done 0, windows pid 9540, Win32 error 6
    680 [main] uname 880 C:\cygwin64\bin\uname.exe: *** fatal error - couldn't create signal pipe, Win32 error 5

with the rather misleading exit code 127 (a code which is reserved to
indicate that a command was not found).

Let's just treat the MSYS2 runtime and the Cygwin runtime as completely
incompatible with one another, by virtue of using a different
magic constant than merely `CHILD_INFO_MAGIC`.

By using the msys2-runtime commit to modify that magic constant, we can
even spawn programs using a different MSYS2 runtime (such as Git for
Windows') because the commit serves as the tell-tale whether two MSYS2
runtime versions are compatible with each other. To support building in
the MSYS2-packages repository (where we do not check out the
`msys2-runtime` but instead check out Cygwin and apply patches on top),
let's accept a hard-coded commit hash as `./configure` option.

One consequence is that spawned MSYS processes using a different MSYS2
runtime will not be visible as such to the parent process, i.e. they
cannot share any resources such as pseudo terminals. But that's okay,
they are simply treated as if they were regular Win32 programs.

Note: We have to use a very rare form of encoding the brackets in the
`expr` calls: quadrigraphs (for a thorough explanation, see
https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.70/html_node/Quadrigraphs.html#Quadrigraphs).
This is necessary because it is apparently impossible to encode brackets
in `configure.ac` files otherwise.

Signed-off-by: Johannes Schindelin <[email protected]>
Having just Cygwin's version in the output of `uname` is not helpful, as
both MSYS2 as well as Git for Windows release intermediate versions of
the MSYS2 runtime much more often than Cygwin runtime versions are
released.

Signed-off-by: Johannes Schindelin <[email protected]>
Reportedly a very recent internal build of Windows 11 once again changed
the current working directory logic a bit, and Cygwin's "magic" (or:
"technologically sufficiently advanced") code needs to be adjusted
accordingly.

In particular, the following assembly code can be seen:

ntdll!RtlpReferenceCurrentDirectory

  598 00000001`800c6925 488d0db4cd0f00  lea     rcx,[ntdll!FastPebLock (00000001`801c36e0)]
  583 00000001`800c692c 4c897810        mov     qword ptr [rax+10h],r15
  588 00000001`800c6930 0f1140c8        movups  xmmword ptr [rax-38h],xmm0
  598 00000001`800c6934 e82774f4ff      call    ntdll!RtlEnterCriticalSection

The change necessarily looks a bit different than 4840a56 (Cygwin:
Adjust CWD magic to accommodate for the latest Windows previews,
2023-05-22): The needle `\x48\x8d\x0d` is already present, as the first
version of the hack after Windows 8.1 was released. In that code,
though, the `call` to `RtlEnterCriticalSection` followed the `lea`
instruction immediately, but now there are two more instructions
separating them.

Note: In the long run, we may very well want to follow the insightful
suggestion by a helpful Windows kernel engineer who pointed out that it
may be less fragile to implement kind of a disassembler that has a
better chance to adapt to the ever-changing code of
`ntdll!RtlpReferenceCurrentDirectory` by skipping uninteresting
instructions such as `mov %rsp,%rax`, `mov %rbx,0x20(%rax)`, `push %rsi`
`sub $0x70,%rsp`, etc, and focuses on finding the `lea`, `call
ntdll!RtlEnterCriticalSection` and `mov ..., rbx` instructions, much
like it was prototyped out for ARM64 at
https://gist.github.com/jeremyd2019/aa167df0a0ae422fa6ebaea5b60c80c9

Signed-off-by: Johannes Schindelin <[email protected]>
This commit starts the rebase of e997f85 to 98a63f7b94
Seeing as Git for Windows tries to stay close to the upstream MSYS2
project, it makes sense to integrate their patches verbatim.

Signed-off-by: Johannes Schindelin <[email protected]>
dscho and others added 14 commits July 5, 2025 20:31
…unction

This code is way too useful _not_ to make it reusable.

While at it, improve on the timeout logic to be quite a bit more
precise.

Signed-off-by: Johannes Schindelin <[email protected]>
It used only 3 spaces, when 4 were called for.

Signed-off-by: Johannes Schindelin <[email protected]>
There is actually no need to have a flashing window just to capture the
output of the command: using the trick (use `Run()`, pipe to `clip` and
then use `A_Clipboard`) from https://stackoverflow.com/a/32298415 makes
it possible to hide the console window _and_ capture the output.

Signed-off-by: Johannes Schindelin <[email protected]>
The `uname` executable is not on the `PATH` by default. Let's use the
Git alias trick to execute it, then.

Signed-off-by: Johannes Schindelin <[email protected]>
When the command fails, we should not simply continue, mistaking an
empty string for being the valid output of a successful run.

Signed-off-by: Johannes Schindelin <[email protected]>
The Ctrl+C way to interrupt run-away processes is highly important. It
was recently broken in multiple ways in the Cygwin runtime (and hence
also in the MSYS2 runtime).

Let's add some integration tests that will catch regressions.

It is admittedly less than ideal to add _integration_ tests; While
imitating exactly what the end user does looks appealing at first,
excellent tests impress by how quickly they allow regressions not only
to be identified but also to be fixed. Even worse: all integration
tests, by virtue of working in a broader environment than, say, unit
tests, incur the price of sometimes catching unactionable bugs, i.e.
bugs in software that is both outside of our control as well as not the
target of our testing at all.

Nevertheless, seeing as Cygwin did not add any unit tests for those
Ctrl+C fixes (which is understandable, given how complex testing for
Ctrl+C without UI testing would be), it is better to have integration
tests than no tests at all.

So here goes: This commit introduces a test that verifies that the MSYS2
`sleep.exe` can be interrupted when run from PowerShell in a Windows
Terminal. This was broken in v3.6.0 and fixed in 7674c51 (Cygwin:
console: Set ENABLE_PROCESSED_INPUT when disable_master_thread,
2025-07-01).

Signed-off-by: Johannes Schindelin <[email protected]>
This imitates Unix shell's `$(...)` behavior better and is eminently
more useful when capturing, say, the output of `cygpath`.

Signed-off-by: Johannes Schindelin <[email protected]>
I want to add an integration test that clones a repository via SSH.
Unfortunately, I have not found a better way than to run OpenSSH for
Windows' `sshd.exe` in debug mode, in which case every successful
connection will open a terminal window.

Let's be prepared for these annoying extra windows by forcefully
activating the desired window as needed.

This change is admittedly a bit intrusive; I did not find any more
elegant way to achieve the same result, though.

Signed-off-by: Johannes Schindelin <[email protected]>
This was the actual use case that was broken and necessitated the fix in
7674c51 (Cygwin: console: Set ENABLE_PROCESSED_INPUT when
disable_master_thread, 2025-07-01).

It does require an SSH server, which Git for Windows no longer ships.
Therefore, this test uses the `sshd.exe` of OpenSSH for Windows
(https://github.com/powershell/Win32-OpenSSH) in conjunction with Git
for Windows' `ssh.exe` (because using OpenSSH for Windows' variant of
`ssh.exe` would not exercise the MSYS2 runtime and therefore not
demonstrate a regression, should it surface in the future).

To avoid failing the test because OpenSSH for Windows is not available,
the test case is guarded by the environment variable
`OPENSSH_FOR_WINDOWS_DIRECTORY` which needs to point to a directory that
contains a working `sshd.exe`.

Signed-off-by: Johannes Schindelin <[email protected]>
In the previous commit, I added a new UI test that generates a somewhat
large repository for testing the clone via SSH. Since that repository is
created in the test directory, that would inflate the `ui-tests` build
artifact rather dramatically. So let's create the repository outside of
that directory.

Signed-off-by: Johannes Schindelin <[email protected]>
…thread

With the commit 476135a24506, set_input_mode() reffers to the flag
disable_master_thread in tty::cygwin mode. So it is necessary to call
set_input_mode() after changing disable_master_thread flag. However,
the commit 476135a24506 was missing that.

With this patch, set_input_mode() is called after changing the flag
disable_master_thread, if the console input mode is tty::cygwin.

Fixes: 476135a24506 ("Cygwin: console: Set ENABLE_PROCESSED_INPUT when disable_master_thread");
Signed-off-by: Takashi Yano <[email protected]>
Cherry-picked-from: 65a48c7202 (Cygwin: console: Call set_input_mode() after changing disable_master_thread, 2025-07-03)
Signed-off-by: Johannes Schindelin <[email protected]>
The fixes of 7674c51 (Cygwin: console: Set ENABLE_PROCESSED_INPUT
when disable_master_thread, 2025-07-01) were unfortunately not complete;
There were still a couple of edge cases where Ctrl+C was unable to
interrupt processes. Let's add a demonstration of that issue.

Signed-off-by: Johannes Schindelin <[email protected]>
In 0ae6a6f (Cygwin: pipe: Fix SSH hang with non-cygwin pipe reader,
2025-06-27), a quite problematic bug was fixed where somewhat large-ish
repositories could not be cloned via SSH anymore.

This fix was not accompanied by a corresponding test case in Cygwin's
test suite, i.e. there is no automated way to ensure that there won't be
any regressions on that bug (and therefore it would fall onto end users
to deal with those).

This constitutes what Michael C. Feathers famously characterized as
"legacy code" in his book "Working Effectively with Legacy Code":

    To me, legacy code is simply code without tests. I've gotten some
    grief for this definition. What do tests have to do with whether
    code is bad? To me, the answer is straightforward, and it is a point
    that I elaborate throughout the book:

	Code without tests is bad code. It doesn’t matter how well
	written it is; it doesn’t matter how pretty or object-oriented
	or well-encapsulated it is. With tests, we can change the
	behavior of our code quickly and verifiably. Without them, we
	really don’t know if our code is getting better or worse.

Just to drive this point home, let me pull out Exhibit A: The bug fix in
question, which is the latest (and hopefully last) commit in a _long_
chain of bug fixes that fix bugs introduced by preceding bug fixes:

- 9e4d308 (Cygwin: pipe: Adopt FILE_SYNCHRONOUS_IO_NONALERT flag for
  read pipe., 2021-11-10) fixed a bug where Cygwin hung by mistake while
  piping output from one .NET program as input to another .NET program
  (potentially introduced by 3651990 (Cygwin: pipe: Avoid false EOF
  while reading output of C# programs., 2021-11-07), which was itself a
  bug fix). It introduced a bug that was fixed by...
- fc691d0 (Cygwin: pipe: Make sure to set read pipe non-blocking for
  cygwin apps., 2024-03-11). Which introduced a bug that was purportedly
  fixed by...
- 7ed9adb (Cygwin: pipe: Switch pipe mode to blocking mode by
  default, 2024-09-05). Which introduced a bug that was fixed by...
- cbfaeba (Cygwin: pipe: Fix incorrect write length in raw_write(),
  2024-11-06). Which introduced a bug that was fixed by... the SSH hang
  fix in 0ae6a6f (Cygwin: pipe: Fix SSH hang with non-cygwin pipe
  reader, 2025-06-27).

There is not only the common thread here that each of these bug fixes
introduced a new bug, but also the common thread that none of the
commits introduced new test cases into the test suite that could
potentially have helped prevent future breakages in this code.

So let's at least add an integration test here.

Side note: I am quite unhappy with introducing integration tests. I know
there are a lot of fans out there, but I cannot help wondering whether
they favor the convenience of writing tests quickly over the vast cost
of making debugging any regression a highly cumbersome and unenjoyable
affair (try single-stepping through a test case that requires several
processes to be orchestrated in unison). Also, integration tests have
the large price of introducing moving parts outside the code base that
is actually to be tested, opening the door for breakages caused by
software (or infrastructure, think: network glitches!) that are
completely outside the power or responsibility of the poor engineer
tasked with fixing the breakages. Nevertheless, I have been unable
despite days of trying to wrap my head around the issue to figure out a
way to reproduce the `fhandler_pipe_fifo::raw_write()` hang without
involving a MINGW `git.exe` and an MSYS2/Cygwin `ssh.exe`. So: It's the
best I could do with any reasonable amount of effort. It's better to
have integration tests that would demonstrate regressions than not
having any tests for that at all.

Signed-off-by: Johannes Schindelin <[email protected]>
... excluding the 1.23 release train that is currently marked as
pre-release.

Signed-off-by: Johannes Schindelin <[email protected]>
@dscho dscho closed this Mar 4, 2026
@dscho
dscho deleted the tmp branch March 4, 2026 06:43
dscho added a commit that referenced this pull request Jun 26, 2026
The Ctrl+C UI test launches OpenSSH for Windows' `sshd.exe` via
`Run` and then immediately types the `git clone` keystrokes into
the PowerShell window. On the current windows-2025 runners,
sshd's cold-start can take long enough that by the time `ssh`
attempts the TCP connect, the listening socket isn't bound yet;
the clone never produces `remote:`, the
`WaitForRegExInWindowsTerminal` for it times out, and the test
fails. This was the failure on attempt #1 of the latest CI run
on `fix-pcon-grandchild-cons0`.

Probe sshd with `ssh ... echo hi` via `RunWait` before letting
the clone proceed, sleeping 5 seconds between attempts and
giving up after a minute. The probe runs directly, not through
the Windows Terminal, so it does not perturb the WT buffer the
test is observing. Run the same probe again before the
verification clones, since the test `Run`s sshd a second time
there and could race that cold-start too.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 26, 2026
The Ctrl+C UI test starts up an OpenSSH-for-Windows `sshd.exe` to
exercise the SSH-based clone scenarios, and intentionally leaves it
running once the test script exits: it has no `Run` wrapper that
would tear it down, and the test does not own a clean shutdown path
for it. When `actions/upload-artifact` then tries to zip up the
`ui-tests` directory, it fails with `EPERM` on
`ui-tests/ctrl-c/ssh_host_rsa_key`, because `sshd.exe` still holds
an exclusive handle on the host key file, and the entire upload
step aborts. That is the failure observed on attempt #1 of the
latest CI run on `fix-pcon-grandchild-cons0`.

Stop any leftover `sshd.exe` instances before uploading. The runner
is ephemeral and dedicated to the job, so identifying the process
by name is safe; the actual termination still goes through
`Stop-Process -Id` to keep the kill targeted. `if: always()` mirrors
the upload step so the cleanup runs whether the test passed or
failed.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 26, 2026
The Ctrl+C UI test launches OpenSSH for Windows' `sshd.exe` via
`Run` and then immediately types the `git clone` keystrokes into
the PowerShell window. On the current windows-2025 runners,
sshd's cold-start can take long enough that by the time `ssh`
attempts the TCP connect the listening socket isn't bound yet;
the clone never produces `remote:`, the
`WaitForRegExInWindowsTerminal` for it times out, and the test
fails. This was the failure on attempt #1 of the latest CI run
on `fix-pcon-grandchild-cons0`.

A naive fix that probes sshd with `ssh ... echo hi` has a fatal
flaw given the test's `sshdOptions`: `sshd -d` (which the test
relies on for verbose debug logs) only handles a single
connection before exiting, so the probe itself consumes the slot
the actual clone needed and the clone then gets
`Connection refused`. That was the failure on
runs/28233821130.

Wait by polling `sshd.log` for the `Server listening on` message
instead; the probe stays out-of-band, leaves sshd's one
connection slot intact for the clone, and is essentially free
(500 ms poll, 60 s deadline). A `static` counter tracks how many
`Server listening on` lines have been acknowledged so far, so
any future call site (e.g. after the verification re-start)
would correctly wait for a fresh message past the previously
seen ones rather than matching a stale entry.

`Server listening on` is logged at `VERBOSE` and above; spell
out `LogLevel VERBOSE` in `sshd_config` so the new wait does not
silently depend on the command-line `-d` flags continuing to
imply that verbosity.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 26, 2026
The Ctrl+C UI test starts up an OpenSSH-for-Windows `sshd.exe` to
exercise the SSH-based clone scenarios, and intentionally leaves it
running once the test script exits: it has no `Run` wrapper that
would tear it down, and the test does not own a clean shutdown path
for it. When `actions/upload-artifact` then tries to zip up the
`ui-tests` directory, it fails with `EPERM` on
`ui-tests/ctrl-c/ssh_host_rsa_key`, because `sshd.exe` still holds
an exclusive handle on the host key file, and the entire upload
step aborts. That is the failure observed on attempt #1 of the
latest CI run on `fix-pcon-grandchild-cons0`.

Stop any leftover `sshd.exe` instances before uploading. The runner
is ephemeral and dedicated to the job, so identifying the process
by name is safe; the actual termination still goes through
`Stop-Process -Id` to keep the kill targeted. `if: always()` mirrors
the upload step so the cleanup runs whether the test passed or
failed.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 26, 2026
The Ctrl+C UI test launches OpenSSH for Windows' `sshd.exe` via
`Run` and then immediately types the `git clone` keystrokes into
the PowerShell window. On the current windows-2025 runners,
sshd's cold-start can take long enough that by the time `ssh`
attempts the TCP connect the listening socket isn't bound yet;
the clone never produces `remote:`, the
`WaitForRegExInWindowsTerminal` for it times out, and the test
fails. This was the failure on attempt #1 of the first CI run
on `fix-pcon-grandchild-cons0`.

A naive fix that probes sshd with `ssh ... echo hi` has a fatal
flaw given the test's `sshdOptions`: `sshd -d` (which the test
relies on for verbose debug logs) only handles a single
connection before exiting, so the probe itself consumes the slot
the actual clone needed and the clone then gets
`Connection refused`. That was the failure on
runs/28233821130.

Wait by polling `sshd.log` for the `Server listening on` message
instead; the probe stays out-of-band, leaves sshd's one
connection slot intact for the clone, and is essentially free
(500 ms poll, 60 s deadline). A `static` counter tracks how many
`Server listening on` lines have been acknowledged so far, so
any future call site (e.g. after the verification re-start)
would correctly wait for a fresh message past the previously
seen ones rather than matching a stale entry.

Spell out the logging configuration this poll depends on, in two
places. First, pass an absolute path to `-E`: the relative
`-E sshd.log` that was there before silently produced no log
file at all when reproduced locally with OpenSSH for Windows
9.8.3.0p2 (the version the workflow installs); sshd reports no
error on its own stderr/stdout and the file is never created
anywhere reachable, so `WaitForSshd` would time out at 60
seconds. This was the failure on runs/28243902161. Second, set
`LogLevel VERBOSE` in `sshd_config`: `Server listening on` is
logged at `VERBOSE` and above, and spelling it out keeps the new
wait from silently depending on the command-line `-d` flags
continuing to imply that verbosity.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 26, 2026
The Ctrl+C UI test starts up an OpenSSH-for-Windows `sshd.exe` to
exercise the SSH-based clone scenarios, and intentionally leaves it
running once the test script exits: it has no `Run` wrapper that
would tear it down, and the test does not own a clean shutdown path
for it. When `actions/upload-artifact` then tries to zip up the
`ui-tests` directory, it fails with `EPERM` on
`ui-tests/ctrl-c/ssh_host_rsa_key`, because `sshd.exe` still holds
an exclusive handle on the host key file, and the entire upload
step aborts. That is the failure observed on attempt #1 of the
latest CI run on `fix-pcon-grandchild-cons0`.

Stop any leftover `sshd.exe` instances before uploading. The runner
is ephemeral and dedicated to the job, so identifying the process
by name is safe; the actual termination still goes through
`Stop-Process -Id` to keep the kill targeted. `if: always()` mirrors
the upload step so the cleanup runs whether the test passed or
failed.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 26, 2026
The Ctrl+C UI test launches OpenSSH for Windows' `sshd.exe` via
`Run` and then immediately types the `git clone` keystrokes into
the PowerShell window. On the current windows-2025 runners,
sshd's cold-start can take long enough that by the time `ssh`
attempts the TCP connect the listening socket isn't bound yet;
the clone never produces `remote:`, the
`WaitForRegExInWindowsTerminal` for it times out, and the test
fails. This was the failure on attempt #1 of the first CI run
on `fix-pcon-grandchild-cons0`.

Use sshd's own readiness signal. Per OpenSSH's `sshd.c`, the
`PidFile` is `fopen`/`fprintf`/`fclose`'d immediately before the
accept loop, after the listen sockets are bound and the sigterm
handler is installed; its existence is a definitive "ready to
accept" signal. The file is closed after the write, so there is
no buffering window and no exclusive lock for a poller to fight.
Configure `PidFile` in `sshd_config`, drop `-d -d -d` (sshd
explicitly suppresses `PidFile` writes in `debug_flag` mode, see
`if (options.pid_file != NULL && !debug_flag)` in `sshd.c`), and
poll `sshd.pid` for both existence and non-empty content from
`WaitForSshd`.

Dropping `-d` has the deliberate side effect of making sshd
multi-connection again. The previous attempts at fixing the
flake had to fight that constraint at every turn: an `ssh ...
echo hi` probe was abandoned because it consumed sshd's only
allowed connection before the actual clone could run
(runs/28233821130); a follow-up "poll sshd.log for `Server
listening on`" probe was abandoned because sshd's `-E` log file
is opened without share-read, so neither AHK's `FileRead`,
PowerShell's `Get-Content`, nor MSYS2's `grep.exe` can open it
while sshd is alive (runs/28243902161 — verified locally with
OpenSSH for Windows 9.8.3.0p2). Multi-connection sshd lets the
verification-clone path also stop being a single-shot dance, but
the existing `Run` plus `restart sshd inside the retry loop`
code is left as-is here; it is now a harmless no-op rather than
load-bearing.

The `-E sshd.log` argument is kept (with the same absolute
`workTree`-anchored path as before) so the debug log is still
captured by `Upload test results` for post-mortem analysis; the
new probe does not depend on its contents. `LogLevel VERBOSE` in
`sshd_config` is kept too, both because `Server listening on` is
useful at that level and because making the logging
configuration explicit shouldn't depend on which command-line
flags happen to be set.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 26, 2026
The Ctrl+C UI test starts up an OpenSSH-for-Windows `sshd.exe` to
exercise the SSH-based clone scenarios, and intentionally leaves it
running once the test script exits: it has no `Run` wrapper that
would tear it down, and the test does not own a clean shutdown path
for it. When `actions/upload-artifact` then tries to zip up the
`ui-tests` directory, it fails with `EPERM` on
`ui-tests/ctrl-c/ssh_host_rsa_key`, because `sshd.exe` still holds
an exclusive handle on the host key file, and the entire upload
step aborts. That is the failure observed on attempt #1 of the
latest CI run on `fix-pcon-grandchild-cons0`.

Stop any leftover `sshd.exe` instances before uploading. The runner
is ephemeral and dedicated to the job, so identifying the process
by name is safe; the actual termination still goes through
`Stop-Process -Id` to keep the kill targeted. `if: always()` mirrors
the upload step so the cleanup runs whether the test passed or
failed.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 26, 2026
The Ctrl+C UI test launches OpenSSH for Windows' `sshd.exe` via
`Run` and then immediately types the `git clone` keystrokes into
the PowerShell window. On the current windows-2025 runners,
sshd's cold-start can take long enough that by the time `ssh`
attempts the TCP connect the listening socket isn't bound yet;
the clone never produces `remote:`, the
`WaitForRegExInWindowsTerminal` for it times out, and the test
fails. This was the failure on attempt #1 of the first CI run
on `fix-pcon-grandchild-cons0`.

Use sshd's own readiness signal. Per OpenSSH's `sshd.c`, the
`PidFile` is `fopen`/`fprintf`/`fclose`'d immediately before the
accept loop, after the listen sockets are bound and the sigterm
handler is installed; its existence is a definitive "ready to
accept" signal. The file is closed after the write, so there is
no buffering window and no exclusive lock for a poller to fight.
Configure `PidFile` in `sshd_config`, drop `-d -d -d` (sshd
explicitly suppresses `PidFile` writes in `debug_flag` mode, see
`if (options.pid_file != NULL && !debug_flag)` in `sshd.c`), and
poll `sshd.pid` for both existence and non-empty content from
`WaitForSshd`.

Dropping `-d` has the deliberate side effect of making sshd
multi-connection again. The previous attempts at fixing the
flake had to fight that constraint at every turn: an `ssh ...
echo hi` probe was abandoned because it consumed sshd's only
allowed connection before the actual clone could run
(runs/28233821130); a follow-up "poll sshd.log for `Server
listening on`" probe was abandoned because sshd's `-E` log file
is opened without share-read, so neither AHK's `FileRead`,
PowerShell's `Get-Content`, nor MSYS2's `grep.exe` can open it
while sshd is alive (runs/28243902161, verified locally with
OpenSSH for Windows 9.8.3.0p2). Multi-connection sshd lets the
verification-clone path also stop being a single-shot dance, but
the existing `Run` plus `restart sshd inside the retry loop`
code is left as-is here; it is now a harmless no-op rather than
load-bearing.

The flip side of long-lived sshd is that it now outlives the
test script's body, and the next thing the script does is
`CleanUpWorkTree` which `DirDelete`s the worktree out from under
sshd's still-open `sshd.pid` and `sshd.log` handles. That hangs
on Windows (runs/28256992298, observed locally). Stop sshd via
the PID we just learned to read before exiting the `if` block,
so the worktree is releasable by the time `CleanUpWorkTree`
runs.

The `-E sshd.log` argument is kept (with the same absolute
`workTree`-anchored path as before) so the debug log is still
captured by `Upload test results` for post-mortem analysis; the
new probe does not depend on its contents. `LogLevel VERBOSE` in
`sshd_config` is kept too, both because `Server listening on` is
useful at that level and because making the logging
configuration explicit shouldn't depend on which command-line
flags happen to be set.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 26, 2026
The Ctrl+C UI test starts up an OpenSSH-for-Windows `sshd.exe` to
exercise the SSH-based clone scenarios, and intentionally leaves it
running once the test script exits: it has no `Run` wrapper that
would tear it down, and the test does not own a clean shutdown path
for it. When `actions/upload-artifact` then tries to zip up the
`ui-tests` directory, it fails with `EPERM` on
`ui-tests/ctrl-c/ssh_host_rsa_key`, because `sshd.exe` still holds
an exclusive handle on the host key file, and the entire upload
step aborts. That is the failure observed on attempt #1 of the
latest CI run on `fix-pcon-grandchild-cons0`.

Stop any leftover `sshd.exe` instances before uploading. The runner
is ephemeral and dedicated to the job, so identifying the process
by name is safe; the actual termination still goes through
`Stop-Process -Id` to keep the kill targeted. `if: always()` mirrors
the upload step so the cleanup runs whether the test passed or
failed.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 26, 2026
The Ctrl+C UI test launches OpenSSH for Windows' `sshd.exe` via
`Run` and then immediately types the `git clone` keystrokes into
the PowerShell window. On the current windows-2025 runners,
sshd's cold-start can take long enough that by the time `ssh`
attempts the TCP connect the listening socket isn't bound yet;
the clone never produces `remote:`, the
`WaitForRegExInWindowsTerminal` for it times out, and the test
fails. This was the failure on attempt #1 of the first CI run
on `fix-pcon-grandchild-cons0`.

Use sshd's own readiness signal. Per OpenSSH's `sshd.c`, the
`PidFile` is `fopen`/`fprintf`/`fclose`'d immediately before the
accept loop, after the listen sockets are bound and the sigterm
handler is installed; its existence is a definitive "ready to
accept" signal. The file is closed after the write, so there is
no buffering window and no exclusive lock for a poller to fight.
Configure `PidFile` in `sshd_config`, drop `-d -d -d` (sshd
explicitly suppresses `PidFile` writes in `debug_flag` mode, see
`if (options.pid_file != NULL && !debug_flag)` in `sshd.c`), and
poll `sshd.pid` for both existence and non-empty content from
`WaitForSshd`.

Dropping `-d` also removes its "process one connection and exit"
side effect; previous attempts at fixing the flake had to fight
that constraint at every turn. An `ssh ... echo hi` probe was
abandoned because it consumed sshd's only allowed connection
before the actual clone could run (runs/28233821130); a
follow-up "poll sshd.log for `Server listening on`" probe was
abandoned because sshd's `-E` log file is opened without
share-read, so neither AHK's `FileRead`, PowerShell's
`Get-Content`, nor MSYS2's `grep.exe` can open it while sshd is
alive (runs/28243902161, verified locally with OpenSSH for
Windows 9.8.3.0p2).

The flip side of long-lived sshd is that sshd outlives the test
script body, and the next thing the script does is
`CleanUpWorkTree` which `DirDelete`s the worktree out from under
sshd's still-open `sshd.pid` and `sshd.log` handles. That hangs
on Windows (observed in runs/28256992298 and locally). Stopping
just the PidFile-named PID is not enough either: the existing
"Re-start sshd" sites at the verification clone and inside the
retry loop launch additional `sshd.exe` instances that survive
along with the original, and the PidFile only ever holds the
most recently written PID. Enumerate all `sshd*.exe` processes
whose `ExecutablePath` lives under the test's OpenSSH directory
via `Win32_Process`, `ProcessClose` each one, and wait for it to
exit before letting `CleanUpWorkTree` proceed. The WMI filter on
both name and executable path keeps the kill scoped to our test
and away from any system OpenSSH service on the runner.

The `-E sshd.log` argument is kept (with the same absolute
`workTree`-anchored path as before) so the debug log is still
captured by `Upload test results` for post-mortem analysis; the
new probe does not depend on its contents. `LogLevel VERBOSE` in
`sshd_config` is kept too, both because `Server listening on` is
useful at that level and because making the logging
configuration explicit shouldn't depend on which command-line
flags happen to be set.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 26, 2026
The Ctrl+C UI test starts up an OpenSSH-for-Windows `sshd.exe` to
exercise the SSH-based clone scenarios, and intentionally leaves it
running once the test script exits: it has no `Run` wrapper that
would tear it down, and the test does not own a clean shutdown path
for it. When `actions/upload-artifact` then tries to zip up the
`ui-tests` directory, it fails with `EPERM` on
`ui-tests/ctrl-c/ssh_host_rsa_key`, because `sshd.exe` still holds
an exclusive handle on the host key file, and the entire upload
step aborts. That is the failure observed on attempt #1 of the
latest CI run on `fix-pcon-grandchild-cons0`.

Stop any leftover `sshd.exe` instances before uploading. The runner
is ephemeral and dedicated to the job, so identifying the process
by name is safe; the actual termination still goes through
`Stop-Process -Id` to keep the kill targeted. `if: always()` mirrors
the upload step so the cleanup runs whether the test passed or
failed.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 27, 2026
The Ctrl+C UI test starts up an OpenSSH-for-Windows `sshd.exe` to
exercise the SSH-based clone scenarios, and intentionally leaves it
running once the test script exits: it has no `Run` wrapper that
would tear it down, and the test does not own a clean shutdown path
for it. When `actions/upload-artifact` then tries to zip up the
`ui-tests` directory, it fails with `EPERM` on
`ui-tests/ctrl-c/ssh_host_rsa_key`, because `sshd.exe` still holds
an exclusive handle on the host key file, and the entire upload
step aborts. That is the failure observed on attempt #1 of the
latest CI run on `fix-pcon-grandchild-cons0`.

Stop any leftover `sshd.exe` instances before uploading. The runner
is ephemeral and dedicated to the job, so identifying the process
by name is safe; the actual termination still goes through
`Stop-Process -Id` to keep the kill targeted. `if: always()` mirrors
the upload step so the cleanup runs whether the test passed or
failed.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
dscho added a commit that referenced this pull request Jun 27, 2026
The Ctrl+C UI test launches OpenSSH for Windows' `sshd.exe` via
`Run` and then immediately types the `git clone` keystrokes into
the PowerShell window. On the current windows-2025 runners,
sshd's cold-start can take long enough that by the time `ssh`
attempts the TCP connect the listening socket isn't bound yet;
the clone never produces `remote:`, the
`WaitForRegExInWindowsTerminal` for it times out, and the test
fails. This was the failure on attempt #1 of the first CI run
on `fix-pcon-grandchild-cons0`.

Use sshd's own readiness signal. Per OpenSSH's `sshd.c`, the
`PidFile` is `fopen`/`fprintf`/`fclose`'d immediately before the
accept loop, after the listen sockets are bound and the sigterm
handler is installed; its existence is a definitive "ready to
accept" signal. The file is closed after the write, so there is
no buffering window and no exclusive lock for a poller to fight.
Configure `PidFile` in `sshd_config`, drop `-d -d -d` (sshd
explicitly suppresses `PidFile` writes in `debug_flag` mode, see
`if (options.pid_file != NULL && !debug_flag)` in `sshd.c`), and
poll `sshd.pid` for both existence and non-empty content from
`WaitForSshd`.

Dropping `-d` also removes its "process one connection and exit"
side effect; previous attempts at fixing the flake had to fight
that constraint at every turn. An `ssh ... echo hi` probe was
abandoned because it consumed sshd's only allowed connection
before the actual clone could run (runs/28233821130); a
follow-up "poll sshd.log for `Server listening on`" probe was
abandoned because sshd's `-E` log file is opened without
share-read, so neither AHK's `FileRead`, PowerShell's
`Get-Content`, nor MSYS2's `grep.exe` can open it while sshd is
alive (runs/28243902161, verified locally with OpenSSH for
Windows 9.8.3.0p2).

The flip side of long-lived sshd is that sshd outlives the test
script body, and the next thing the script does is
`CleanUpWorkTree` which `DirDelete`s the worktree out from under
sshd's still-open `sshd.pid` and `sshd.log` handles. That hangs
on Windows (observed in runs/28256992298 and locally). Stopping
just the PidFile-named PID is not enough either: the existing
"Re-start sshd" sites at the verification clone and inside the
retry loop launch additional `sshd.exe` instances that survive
along with the original, and the PidFile only ever holds the
most recently written PID. Enumerate all `sshd*.exe` processes
whose `ExecutablePath` lives under the test's OpenSSH directory
via `Win32_Process`, `ProcessClose` each one, and wait for it to
exit before letting `CleanUpWorkTree` proceed. The WMI filter on
both name and executable path keeps the kill scoped to our test
and away from any system OpenSSH service on the runner.

The `-E sshd.log` argument is kept (with the same absolute
`workTree`-anchored path as before) so the debug log is still
captured by `Upload test results` for post-mortem analysis; the
new probe does not depend on its contents. `LogLevel VERBOSE` in
`sshd_config` is kept too, both because `Server listening on` is
useful at that level and because making the logging
configuration explicit shouldn't depend on which command-line
flags happen to be set.

Assisted-by: Opus 4.7
Signed-off-by: Johannes Schindelin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.