My 2023 git and GitHub setup guide.

Git Setup

Set up git globally:

git config --global init.defaultbranch main
git config --global color.ui true
git config --global fetch.prune true
git config --global diff.colorMoved zebra

Make a new ssh key

Make a ssh key for authentication:

ssh-keygen -a 100 -t ed25519 -C "jas@business.com" -f jas-business-github-key-ed25519

Upload the ssh key to your GitHub acount, and test with:

ssh -i jas-business-github-key-ed25519 -T git@github.com

And GitHub should reply with:

Hi jas-business! You've successfully authenticated, but GitHub does not provide shell access.

Reset ssh-agent issue

So, sometimes when you run:

ssh -i jas-business-github-key-ed25519 -T git@github.com

And GitHub should reply with:

Hi jas-business! You've successfully authenticated, but GitHub does not provide shell access.

But instead you see:

Hi jas-PERSONAL! You've successfully authenticated, but GitHub does not provide shell access.

And you’re confused because you definitely used the right key and when you run git config user.name you see the right user name, it may be because the ssh-agent got confused between terminal windows, sigh!

Do this:

killall ssh-agent; eval `ssh-agent`

and sanity will be restored!

Adding keys to the local git config

If you are git clone-ing a existing project that needs your new key1, use a line like this one:

ssh-agent $(ssh-add jas-business-github-key-ed25519; git clone git@github.com:user/project.git)

And if you work on different projects for business and for personal, in the directory of the project2:

git init
git config --local user.name "jas"
git config --local user.email "jas@business.com"
git config --local core.sshCommand "ssh -i jas-business-github-key-ed25519"

To rebase or not to rebase?

The rebase question:

So, previously I have recommended using this flag to force a rebase on a pull,

git config --global pull.rebase true

however, after investigating signed/verified git commits I came across the following advice3:

When rebasing the changes are replayed on master. This causes them to be “rebased” on a new parent commit which will change the commit-id (which is partially based on the parent commit-id).

Rebasing may also require merging the changes as the commits are replayed. Even if the merge happens automatically, it may change the contents of the files. The file contents are another element that make up the commit-id.

The verification is done through a cryptographic signature of the contents and the commit-metadata. Hence, rebasing will break that signature.

To not break your signature you’ll need to use a fast-forward merge (where no new merge commit is created). To achieve that you’ll need to locally rebase your changes and sign them.

Or you can squash-rebase, where all your small commits are rolled up into a single new commit, which GitHub will sign on your behalf.

If verification is important to you, rebasing is generally a bad idea, fast-forward merges and merge commits will better reflect what actually happened and who had authored those changes.

So, in conclusion, I am now recommending git merge and ignore rebase options, historical commits are useful, and if they are signed/verified, then the signatures will be lost if rebase is used. Atlassian has advice here4.

So when you are asked about this:

hint: Pulling without specifying how to reconcile divergent branches is
hint: discouraged. You can squelch this message by running one of the following
hint: commands sometime before your next pull:
hint: 
hint:   git config pull.rebase false  # merge (the default strategy)
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint: 
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.

I recommend:

git config --global pull.rebase false

Signing (verified) git commits

Now, about signing git commits:

See this reference5

References


  1. https://stackoverflow.com/questions/4565700/how-to-specify-the-private-ssh-key-to-use-when-executing-shell-command-on-git ↩︎

  2. https://dev.to/web3coach/how-to-configure-a-local-git-repository-to-use-a-specific-ssh-key-4aml ↩︎

  3. https://stackoverflow.com/questions/62950018/verified-signatures-are-gone-after-i-pressed-rebase-and-merge ↩︎

  4. https://www.atlassian.com/git/tutorials/merging-vs-rebasing ↩︎

  5. https://calebhearth.com/sign-git-with-ssh ↩︎