Skip to content
Dave Cox edited this page May 11, 2026 · 11 revisions

Git Worktrees

Work in directories outside of cloned repo, in disctinct branches: git-worktree.
git worktree add c:/trees/AP-4321 -b bug/AP-4321_fix_xyz -> new branch named bug/AP-4321_fix_xyz
git worktree add <path> <branch> -> existing branch
git worktree add ../hotfix -> new branch named hotfix

git worktree list
c:/repos/win      b8026860 [bug/AP-3571_catch_parse_exception]
c:/trees/AP-3549  b8026860 [bug/AP-3549_LogSender_destruction]

git worktree remove c:/trees/AP-4321

Windows

config

~/.gitconfig

[user]
	name = Dave Cox
	email = dcox@bgrove.com

# this SSH (built-in with newer Win10) uses Windows's ssh-agent service, whereas
# Sublime Merge's default SSH does not.  20201009
[core]
	sshCommand = C:/Windows/System32/OpenSSH/ssh.exe	

ssh

Host bitbucket.org
    User dave-cox
    IdentityFile C:\Users\dcox\.ssh\git-client-key-20201007

WSL

ssh-agent to avoid repeated prompts for ssh key passphrase

ssh-agent -s emits script code to set environment variables that ssh and ssh-add need to connect to the agent. And then ssh-agent forks to run in the background, without using shell’s background jobs facility. So do this to install the environment variables into running shell:

  • eval $(ssh-agent -s)

The ssh-agent instance runs only as long as bash terminals are open. It should be possible to make a Windows Scheduled Task that runs on user logon to launch wsl.exe to run ssh-agent, perhaps via intermediate shell script. Need ssh-agent -D to avoid forking and terminating the foreground ssh-agent process. wsl.exe --user dave --exec ssh-agent -D seems to work. https://www.daveeddy.com/2017/10/18/persistent-sshagent-on-bash-on-ubuntu-on-windows/

Then add ssh key (found in ~/.ssh) to the agent:

  • ssh-add ~/.ssh/git-client-key-20201007

This will prompt for the passphrase to unlock the ssh key, and cache the key for use by ssh connections to the remote repo.

macOS

ssh

  • add key to keychain, analogous to adding it to ssh-agent/pageant, so it may cache the password to unlock the key:
ssh-add -K ~/.ssh/git-client-key-20200827

# and/or (this form may be necessary to store private-key passwords for commit-signing (see below) to the macOS keychain)

ssh-add --apple-use-keychain ~/.ssh/git-client-key-20201007

Note: this doesn’t seem to stick across reboots; I’m having to repeat it each time.

  • .ssh/config
Host *
  UseKeychain yes
  • trust the git server (e.g. bitbucket.com) by adding its ssh key to client’s known_hosts file:
ssh-keyscan -t rsa bitbucket.org >> ~/.ssh/known_hosts

Trying to fix the non-stickyness mentioned above

  • .ssh/config, specify the key to add
Host *
    UseKeychain yes
Host bitbucket.org
    HostName bitbucket.org
    User dave-cox
    IdentityFile ~/.ssh/git-client-key-20200827

Signing Commits

git supports signing with ssh, gpg or s/mime keys. It's expedient to sign with the same ssh key used to access GitHub.

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/git-client-key-20201007.pub
git config --global commit.gpgsign true

Also add the public key as a signing key to the GitHub account you push to. GitHub:
  Settings
    > SSH and GPG keys
      > New SSH Key.
        Paste your public key and ensure you change the "Key type" dropdown to Signing Key.

For the local git client to verify your signatures or anyone else's, it needs to be informed of the public keys associated with users' signatures.

git config --global gpg.ssh.allowedSignersFile "~/.ssh/git_allowed_signers"

then edit ~/.ssh/git_allowed_signers such that each line maps a user's email to their public key:

dcox@bgrove.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCvqm3nNd...

Add executable bit to file (without a unix filesystem)

git update-index --chmod=+x /path/to/file (https://stackoverflow.com/q/13237611/6169408)

Fetch a specific tag

Some repos have too many tags, slowing down fetches intolerably, in which case I set the repo's remote's tagopt = --no-tags in its .git/config file, in which case no tags are fetched. In that case if I want to see some few specific tags (e.g. observed through the GitHub web UI), I must fetch them explicitly:

git fetch origin refs/tags/visible-tag-name:refs/tags/visible-tag-name

Delete tag

  • at remote repo:
    git push --delete <origin> <tag-name>
  • local:
    git tag -d <tag-name>

Windows Checkout Verbatim (Preserve LF without CR)

Do this upon dev box setup, and early in CI jobs, so cloning/fetching/pushing doesn’t try to translate line endings. Assuming you’re doing cross-platform development and want to use plain CR on Windows as well as Unix.
git config --global core.autocrlf false

Clone this wiki locally