When looking up an executable via the `_which` function, Git GUI imitates the `execlp()` strategy where the environment variable `PATH` is interpreted as a list of paths in which to search. For historical reasons, stemming from the olden times when it was uncommon to download a lot of files from the internet into the current directory, empty elements in this list are treated as if the current directory had been specified. Nowadays, of course, this treatment is highly dangerous as the current directory often contains files that have just been downloaded and not yet been inspected by the user. Unix/Linux users are essentially expected to be very, very careful to simply not add empty `PATH` elements, i.e. not to make use of that feature. On Windows, however, it is quite common for `PATH` to contain empty elements by mistake, e.g. as an unintended left-over entry when an application was installed from the Windows Store and then uninstalled manually. While it would probably make most sense to safe-guard not only Windows users, it seems to be common practice to ignore these empty `PATH` elements _only_ on Windows, but not on other platforms. Sadly, this practice is followed inconsistently between different software projects, where projects with few, if any, Windows-based contributors tend to be less consistent or even "blissful" about it. Here is a non-exhaustive list: Cygwin: It specifically "eats" empty paths when converting path lists to POSIX: https://github.com/cygwin/cygwin/commit/753702223c7d I.e. it follows the common practice. PowerShell: It specifically ignores empty paths when searching the `PATH`. The reason for this is apparently so self-evident that it is not even mentioned here: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_environment_variables#path-information I.e. it follows the common practice. CMD: Oh my, CMD. Let's just forget about it, nobody in their right (security) mind takes CMD as inspiration. It is so unsafe by default that we even planned on dropping `Git CMD` from Git for Windows altogether, and only walked back on that plan when we found a super ugly hack, just to keep Git's users secure by default: https://github.com/git-for-windows/MINGW-packages/commit/82172388bb51 So CMD chooses to hide behind the battle cry "Works as Designed!" that all too often leaves users vulnerable. CMD is probably the most prominent project whose lead you want to avoid following in matters of security. Win32 API (`CreateProcess()`) Just like CMD, `CreateProcess()` adheres to the original design of the path lookup in the name of backward compatibility (see https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw for details): If the file name does not contain a directory path, the system searches for the executable file in the following sequence: 1. The directory from which the application loaded. 2. The current directory for the parent process. [...] I.e. the Win32 API itself chooses backwards compatibility over users' safety. Git LFS: There have been not one, not two, but three security advisories about Git LFS executing executables from the current directory by mistake. As part of one of them, a change was introduced to stop treating empty `PATH` elements as equivalent to `.`: https://github.com/git-lfs/git-lfs/commit/7cd7bb0a1f0d I.e. it follows the common practice. Go: Go does not follow the common practice, and you can think about that what you want: https://github.com/golang/go/blob/go1.19.3/src/os/exec/lp_windows.go#L114-L135 https://github.com/golang/go/blob/go1.19.3/src/path/filepath/path_windows.go#L108-L137 Git Credential Manager: It tries to imitate Git LFS, but unfortunately misses the empty `PATH` element handling. As of time of writing, this is in the process of being fixed: https://github.com/GitCredentialManager/git-credential-manager/pull/968 So now that we have established that it is a common practice to ignore empty `PATH` elements on Windows, let's assess this commit's change using Schneier's Five-Step Process (https://www.schneier.com/crypto-gram/archives/2002/0415.html#1): Step 1: What problem does it solve? It prevents an entire class of Remote Code Execution exploits via Git GUI's `Clone` functionality. Step 2: How well does it solve that problem? Very well. It prevents the attack vector of luring an unsuspecting victim into cloning an executable into the worktree root directory that Git GUI immediately executes. Step 3: What other security problems does it cause? Maybe non-security problems: If a project (ab-)uses the unsafe `PATH` lookup. That would not only be unsafe, though, but fragile in the first place because it would break when running in a subdirectory. Therefore I would consider this a scenario not worth keeping working. Step 4: What are the costs of this measure? Almost nil, except for the time writing up this commit message ;-) Step 5: Given the answers to steps two through four, is the security measure worth the costs? Yes. Keeping Git's users Secure By Default is worth it. It's a tiny price to pay compared to the damages even a single successful exploit can cost. So let's follow that common practice in Git GUI, too. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Git GUI - A graphical user interface for Git
Git GUI allows you to use the Git source control management
tools via a GUI. This includes staging, committing,
adding, pushing, etc. It can also be used as a blame viewer, a tree browser,
and a citool (make exactly one commit before exiting and returning to shell).
More details about Git GUI can be found in its manual page by either running
man git-gui, or by visiting the online manual
page.
Git GUI was initially written by Shawn O. Pearce, and is distributed with the standard Git installation.
Building and installing
You need to have the following dependencies installed before you begin:
- Git
- Tcl
- Tk
- wish
- Gitk (needed for browsing history)
- msgfmt
Most of Git GUI is written in Tcl, so there is no compilation involved. Still, some things do need to be done (mostly some substitutions), so you do need to "build" it.
You can build Git GUI using:
make
And then install it using:
make install
You probably need to have root/admin permissions to install.
Contributing
The project is currently maintained by Pratyush Yadav over at https://github.com/prati0100/git-gui. Even though the project is hosted at GitHub, the development does not happen over GitHub Issues and Pull Requests. Instead, an email based workflow is used. The Git mailing list git@vger.kernel.org is where the patches are discussed and reviewed.
More information about the Git mailing list and instructions to subscribe can be found here.
Sending your changes
Since the development happens over email, you need to send in your commits in
text format. Commits can be converted to emails via the two tools provided by
Git: git-send-email and git-format-patch.
You can use git-format-patch to generate patches in mbox format from your
commits that can then be sent via email. Let's say you are working on a branch
called 'foo' that was created on top of 'master'. You can run:
git format-patch -o output_dir master..foo
to convert all the extra commits in 'foo' into a set of patches saved in the
folder output_dir.
If you are sending multiple patches, it is recommended to include a cover
letter. A cover letter is an email explaining in brief what the series is
supposed to do. A cover letter template can be generated by passing
--cover-letter to git-format-patch.
After you send your patches, you might get a review suggesting some changes.
Make those changes, and re-send your patch(es) in reply to the first patch of
your initial version. Also please mention the version of the patch. This can be
done by passing -v X to git-format-patch, where 'X' is the version number
of the patch(es).
Using git-send-email
You can use git-send-email to send patches generated via git-format-patch.
While you can directly send patches via git-send-email, it is recommended
that you first use git-format-patch to generate the emails, audit them, and
then send them via git-send-email.
A pretty good guide to configuring and using git-send-email can be found
here
Using your email client
If your email client supports sending mbox format emails, you can use
git-format-patch to get an mbox file for each commit, and then send them. If
there is more than one patch in the series, then all patches after the first
patch (or the cover letter) need to be sent as replies to the first.
git-send-email does this by default.
Using GitGitGadget
Since some people prefer a GitHub pull request based workflow, they can use GitGitGadget to send in patches. The tool was originally written for sending patches to the Git project, but it now also supports sending patches for git-gui.
Instructions for using GitGitGadget to send git-gui patches, courtesy of Johannes Schindelin:
If you don't already have a fork of the git/git repo, you need to make one. Then clone your fork:
git clone https://github.com/<your-username>/git
Then add GitGitGadget as a remote:
git remote add gitgitgadget https://github.com/gitgitgadget/git
Then fetch the git-gui branch:
git fetch gitgitgadget git-gui/master
Then create a new branch based on git-gui/master:
git checkout -b <your-branch-name> git-gui/master
Make whatever commits you need to, push them to your fork, and then head over to https://github.com/gitgitgadget/git/pulls and open a Pull Request targeting git-gui/master.
GitGitGadget will welcome you with a (hopefully) helpful message.
Signing off
You need to sign off your commits before sending them to the list. You can do
that by passing the -s option to git-commit. You can also use the "Sign
Off" option in Git GUI.
A sign-off is a simple 'Signed-off-by: A U Thor <author@example.com>' line at the end of the commit message, after your explanation of the commit.
A sign-off means that you are legally allowed to send the code, and it serves as a certificate of origin. More information can be found at developercertificate.org.
Responding to review comments
It is quite likely your patches will get review comments. Those comments are sent on the Git mailing list as replies to your patch, and you will usually be Cc'ed in those replies.
You are expected to respond by either explaining your code further to convince the reviewer what you are doing is correct, or acknowledge the comments and re-send the patches with those comments addressed.
Some tips for those not familiar with communication on a mailing list:
- Use only plain text emails. No HTML at all.
- Wrap lines at around 75 characters.
- Do not send attachments. If you do need to send some files, consider using a hosting service, and paste the link in your email.
- Do not top post.
- Always "reply all". Keep all correspondents and the list in Cc. If you reply directly to a reviewer, and not Cc the list, other people would not be able to chime in.