Skip to content

Add MSIX Installer#665

Open
shmuelie wants to merge 3 commits into
git-for-windows:mainfrom
shmuelie:add-msix-installer
Open

Add MSIX Installer#665
shmuelie wants to merge 3 commits into
git-for-windows:mainfrom
shmuelie:add-msix-installer

Conversation

@shmuelie

@shmuelie shmuelie commented Dec 10, 2025

Copy link
Copy Markdown

What

This PR introduces creating an MSIX package for Git for Windows, in addition to the existing installers.

Why?

MSIX has a number of advantages over traditional MSI/EXE based installers on Windows. While not an exhaustive list, a few that affect Git are:

  • Instead of modifying the PATH, App Aliases allow for a user to enable or disable individual applications from being "on the PATH".
  • While always installed for the current user, if a different user wants to install, the same files are re-used. This gives user level installation (no elevation required) while also not getting installed multiple times.
  • MSIX packages can easily declare dependencies on other MSIX packages, meaning tools that want to know if Git is installed can simply declare they need it. The PackageManager APIs are also much simpler to use than the various registry or file system tricks, tricks that won't work if the user installs to a non-standard location.
  • MSIX supports delta based updating where only the things that changed are downloaded to the user's machine.
  • MSIX includes various systems to handle updating for you, so no need to have a Windows Service that checks for updates and prompts the user.
  • Because MSIX packages are identified by their package identity and not their installation location, different Git installations can coexist without conflicting. The Alias system allows for picking which executables are found, even mixing and matching.

User Experience

After installation, the Start Menu shows entries for Git Bash, Git CMD, and Git GUI, grouped under "Git for Windows". Launching Git Bash opens a mintty terminal window identical to the traditional installer experience. Command-line usage via the execution aliases (git, bash, sh) works the same as a PATH-based installation.

Configuration Defaults

The MSIX package bakes in the following system gitconfig settings:

  • credential.helper manager (Git Credential Manager as the default credential helper)
  • core.fscache true
  • On 64-bit builds, pack.packSizeLimit is unset

The manifest declares desktop6:FileSystemWriteVirtualization and desktop6:RegistryWriteVirtualization as disabled and requests the unvirtualizedResources capability. This means the packaged etc/gitconfig is not virtualized — it lives at its real path and is writable by the user post-install, so changes made via git config --system persist in place. However, MSIX upgrades replace the package contents, so user customizations to the system gitconfig would need to be reapplied after updates. Users can avoid this by using --global config instead, which lives in their home directory outside the package.

Execution Aliases and Coexistence

The manifest registers execution aliases for git.exe, git-bash.exe, git-cmd.exe, git-gui.exe, bash.exe, sh.exe, and nano.exe. Each alias can be individually enabled or disabled by the user in Windows Settings (Settings → Apps → Advanced app settings → App execution aliases).

This means bash.exe and sh.exe will not automatically shadow WSL, Cygwin, or other installations — the user controls which aliases are active. If a regular Git for Windows installation is also present, the user can toggle which git.exe alias is active, or disable the MSIX aliases entirely to use the PATH-based installation.

System Gitconfig Discoverability

MSIX packages install to a per-user location under C:\Program Files\WindowsApps\... which is not a well-known fixed path. Tools like Visual Studio, VS Code, and SmartGit that look for Git at C:\Program Files\Git\etc\gitconfig will not find the MSIX-packaged gitconfig at that path. These tools would need to discover Git via the execution alias (where.exe git) and resolve the config path from there. This is a known gap compared to the traditional installer.

Known Issues and Limitations

  • No configuration UI during install. While the need for the "Add to PATH" option is gone (replaced by execution aliases), other installation options are not available.
  • Must be signed. Installing unsigned MSIX packages, while possible, is not user friendly (requires Developer Mode).

Building

Build the MSIX package from a Git for Windows SDK shell (MINGW64):

msix/release.sh [--output=<directory>] [--include-pdbs] <version>

For example:

msix/release.sh --output=/tmp 2.47.1.windows.1

This requires rsvg-convert (from mingw-w64-x86_64-librsvg) to generate the package asset images, and makeappx.exe from a Windows 10 SDK installation.

Installing Without Signing

MSIX packages must be signed to install normally. To install an unsigned package for testing, enable Developer Mode in Windows Settings (Settings → System → For developers → Developer Mode), then install with:

Add-AppxPackage -Path .\Git.GitforWindows_<version>_x64.msix

@shmuelie shmuelie force-pushed the add-msix-installer branch 2 times, most recently from 8f9cff5 to 9e28cd5 Compare March 4, 2026 21:51
@shmuelie shmuelie marked this pull request as ready for review March 4, 2026 22:02

@dscho dscho left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @shmuelie,

Thank you for working on this. MSIX packaging for Git for Windows is something that was attempted a couple of times, and I appreciate you picking it up. That said, this PR needs significant rework before I can consider merging it. Let me walk through the concerns.

Commit history. In Git for Windows we polish commits to tell a clean, compelling story. The current history reads like a lab notebook: "Initial prototype for MSIX creation", "Minor cleanup", "Initial release script", "Fix generated package name", "Fix manifest", followed by five Copilot-assisted fixup commits. Errors should be squashed into the commits that introduced them, not stacked on top. Please rework the branch into a small number of logical, self-contained commits that each do one thing correctly. For example, one commit could refactor portable/release.sh to separate out reusable parts, and the next one could add a minimal manifest template with the release.sh script to build an MSIX, another the asset generation (see below). Each commit message should explain why, not just what.

Committed image assets. The PR adds 8 PNG files under msix/Assets/. I would much rather see a small automation step that generates these from the git-for-windows.png (or git-for-windows.svg) already in the repo root at build time, resizing to the required dimensions. I notice that several of the committed PNGs share the same blob hash (3 files are identical at b5c5143, 2 more at fa651cf), which reinforces that these are mechanically derived. Committing generated binary artifacts that cannot easily be manually recreated or verified is something I try to avoid. If generating them at build time is truly not feasible, that needs justification. You could then still follow the example in gitforwindows.org where generated files are committed, but are accompanied with easy, reproducible steps to recreate them.

Configurability. Previous attempts at MSIX/Store packaging ran into a fundamental problem: the Git for Windows installer allows extensive configuration (default editor, line endings, PATH modifications, credential helper, terminal emulator, etc.), but an MSIX package has no such configuration UI. The script currently hardcodes credential.helper manager and core.fscache true into the system gitconfig, which is a reasonable starting point, but the PR description needs to address this gap explicitly. What defaults are baked in? How can users change them conveniently after installation and persist the changes across upgrades? The manifest declares desktop6:FileSystemWriteVirtualization and desktop6:RegistryWriteVirtualization as disabled, and requests unvirtualizedResources. Does that mean the packaged etc/gitconfig is writable by the user post-install? This needs to be documented.

Missing PR description. The PR currently has no description at all. It needs to explain at minimum: How to build the MSIX artifact (the exact commands; note that the script's opening comment still says "Build the portable Git for Windows", suggesting it was copy-pasted from portable/release.sh without updating). How to code-sign the resulting .msix, or how to install it without signing (MSIX packages must be signed, or the user must enable Developer Mode). How to actually use the result: does it work? What does the user experience look like? Does git-bash.exe launch correctly from the Start Menu? Whether the execution aliases (git.exe, bash.exe, sh.exe, nano.exe) clash with a regular Git for Windows installation on the same machine. Registering bash.exe and sh.exe as app execution aliases seems particularly aggressive for users who have WSL or Cygwin installed. Whether the MSIX package can provide a central Git config analogous to C:\Program Files\Git\etc\gitconfig (which Git for Windows' installer provides, and which MinGit picks up so that tools like Visual Studio, VS Code, and SmartGit can rely on the central file for shared configuration).

Relationship to existing stale msix/ content. The msix/ directory already contains appxmanifest.xml, PackagingLayout.xml, Microsoft.Alm.Authentication.dll, WebView2Loader.dll, and stale .appx/.appxbundle binaries from a previous abandoned attempt (dating back to the Git 2.32 era). This PR adds a new appxmanifest.xml.in alongside the existing appxmanifest.xml without removing or replacing the old files. This needs to be cleaned up, and that cleanup deserves its own commit at the start of the series with a brief explanation of what the old files were and why they are being replaced.

Publisher identity. The new appxmanifest.xml.in uses Publisher="CN=The Git Development Community" and Name="Git.GitforWindows", while the old appxmanifest.xml uses Publisher="CN=Johannes Schindelin, ..." and Name="JohannesSchindelin.Git". The publisher string in an MSIX must match the signing certificate exactly, so this is not a cosmetic choice. Can you explain the rationale for the new identity?

I am genuinely impressed by the effort you put in, and want to assist so that you can succeed. The approach of reusing make-file-list.sh and basing this on the MinGit/portable infrastructure looks right. But the PR needs the rework described above: clean commit history, following the DRY principle, generated (ideally not committed) assets, cleanup of the stale files, and most importantly a thorough PR description that addresses the configurability and coexistence questions.

Thank you!

@rimrul

rimrul commented Mar 5, 2026

Copy link
Copy Markdown
Member

This PR adds code for building an MSIX on x86, amd64 and arm64. I don't think we'll ever want to publish a MSIX for x86, though.

Whether the execution aliases (git.exe, bash.exe, sh.exe, nano.exe) clash with a regular Git for Windows installation on the same machine. Registering bash.exe and sh.exe as app execution aliases seems particularly aggressive for users who have WSL or Cygwin installed.

I also have questions about these aliases.
Do we even want these for sh.exe, bash.exe and nano.exe? Why?
Shouldn't the git.exe one use cmd/git.exe rather than bin/git.exe?

@shmuelie

shmuelie commented Mar 5, 2026

Copy link
Copy Markdown
Author

Awesome, thank you for the feedback. I was honestly so overjoyed to get something that works I forgot to think about other things 😅. Hope to take a look at each point tonight and get back to you!

@shmuelie

shmuelie commented Mar 8, 2026

Copy link
Copy Markdown
Author

Commit history: Happy to do that, and yeah... you can clearly see the history of me trying to get it working. Will rework the history as I work on the other issues

Committed image assets: They were generated from the SVG as you suggested. The tool I used is not free or open source so I wouldn't want to add it to the build pipeline. I will look for a way to generate them in the pipeline though

Configurability: There are a couple of options here. MSIX packages can have locations that are user editable to allow configuring the system level configuration, though that is not what the feature you mentioned are about. Those features are so that the applications in the package don't see a virtualized version of the file system. As for the PATH editing, that would not be needed as that's why the aliases are for. Aliases can be turned on and off in Windows Settings, allowing users to choose which are enabled from the package.

Missing PR description: Very good points. I will edit the PR description and the script. Thought I had changed all the messages but guess I missed a few 😅

Relationship to existing stale msix/ content: This one I'm confused about as I don't see that content anywhere?

Publisher identity: I just put values there so I would have something to work with, very likely we'd have to change those.

As for the questions about the various alias: In the packaged world, you don't modify the PATH, instead for every application you can create one or more aliases that have kind of symbolic links created for them. As I noted above, each alias can be individually turned on or off to help the user select what will be found. This can even work with multiple packages declaring the same aliases.

@shmuelie

Copy link
Copy Markdown
Author

@dscho I have updated the PR description. Still missing build instructions but want to make some changes before I add that

@shmuelie shmuelie force-pushed the add-msix-installer branch 2 times, most recently from 397d238 to cac87a9 Compare March 12, 2026 21:07
@shmuelie

Copy link
Copy Markdown
Author

@dscho I've cleaned the commit history, changed to generate the images, and updated the PR description with all the details you asked for 😄

Comment thread msix/appxmanifest.xml.in
Comment thread msix/appxmanifest.xml.in Outdated
Comment thread msix/appxmanifest.xml.in Outdated
Comment thread msix/appxmanifest.xml.in Outdated
Comment thread msix/appxmanifest.xml.in
</uap3:Extension>
</Extensions>
</Application>
<Application Id="Bash" Executable="bin\bash.exe" uap10:RuntimeBehavior="win32App" uap10:TrustLevel="mediumIL">

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of the bash alias? It would allow MSIX users to create their own Windows Terminal profile, so it might be usefull.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, or if they just want to run bash from CMD or PowerShell

Comment thread msix/release.sh Outdated
Comment thread msix/release.sh
Comment thread portable/release.sh
;;
MINGW32) ARTIFACT_SUFFIX="32-bit";;
MINGW64) ARTIFACT_SUFFIX="64-bit";;
CLANGARM64) ARTIFACT_SUFFIX=arm64;;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised ARTIFACT_SUFFIX isn't common.

Comment thread portable/release.sh
BITNESS=64
ARCH=aarch64
ARTIFACT_SUFFIX=arm64
MD_ARG=256M

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think MD_ARG should be common.

Comment thread msix/release.sh

case "$MSYSTEM" in
MINGW32) ARTIFACT_SUFFIX="x86";;
MINGW64) ARTIFACT_SUFFIX="x64";;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this explains why the suffix isn't common. I'm not sure how I feel about introducing a different suffix for one artefact, though.

@DrusTheAxe

Copy link
Copy Markdown

Publisher identity. The new appxmanifest.xml.in uses Publisher="CN=The Git Development Community" and Name="Git.GitforWindows", while the old appxmanifest.xml uses Publisher="CN=Johannes Schindelin, ..." and Name="JohannesSchindelin.Git". The publisher string in an MSIX must match the signing certificate exactly, so this is not a cosmetic choice. Can you explain the rationale for the new identity?

Also, change your identity and you're a new thing. This would have no(!) relation to existing installs e.g. if this appears in v9.8.7 then any system with 9.8.6 with the older Publisher would wind up with both installed, no data from 9.8.6 would appear for 9.8.7 (ApplicationData, Settings, etc). Doesn't matter if their names are coincidentally similar, not-identical family means totally different things. May as well call them "Fish" and "Bicycle" :P

Identity is a programmatic identifier -- for machine and developer consumption

DisplayName (+Logo) are localized identifiers -- for human consumption

Publisher must match your certificate's SUBJECT field, true. But even if you could have a different cert, changing Identity is impactful. Only do it if you truly do intend to make a different thing.

DON'T change identity for cosmetic reasons. That's what DisplayName is for :-)

@linghengqian linghengqian left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current PR has a merge conflict, making it inconvenient to review.

@dscho

dscho commented Jul 13, 2026

Copy link
Copy Markdown
Member

The current PR has a merge conflict, making it inconvenient to review.

@linghengqian I am afraid that your code review might not be the most pressing thing here. With all due respect, the still unaddressed feedback of the long-time contributor @rimrul weighs a lot more than yours.

Besides, the most pressing concerns with this PR are not necessarily in the current code changes. Concerns including, but not limited to:

  • The configurability I already mentioned at the very top. The Git for Windows installer offers plenty of options that the MSIX lacks. Granted, Portable Git and Git archives (which are offered as part of Git for Windows' official versions) also lack those, but then, unlike the MSIX, they don't want to install into the Start Menu. Ideally this configurability would have one source of truth that would be shared between the installer and the MSIX, and obviously this could potentially lead to a way to configure Portable Git and Git archive conveniently, too.
  • Cost: I am not only talking about the cost of building and maintaining this thing, last time I checked, the MSIX packages had to be signed with a key that does not come for free, and had to be uploaded to the Store in some non-obvious way.
  • Upgrade story: Git for Windows occasionally needs to issue important updates. With the installer, users have a chance to enable a daily update check. With the Store, I don't know of a fine way to notify users that they need to update, urgently.

@shmuelie

Copy link
Copy Markdown
Author

I will work on the conflicts hopefully today, but regarding the issues raised:

  1. Regarding configuration, while not configurable at install time, there's no reason the system wide config in ProgramData wouldn't still work.
  2. Signing is required for MSIX, but if submitted to the store the package is signed by the store, not the developer and that's free (as is submitting to the store). You can get the package that is store signed after to provide direct download links if you'd prefer still.
  3. If the app is installed by the store, the store checks for updates every 24 hours by default. If installed using appinstaller files, then the appinstaller file specifies how often to check for updates.

@shmuelie shmuelie force-pushed the add-msix-installer branch from cac87a9 to b81ddf0 Compare July 14, 2026 16:25
@dscho

dscho commented Jul 14, 2026

Copy link
Copy Markdown
Member
  1. Regarding configuration, while not configurable at install time, there's no reason the system wide config in ProgramData wouldn't still work.

Oh, but there is a very, very good reason why the system wide config in ProgramData should absolutely not work. That used to be the place where the global configuration lived until a vulnerability report caused quite a bit of stress for me and I fixed that in one big hurry way back when.

The correct place for the configuration is C:\Program Files\Git\etc\gitconfig.

But I think I made myself unclear about the scope of the problem. On Windows, nobody really wants to configure anything via error-prone command-lines. See the screenshots at https://gitforwindows.org/mapping-between-git-installer-gui-settings-and-command-line-arguments.html. That's how users who use the official Git for Windows installer have come to expect to configure the most important Git settings. And that's what any solution has to compete with that tries to install Git for Windows into the Start Menu (read: it wants to replace Git for Windows' official installer), which this here PR wants to do.

3. If the app is installed by the store, the store checks for updates every 24 hours by default. If installed using appinstaller files, then the appinstaller file specifies how often to check for updates.

Hmm. I used to have GIMP installed via the Store, but stopped that practice when I noticed that it was woefully out of date. I then switched to MSYS2's variant because I keep my MSYS2 installation up to date, anyway. So I am somewhat curious how I missed updates of that Store application when it was supposed to at least notify me every 24h for several months that my GIMP needed an update?

2. Signing is required for MSIX, but if submitted to the store the package is signed by the store, not the developer and that's free (as is submitting to the store). You can get the package that is store signed after to provide direct download links if you'd prefer still.

So how does that work? Last time somebody tried to get me to publish to the Store, they said that I'd just have to pay X amount of dollars per year to get an account, it would be easy peasy 😁

@dscho

dscho commented Jul 14, 2026

Copy link
Copy Markdown
Member

Also, as far as I can tell, most of the feedback of #665 (review) is still unanswered.

@shmuelie

Copy link
Copy Markdown
Author

Ah, yes. I did misunderstand your issue with configuration. I'm a bit unsure about how to best solve that off the top of my head but will do what I can to get an answer there.

For updates, my best guess would be that either you had automatic updates turned off (something we've seen removed) or maybe GIMP wasn't submitting updates? Hard to diagnose now 😅

As for submitting to the store, in the past we did have a cost, but we've since eliminated the cost. (Disclaimer that I work on the store team).

And ah, yes I missed those feedback items. Will try to get to them today

@shmuelie

Copy link
Copy Markdown
Author

Actually, @dscho, would a solution for the configuration problem be a post install GUI? Admittedly there are things it couldn't change like the start menu entries, but for many others it would work?

@dscho

dscho commented Jul 14, 2026

Copy link
Copy Markdown
Member

would a solution for the configuration problem be a post install GUI? Admittedly there are things it couldn't change like the start menu entries, but for many others it would work?

I am a but doubtful that it would be able to edit C:\Program Files\Git\etc\gitconfig, and that's where the config needs to live so that is accessible for other applications (such as Visual Studio and GitHub Desktop, both of which use their own MinGit that is configured to respect the global Git config in that place).

Which reminds me: Is the Store application is per-user, and wants to bury the "system" config deep in the user's home directory? That would be quite incompatible with that strategy to interact nicely with other applications (that bundle MinGit).

shmuelie and others added 3 commits July 16, 2026 09:43
The portable and MSIX release scripts share significant logic: argument
parsing, MSYSTEM/architecture detection, root directory setup, file list
generation, gitconfig configuration, DLL copying, and PDB handling.

Extract these into release-common.sh as a shared include with reusable
functions (prepare_root, init_etc_gitconfig, generate_file_list,
copy_dlls_to_libexec, unpack_pdbs), and refactor portable/release.sh to
source it. No behavioral change to portable builds.

Signed-off-by: Shmueli Englard <[email protected]>
Co-authored-by: Copilot <[email protected]>
Add appxmanifest.xml.in, the template for the MSIX package that Git for
Windows ships alongside its other installers. The manifest declares the
Git Bash, Git CMD, and Git GUI applications (each with a Start Menu entry
and an execution alias), plus aliases for git, bash, sh, and nano so the
individual tools can be enabled or disabled per user without modifying
the PATH. It requests unvirtualized filesystem and registry access so
the packaged system gitconfig stays writable after installation.

The template carries placeholders that the release script substitutes at
build time: @@IDENTITY_NAME@@ and @@DISPLAY_NAME@@ select the per-channel
package family, @@Version@@ the four-part MSIX version, @@architecture@@
the package ProcessorArchitecture, and @@MINVERSION@@ the minimum Windows
version.

Also ignore the generated msix/root/ build directory.

Signed-off-by: Shmueli Englard <[email protected]>
Co-authored-by: Copilot <[email protected]>
Add msix/release.sh, which assembles an MSIX package for Git for Windows.
It reuses the shared helpers from release-common.sh for argument parsing,
root directory setup, file list generation, and gitconfig configuration,
then layers on the MSIX-specific steps.

Packages are built for x64 (from MINGW64 or UCRT64) and arm64 (from
CLANGARM64); 32-bit is not supported and any other MSYSTEM is rejected.
The package declares its ProcessorArchitecture so Windows can target it
correctly -- an x64 package installs on both x64 and arm64, while the
arm64 package provides native arm64 binaries. Because the arm64 package
still bundles x64 binaries that need POSIX emulation (for example
bash.exe), its minimum Windows version is raised to the Windows 11 build
that supports x64-on-arm64 emulation, while x64 keeps the Windows 10
baseline.

Each release channel ships as its own package family, derived from the
version string: stable (Git.GitforWindows), release candidate
(Git.GitforWindows.Prerelease, versions with an "rc" marker), and
snapshot (Git.GitforWindows.Snapshot, versions with a "prerelease-"
prefix). The MSIX version is normalized to exactly four numeric segments
so snapshot versions with extra components remain valid.

Asset images are generated at build time from git-for-windows.svg with
rsvg-convert rather than committed as binaries, and the package is
produced with makeappx.exe from the installed Windows SDK.

Signed-off-by: Shmueli Englard <[email protected]>
Co-authored-by: Copilot <[email protected]>
@shmuelie shmuelie force-pushed the add-msix-installer branch from 5b3c0d9 to bfe5e80 Compare July 16, 2026 16:47
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.

5 participants