User:Chlod/Multiple identities

A common situation some developers may have is having to deal with multiple identities for anonymity. For example, someone wishing to help develop features on Gerrit may not wish to have their real name, email, and possibly GPG signing key to be published onto Wikimedia Gerrit repositories. This usually entails the use of scripts, but this worsens developer experience as the effects of configuration changes are usually global (and an extra step prior and subsequent to developing on Wikimedia software).

Luckily, proper configurations can make this experience seamless and scriptless. This page details that setup for developers.

On Git, emails are public. To keep your real email private, you must have a different email account here.
For this guide, bob@example.com will be used, and bob is this user's UNIX shell username. Be sure to replace these with your own credentials. Haven't made a Wikimedia developer account yet? See wikitech:Help:Create a Wikimedia developer account and follow the "VPS and General Users" method.

You will need to edit files in your user (or home) directory. The %USERPROFILE% environment variable on Windows and the ~ symbol for macOS/Linux points to this folder. Your user folder is one of the following:

  • C:/Users/bob/ on Windows
  • /Users/bob/ on macOS
  • /home/bob/ on Linux

SSH edit

It's advised to use a different SSH identity for Wikimedia Gerrit/GitLab with the one you have for work/real life. Not only does this allow you to set a different passphrase for your Wikimedia keys, but it makes your public key different and thus isolates your real identity from your Wikimedia one.

If you don't have keys for Wikimedia yet, you can generate one with the following commands. This will generate an ED25519 key with the comment "bob@example.com's Wikimedia key" (changeable as needed) under a wikimedia folder on your existing .ssh folder.


On Windows
mkdir %USERPROFILE%\.ssh\wikimedia
ssh-keygen -t ed25519 -C "bob@example.com's Wikimedia key" -f "%USERPROFILE%\.ssh\wikimedia\id_ed25519"
On macOS/Linux
mkdir -p ~/.ssh/wikimedia
ssh-keygen -t ed25519 -C "bob@example.com's Wikimedia key" -f "~/.ssh/wikimedia/id_ed25519"

Next, you'll need to write (or modify) your SSH configuration to automatically use this key for connecting to Wikimedia Gerrit/GitLab. Create (or edit) the .ssh/config file in your user directory and add the following lines:

# Wikimedia Gerrit
Host gerrit.wikimedia.org
    HostName gerrit.wikimedia.org
    IdentityFile ~/.ssh/wikimedia/id_ed25519
    # User bob
    # Port 29418
    
# Wikimedia GitLab
Host gitlab.wikimedia.org
    IdentityFile ~/.ssh/wikimedia/id_ed25519
    User git

You can optionally uncomment the User bob line to always use bob as the user when connecting. You can also uncomment the Port 29418 line to always use the port 29418 when talking to Gerrit. Both of these are useful for the #Remote-based Git configuration section below, in case you decide to go with that option.

To test this configuration for Gerrit, run the appropriate command in your terminal:

  • ssh bob@gerrit.wikimedia.org -p 29418
  • ssh gerrit.wikimedia.org -p 29418 (if you uncommented only the User line)
  • ssh bob@gerrit.wikimedia.org (if you uncommented only the Port line)
  • ssh gerrit.wikimedia.org (if you uncommented both User and Port lines)

You should see a "Welcome to Gerrit Code Review" message. If you instead received "Permission denied (publickey)" or similar, double-check your configuration to see if you made a mistake.

To test this configuration for GitLab, run the following command in your terminal:

  • ssh gitlab.wikimedia.org

You should see a "Welcome to GitLab, @bob!" message. If you instead received "Permission denied (publickey)" or similar, double-check your configuration to see if you made a mistake.

Git edit

One of the most common solutions is setting per-repo configurations, but this is a hassle especially if you're making changes to many different MediaWiki repositories. In addition, your Git configuration won't be taken into consideration when cloning repositories, which can cause a global config option (such as core.autocrlf) to be applied when you don't want it to.

Git 2.36 added the new "conditional includes" options for the Git configuration, which allows you to conditionally include a different file for your Git configuration. Through this, you'll be able to set a different Git identity based on either directory (suggested) or remote.

For this part, the Wikimedia-specific configuration will be stored in ~/.wikimedia.gitconfig. You can change this to point to somewhere else for ease of access.

Directory-based Git configuration edit

This assumes that all of the repositories you will be working on will be cloned under a specific folder on your computer.


On Windows

Windows is a bit quirky and not like the other OSes, so the process is a bit different.

Edit (or create) the .gitconfig file in your user directory. Assuming that your Wikimedia-related projects are in C:/Users/bob/Documents/wikimedia-projects:

[includeIf "gitdir/i:C:/Users/bob/Documents/wikimedia-projects/"]
    path = ~/.wikimedia.gitconfig

If the folder is on another drive, just change the path after gitdir/i:.

[includeIf "gitdir/i:D:/Programming/Wikimedia/"]
    path = ~/.wikimedia.gitconfig
The /i after gitdir is important, as it marks the matching as case-insensitive. On Windows, the capitalization of folders do not matter and, as a result, you would want Git to recognize both capitalized or uncapitalized versions of the path.
On macOS/Linux

Edit (or create) the .gitconfig file in your user directory. Assuming that your Wikimedia-related projects are in ~/Documents/my-wikimedia-projects:

[includeIf "gitdir:~/Documents/my-wikimedia-projects/"]
    path = ~/.wikimedia.gitconfig

The trailing slash / is important, as it means "everything under this directory" (or in globbing terms, /**). Without it, the configuration will only apply to that specific folder.

Now, create a .wikimedia.gitconfig file in your user directory. You can now place your custom configuration here. For example, here's some basic values for Gerrit:

[user]
	email = bob@example.com
	name = Bob
[gitreview]
	remote = origin
	username = bob

You can also set things such as core.autocrlf or user.signingkey (for GPG).

Instead of using --global when modifying configuration values, you must instead now use --file .wikimedia.gitconfig, or just manually edit the configuration file. Otherwise, configuration values will be set globally.

Remote-based Git configuration edit

If your Wikimedia-related projects are scattered across your filesystem, you may opt to do remote-based configuration instead. This method is slightly more complicated, owing to the lack of multiple wildcard expressions when globbing.

Edit (or create) the .gitconfig file in your user directory. Add the following lines into the file, replacing all instances of bob with your UNIX shell name, as usual:

[includeIf "hasconfig:remote.*.url:ssh://gerrit.wikimedia.org/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:ssh://gerrit.wikimedia.org:29418/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:ssh://bob@gerrit.wikimedia.org/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:ssh://bob@gerrit.wikimedia.org:29418/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:gerrit.wikimedia.org/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:gerrit.wikimedia.org:29418/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:bob@gerrit.wikimedia.org/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:bob@gerrit.wikimedia.org:29418/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:ssh://gitlab.wikimedia.org/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:ssh://git@gitlab.wikimedia.org/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:gitlab.wikimedia.org:*/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:git@gitlab.wikimedia.org:*/**"]
	path = ~/.wikimedia.gitconfig

The above catches all possible permutations for the Gerrit and GitLab remotes, to ensure that the configuration still applies even if small parts of the URL change. With the User and Port configurations in the #SSH section above, you can have the following instead:

[includeIf "hasconfig:remote.*.url:ssh://gerrit.wikimedia.org/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:ssh://gitlab.wikimedia.org:*/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:gerrit.wikimedia.org/**"]
	path = ~/.wikimedia.gitconfig
[includeIf "hasconfig:remote.*.url:gitlab.wikimedia.org:*/**"]
	path = ~/.wikimedia.gitconfig

But this does make your life harder as you have to be sure to clone the proper repository URL whenever cloning (i.e. remove the port and username from the URL). The above method is more fire-and-forget, despite its size.

Testing edit

To test this, navigate to a cloned repository using your terminal, and run git config user.name. If you modified your user.name in your Wikimedia configuration, it should apply here. You can confirm where the configuration value is being set with --show-origin (e.g. git config --show-origin user.name).

To be extra sure, you can try running the following:

git commit --allow-empty -m "test"
git log

The top commit should show the proper user name and email (if you've changed them). To reset this, use the following (or, if that doesn't work, just re-clone the repository):

git reset --hard HEAD~1
git gc --prune=now --aggressive