# Configurations

## Configurations

{% hint style="info" %}
Global git configurations are done with the flag `--global`.
{% endhint %}

### Username and Email

{% hint style="info" %}
If in `<user-name>` you need a spaced name, make sure to wrap it in double quotes. (`"User Name"`)
{% endhint %}

```bash
git config --global user.name <user-name>
git config --global user.email <user-email>
```

{% hint style="danger" %}
Keep in mind that global user configurations do not stop you from impersonating someone else.

**Always configure your GPG Signatures, that will be used in Commits, PRs, etc..**
{% endhint %}

{% hint style="warning" %}
If you intend to work with multiple git accounts **do not set global configurations**.
{% endhint %}

### SigningKey

{% hint style="success" %}
Always configure Git to sign Commits, PRs, etc with your GPG Public key.
{% endhint %}

Configure the private GPG key for git to use for its commands and verify that your local git user is really you.

[#get-private-key-id](#get-private-key-id "mention").

```bash
# Speficy the Private key Git will use
# Example: git config --global user.signingKey <private-key-ID>
git config --global user.signingKey
```

#### Additional configs

```bash
# Make Git use the signinkey in Commits, Tags, etc
git config --global commit.gpgSign true
git config --global tag.gpgSign true

# Make Git sign pushes only if Server supports it
git config --global push.gpgSign "if-asked"
```

Or add use the configurations in the `.gitconfig`

```
[commit]
    gpgsign = true
[tag]
    gpgsign = true
```

## GPG Keys

### Check existing keys

{% hint style="info" %}
The keys are maintained in `/home/user/.gnupg`.
{% endhint %}

1. Run the command on your machine that you will be using git.
2. If the command returns nothing, means that there are no generated keys on your system. *(If the `/.gnupg` folder doesn't exist it might say that it was created)*

```bash
gpg --list-secret-key --keyid-form LONG
```

### Generating new keys

#### Install GPG packages

```bash
sudo apt-get install gpg gnupg gpg-agent
```

#### Create private key

```bash
gpg --full-generate-key
```

1. Run the command and pick the default key *(RSA and RSA)*.
2. Choose the key size to be the longest *(4096 bits)*.
3. The validity time can be any you want.
4. In user ID to identify your key section
   1. "Real Name" is the same `user.name` you configured in Git. *(Which can be your GitHub username or your full name)*
   2. "Email Address" will also be the same `user.email` configured in Git.
5. For last, it will request a password so that you can access your keys. *(If running on WSL the password window should be opening from Windows)*

#### Get private key ID

To find the `<private-key-ID>` run the command to show existing keys:

<pre class="language-bash"><code class="lang-bash"><strong># List all keys
</strong><strong>gpg --list-secret-key --keyid-form LONG
</strong><strong>
</strong><strong># Or list by email
</strong>gpg --list-secret-key --keyid-form LONG "your_email@example.com"
</code></pre>

{% code title="Output example" %}

```bash
$ gpg --list-secret-key --keyid-form LONG

gpg: checking the trustdb
gpg: marginals needed: 0  completes needed: 0  trust model: pgp
gpg: depth: 0  valid:   0  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
/home/user/.gnupg/pubring.kbx
-----------------------------
sec   rsa4096/<private-key-ID> 2024-01-01 [SC] [expires: 2025-01-01]
      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
uid                 [ultimate] <User.name> <User.email>
ssb   rsa4096/<???> 2024-01-01 [E] [expires: 2025-01-01]
```

{% endcode %}

The `<private-key-ID>` will be the one after `sec   rsa4096/`.

#### Get public key

```bash
# Example: gpg --armor --export <private-key-ID>
gpg --armor --export
```

### Add Public Key to GitHub

1. Copy the "Public Key Block" from the first command to GitHub at <https://github.com/settings/gpg/new>.
2. Use the name convention as `<computer-hostname> (<wsl-instance-name>)`.

### In VSCode

Force VSCode to ask GPG passphrase at commits.

{% code title="settings.json" %}

```json
"git.enableCommitSigning": true
```

{% endcode %}

### For WSL2

{% embed url="<https://www.39digits.com/signed-git-commits-on-wsl2-using-visual-studio-code>" %}

{% hint style="danger" %}
Failure to complete this step will produce errors and failure in using the GPG keys, if using VSCode's to Commit, Push, etc.
{% endhint %}

{% hint style="info" %}
`GPG4Win` will recognize GPG keys created, in WSL Ubuntu, before it was installed.

There is no need to re-create the GPG keys.
{% endhint %}

1. Install [`GPG4Win`](https://www.gpg4win.org/) on the Windows side.
2. Edit/create this file in Ubuntu:

{% code title="\~/.gnupg/gpg-agent.conf" %}

```bash
# These will cache the passphrase for ~400 days or until computer is restarted
default-cache-ttl 34560000
max-cache-ttl 34560000

# This explicitly tells GnuPG to use the pin entry app on Windows to prompt for the passphrase
pinentry-program "/mnt/c/Program Files (x86)/GnuPG/bin/pinentry-basic.exe"
```

{% endcode %}

4. Force restart the gpg agent to apply the changes.

```bash
gpgconf --kill gpg-agent
```

5. Add this to the `.bashrc` file.

{% code title="WSL2 Linux (only)" %}

```bash
$ vim ~/.bashrc

# Configure password ask for signed commits
export GPG_TTY=$(tty)
```

{% endcode %}

## SSH keys

You should use ssh keys to avoid creating **personal tokens** when connecting to private repositories.

### [Generating new keys](https://docs.github.com/pt/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)

#### Create private key

{% hint style="info" %}
If "empty" is passed in the keyfile name a file `id_ed25519` will be created at `~/.ssh`.
{% endhint %}

```bash
ssh-keygen -t ed25519 -C "your_email@example.com"
```

#### Get public key

```bash
cat ~/.ssh/id_ed25519.pub
```

### Add Public Key to GitHub

1. Copy the "Public Key Block" from the first command to GitHub at <https://github.com/settings/ssh/new>.
2. Use the name convention as `<computer-hostname> (<wsl-instance-name>)`.

## Multiple Git Users

{% hint style="info" %}
If working with multiple users, avoid setting global configs for username, email and signingKey.
{% endhint %}

### Configure

#### Edit global .gitconfig

In `~/.gitconfig` add a `includeIf` for each folder, configuring which local `.gitconfig-user` file to use.

{% hint style="warning" %}
If your global `.gitconfig` has `[user]` block, add the `includeIf` right after it.
{% endhint %}

{% code title=".gitconfig" %}

```
[includeIf "gitdir:~/Work/"]
    path = ~/.gitconfig-<work-user>
    
[includeIf "gitdir:~/Personal/"]
    path = ~/.gitconfig-<personal-user>
```

{% endcode %}

#### Create specific .gitconfig for each user

{% code title=".gitconfig-<work-user>" %}

```
[user]
    name = <user-name>
    email = <user-email>
    signingKey = <private-gpg-key>

[core]
    sshCommand = ssh -i ~/.ssh/<private-ssh-user-file> -o IdentitiesOnly=yes
```

{% endcode %}

### Test

The command should output the correct user for the folder.

```bash
git config user.email
```
