Skip to content

Instantly share code, notes, and snippets.

@Lightfire228
Last active February 26, 2022 05:40
Show Gist options
  • Save Lightfire228/3b80babe7fed035f3f5631d14c19495f to your computer and use it in GitHub Desktop.
Save Lightfire228/3b80babe7fed035f3f5631d14c19495f to your computer and use it in GitHub Desktop.
Git MultiUser Utility

Follow steps 1 and 2 from this guide (copied below) You'll either need to move the rsa keys into the folder structure defined in users.py, or modify users.py to fit your desired folder structure

Then simply run python git_set_user.py profile to set your credentials in the current git repo, and python git_clone_as_user.py profile git_ssh_url to clone a git repo with your credentials.

(NOTE: You will have to use the SSH version of remote urls, for both pushing / pulling and cloning)


Step 1 - Create a New SSH Key

We need to generate a unique SSH key for our second GitHub account.

ssh-keygen -t rsa -C "your-email-address"

Be careful that you don't over-write your existing key for your personal account. Instead, when prompted, save the file as id_rsa_COMPANY. In my case, I've saved the file to ~/.ssh/id_rsa_work.

Step 2 - Attach the New Key

Next, login to your second GitHub account, browse to "Account Overview" and attach the new key, within the "SSH Public Keys" section. To retrieve the value of the key that you just created, return to the Terminal and type: vim ~/.ssh/id_rsa_COMPANY.pub.

Copy the entire string that is displayed, and paste this into the GitHub textarea. Feel free to give it any title you wish.

Next, because we saved our key with a unique name, we need to tell SSH about it. Within the Terminal, type: ssh-add ~/.ssh/id_rsa_COMPANY. If successful, you'll see a response of Identity Added.

#!/usr/bin/env python
import argparse
import os
import subprocess
import sys
from pathlib import Path
import users
import ssh_cmd
import git_set_user
def main(args):
_validate_url(args.url)
user = users.get_user(args.user)
print ('Cloning repository as user', user.label)
clone_repo(user, args.url, folder=args.folder)
_chdir (args)
# _set_remote () # uncomment to set the remote name to something other than 'origin'
git_set_user.set_user(user)
def clone_repo(user: users.User, url, folder=None):
env = ssh_cmd.get_env(user.id_rsa)
args = []
if folder:
args.append(folder)
subprocess.run(['git', 'clone', url, *args], env=env)
def menu():
parser = argparse.ArgumentParser(description = 'Git Clone repo as User')
parser.add_argument('user', choices=users.USERS_DICT.keys())
parser.add_argument('url')
parser.add_argument('--folder', default=None)
return parser.parse_args()
def _validate_url(url: str):
prefix = 'git@github.com:'
if not url.startswith(prefix):
print(f'Invalid URL: url must start with "{prefix}"', file=sys.stderr)
exit(1)
# cd's into the newly created folder (using the url to derive the folder name)
def _chdir(args):
# yes this works
folder = args.folder or Path(args.url).stem
dest = Path(os.getcwd()) / folder
os.chdir(dest)
# this is my preference for the 'default' remote name
def _set_remote():
subprocess.run(['git', 'remote', 'rename', 'origin', 'upstream'])
if __name__ == '__main__':
args = menu()
main(args)
#!/usr/bin/env python
import argparse
import subprocess
import users
def main(args):
user = users.get_user(args.user)
set_user(user)
import os
print(os.getcwd())
print ('Set git user to', user.label)
def set_user(user: users.User):
git_conf = ['git', 'config']
subprocess.run([*git_conf, 'user.name', user.name])
subprocess.run([*git_conf, 'user.email', user.email])
# tells git to use the rsa key you generated when accessing the remote
subprocess.run([*git_conf, 'core.sshCommand', f'ssh -i {user.id_rsa.as_posix()}'])
def menu():
parser = argparse.ArgumentParser(description = 'Git Set User')
parser.add_argument('user', choices=users.USERS_DICT.keys())
return parser.parse_args()
if __name__ == '__main__':
args = menu()
main(args)
#!/usr/bin/env python
import os
from pathlib import Path
def get_env(key: Path):
os.environ['GIT_SSH_COMMAND'] = f'ssh -i {key.as_posix()}'
return os.environ
#!/usr/bin/env python
from pathlib import Path
class User():
def __init__(self, arg, label, name, email, rsa) -> None:
self.arg = arg
self.label = label
self.name = name
self.email = email
self.rsa = rsa
# this is how I set up my folders, '~/.ssh/github/github_user/id_rsa'
self.id_rsa = (Path.home() / '.ssh/github' / self.rsa / 'id_rsa').resolve()
WORK = User(
'work',
'Work',
'example',
'foo_bar@example.com',
'rsa_folder',
)
PERSONAL = User(
'personal',
'Personal',
'example2',
'foo_bar2@example.com',
'rsa_folder_2',
)
USERS = [
WORK,
PERSONAL
]
USERS_DICT = { u.arg: u for u in USERS }
def get_user(arg):
return USERS_DICT.get(arg, None)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment