|
| 1 | +# Agent Instructions for MINGW-packages |
| 2 | + |
| 3 | +Git for Windows is built on top of MSYS2, which provides the Unix |
| 4 | +build environment (bash, make, autotools, Perl, etc.) and the |
| 5 | +package management infrastructure (pacman, makepkg). The Git for |
| 6 | +Windows SDK is a full MSYS2 installation with additional tools for |
| 7 | +building Git for Windows itself. |
| 8 | + |
| 9 | +MSYS2 has two classes of packages: MSYS packages (which depend on |
| 10 | +the MSYS2 runtime, `msys-2.0.dll`, a Cygwin fork) and MINGW |
| 11 | +packages (which produce native Win32/Win64 binaries with no MSYS2 |
| 12 | +runtime dependency). This repository contains MINGW packages. The |
| 13 | +build tool is `makepkg-mingw`, not `makepkg`. |
| 14 | + |
| 15 | +## Building packages |
| 16 | + |
| 17 | +MINGW builds need the target toolchain on PATH. In PowerShell: |
| 18 | + |
| 19 | + $env:MSYSTEM = "MINGW64" |
| 20 | + $env:PATH = "<MSYS-root>\mingw64\bin;<MSYS-root>\usr\bin;$env:PATH" |
| 21 | + $env:HOME = $env:USERPROFILE |
| 22 | + bash -c "cd /path/to/package && makepkg-mingw -s 2>&1" |
| 23 | + |
| 24 | +Do not use `bash -l` or `bash --login`; login shells may hang in |
| 25 | +Git for Windows SDK environments. |
| 26 | + |
| 27 | +Use `makepkg-mingw -s` to install missing dependencies |
| 28 | +automatically. Use `--nocheck` to skip the test suite, `--cleanbuild` |
| 29 | +to force a clean rebuild, and `--skippgpcheck` to skip GPG signature |
| 30 | +verification. Use `makepkg-mingw -o` (extract and prepare only) |
| 31 | +to validate that patches apply cleanly without waiting for a full |
| 32 | +compile. |
| 33 | + |
| 34 | +When a package uses git sources, `updpkgsums` must be run with |
| 35 | +`core.autoCRLF=false` in the Git configuration. Otherwise the |
| 36 | +generated `.tar` archive is checksummed with CRLF line endings |
| 37 | +and CI (which uses LF) will fail the validity check. Set the |
| 38 | +environment variable in PowerShell before invoking bash: |
| 39 | + |
| 40 | + $env:GIT_CONFIG_PARAMETERS = "'core.autoCRLF=false'" |
| 41 | + bash -c "cd /path/to/package && updpkgsums" |
| 42 | + |
| 43 | +## Running tests without rebuilding |
| 44 | + |
| 45 | +After a successful build (even with `--nocheck`), the build directory |
| 46 | +at `src/build-<MSYSTEM>/` contains all compiled binaries and test |
| 47 | +infrastructure. Run individual tests or the full suite directly: |
| 48 | + |
| 49 | + cd src/build-MINGW64 |
| 50 | + make VERBOSE_FAILURE=1 TESTS='test_ocsp_cert_chain test_store' test |
| 51 | + |
| 52 | +To run the full suite (excluding a specific test): |
| 53 | + |
| 54 | + HARNESS_JOBS=8 make VERBOSE_FAILURE=1 TESTS=-test_symbol_presence test |
| 55 | + |
| 56 | +`HARNESS_JOBS` controls Perl Test::Harness parallelism. Without it, |
| 57 | +tests run sequentially, which can take over an hour for large suites |
| 58 | +like OpenSSL. A value of 8 is a reasonable default. |
| 59 | + |
| 60 | +## Perl $^O on Git for Windows |
| 61 | + |
| 62 | +Git for Windows recently stopped building its own Perl and now uses |
| 63 | +the MSYS2 version. Because MSYS2's runtime is a Cygwin fork, |
| 64 | +`/usr/bin/perl` reports `$^O` as `cygwin`, not `msys`. Any test |
| 65 | +skip guard that checks for `msys` (e.g. `skip if $^O =~ /msys/`) |
| 66 | +must also check for `cygwin`, or it will stop firing and the test |
| 67 | +will run unexpectedly. |
| 68 | + |
| 69 | +This is particularly dangerous for tests that open listening sockets |
| 70 | +(OCSP responders, HTTP servers, TFO listeners), because Windows |
| 71 | +Firewall will prompt for permission. On interactive machines this |
| 72 | +causes a modal dialog; on CI agents there is nobody to click |
| 73 | +"Allow", so the test hangs until the job times out. |
| 74 | + |
| 75 | +## The playground repository |
| 76 | + |
| 77 | +When upgrading a package to a new version, patches often fail to |
| 78 | +apply because the upstream context has changed. Rather than hand- |
| 79 | +editing hunks, create a standalone Git repository at `src/playground` |
| 80 | +inside the package directory and use it to rebase the patches: |
| 81 | + |
| 82 | +1. Import the old upstream tarball with Git's |
| 83 | + `contrib/fast-import/import-tars.perl` (run via |
| 84 | + `<MSYS-root>\usr\bin\perl`; the script can be downloaded from |
| 85 | + https://github.com/git/git/blob/HEAD/contrib/fast-import/import-tars.perl). |
| 86 | +2. Apply the existing `.patch` files as individual commits using |
| 87 | + `git am`. For patch files that lack a `git am`-format header, |
| 88 | + start `git am` with a properly formatted copy to capture |
| 89 | + authorship and subject, then when it fails (because the diff |
| 90 | + content is stale), apply the correct patch via `patch -p1`, |
| 91 | + `git add -A`, and `git am --continue`. Check for stray `.orig` |
| 92 | + files and remove them before or as part of the amend. |
| 93 | + (`--committer-date-is-author-date` is not needed; step 5 forces |
| 94 | + committer=author via fast-export/fast-import regardless.) |
| 95 | +3. Import the new upstream tarball into the same repo. |
| 96 | +4. `git rebase --onto <new-tag> <old-tag> <branch>` to replay the |
| 97 | + patches onto the new version. Resolve conflicts. |
| 98 | +5. Before exporting, verify committer matches author in every |
| 99 | + commit (to keep `.patch` files stable across Git versions): |
| 100 | + |
| 101 | + git log --format='%aN <%aE> %ai%n%cN <%cE> %ci' HEAD | uniq -u |
| 102 | + |
| 103 | + Each commit produces two consecutive lines (author, then |
| 104 | + committer). When they match, `uniq` collapses them and |
| 105 | + `uniq -u` suppresses the result, so empty output means all |
| 106 | + OIDs are stable. Use `HEAD` (not a range like |
| 107 | + `<base-tag>..HEAD`) so the import commit is checked too; a |
| 108 | + mismatched committer date there changes the OID of every |
| 109 | + descendant. If any lines appear, fix them with: |
| 110 | + |
| 111 | + git fast-export --no-data HEAD | \ |
| 112 | + awk '/^author /{a=$0} /^committer /{$0="committer " substr(a,8)} 1' | \ |
| 113 | + git fast-import --force --quiet |
| 114 | + |
| 115 | + Then update the tag and branch ref (`git checkout <branch>`). |
| 116 | +6. `git format-patch --no-signature -o ../.. <base-tag>` to export |
| 117 | + back to the PKGBUILD directory. |
| 118 | +7. Verify the round-trip: re-export `format-patch` from the |
| 119 | + playground and `git diff -I'^@@'` against the originals. Only |
| 120 | + commit OIDs, index lines, and `@@` offsets should differ. |
| 121 | + |
| 122 | +`patch -p1` supports fuzz matching that `git apply` does not. When |
| 123 | +`git am` or `git apply` fails on context lines, fall back to |
| 124 | +`patch -p1` and stage the result. |
| 125 | + |
| 126 | +Keep the playground around for the duration of the upgrade work. New |
| 127 | +fixes and patch adjustments are committed here, then re-exported with |
| 128 | +`git format-patch --no-signature -o ../.. <base-tag>`. Deleting and |
| 129 | +recreating it means re-importing tarballs, re-applying all patches, |
| 130 | +and re-resolving any conflicts from scratch. |
| 131 | + |
| 132 | +When an existing patch needs updating (e.g. a patch that introduces |
| 133 | +MSYS-specific handling needs to cover a new platform variant), amend |
| 134 | +the original commit in the playground rather than layering a new |
| 135 | +patch on top. Use `amend!` commits and |
| 136 | +`git rebase -i --autosquash` to fold the fix into the right commit, |
| 137 | +then re-export all patches. This keeps the patch series clean and |
| 138 | +makes the intent of each patch self-contained. |
| 139 | + |
| 140 | +## General workflow |
| 141 | + |
| 142 | +Use `git worktree add` with sparse checkout for testing dependent |
| 143 | +packages. Commit fixes in the worktree and `git cherry-pick` them |
| 144 | +into the main branch rather than copying files manually. |
0 commit comments