Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MohamedKari/d2ed975a0c9abc152e5e6262892aa1ed to your computer and use it in GitHub Desktop.
Save MohamedKari/d2ed975a0c9abc152e5e6262892aa1ed to your computer and use it in GitHub Desktop.
'''
**Author**:
Mohamed Kari <contact@mkari.de>
**Describtion**
Clone private github repos effortlessly into your Notebook Cloud VM with a two-liner.
**Usage**
Alternative 1 (recommended):
------
Copy the following two lines into your notebook:
!curl https://gist.githubusercontent.com/MohamedKari/d2ed975a0c9abc152e5e6262892aa1ed/raw/?$(date +%s) -o "nb-git.py" -s
%run nb-git.py basicauth MohamedKari/waymo_od_perception MohamedKari
- or -
%run nb-git.py oauth2 MohamedKari/waymo_od_perception
Then adapt the command line args to your specfic repo and - in case of basicauth - user name and run the cell.
To push changes back to the repo run
%run nb-git.py basicauth MohamedKari/waymo_od_perception MohamedKari --push
- or -
%run nb-git.py oauth2 MohamedKari/waymo_od_perception --push
------
Alternative 2
------
Copy & paste & run the following code in your notebook. You'll be interactively asked for the relevant settings.
!curl https://gist.githubusercontent.com/MohamedKari/d2ed975a0c9abc152e5e6262892aa1ed/raw/?$(date +%s) -o "nb-git.py" -s
%run nb-git.py
------
Alternative 3:
------
Copy & paste the second code block from below into your Colab Notebook and execute it. You'll be interactively asked for the relevant settings.
To avoid re-entering the settings every time you load the notebook, you can hard-code them at the top of the copied notebook.
------
'''
#########################################################
###### CALLABLE SCRIPT FOR MINIMAL INTERACTIVENESS ######
#########################################################
import argparse
import sys
def get_interactive(args):
return None, None, None, None, None
def get_oauth2_settings(args):
return "oauth2", args.gitcommand, args.repo, None, args.keep_secret
def get_basicauth_settings(args):
return "basicauth", args.gitcommand, args.repo, args.user, args.keep_secret
# shared parser that is inherited to other parsers
shared_parser = argparse.ArgumentParser(add_help=False)
shared_parser.add_argument("-k", "--keep-secret", action="store_true")
# mutually exclusive group that stores their value in a field called 'gitcommand' which assumes the default 'clone'
group = shared_parser.add_mutually_exclusive_group()
group.add_argument("-c", "--clone", action="store_const", dest="gitcommand", const="clone")
group.add_argument("-p", "--push", action="store_const", dest="gitcommand", const="push")
group.set_defaults(gitcommand="clone")
# Main and sub parsers
mainparser = argparse.ArgumentParser()
mainparser.set_defaults(func=get_interactive)
subparsers = mainparser.add_subparsers()
subparser_oauth2 = subparsers.add_parser("oauth2", parents=[shared_parser])
subparser_oauth2.add_argument("repo")
subparser_oauth2.set_defaults(func=get_oauth2_settings)
subparser_basicauth = subparsers.add_parser("basicauth", parents=[shared_parser])
subparser_basicauth.add_argument("repo")
subparser_basicauth.add_argument("user")
subparser_basicauth.set_defaults(func=get_basicauth_settings)
args = mainparser.parse_args(sys.argv[1:])
mode, gitcommand, repo, user, keep_secret = args.func(args)
#########################################################
########## PASTABLE CODE FOR INTERACTIVE CLONE ##########
#########################################################
# hardcode setting here if you like by uncommenting and editing the lines
# if not, you'll be asked interactively for the settings
# gitcommand = "clone"
# repo = "MohamedKari/waymo_od_perception"
# mode = "basicauth"
# user = "MohamedKari"
# or
# gitcommand = "clone"
# repo = "MohamedKari/waymo_od_perception"
# mode = "oauth2"
import os
from getpass import getpass
import urllib.parse
import re
gitcommand = gitcommand if "gitcommand" in vars() and gitcommand is not None else input("gitcommand (clone, push)")
repo = repo if "repo" in vars() and repo is not None else input("Repo (<user>/<name>): ")
git_dir = repo.split("/")[1]
mode = mode if "mode" in vars() and mode is not None else {
"": "basicauth",
"b": "basicauth",
"basicauth": "basicauth",
"o": "oauth2",
"oauth2": "oauth2"
}.get(input("[b]asicauth or [o]auth2 (default: basicauth):\n"))
remove_secret = mode if "mode" in vars() and mode is not None else True
if mode == "basicauth":
user = user if "user" in vars() and user is not None else input("User name: ")
secret = getpass('Password: ')
secret = urllib.parse.quote(secret)
cmd_string = f"git --git-dir {git_dir}/.git {gitcommand} https://{user}:{secret}@github.com/{repo}.git"
if mode == "oauth2":
secret = getpass('Token: ')
secret = urllib.parse.quote(secret)
cmd_string = f"git --git-dir {git_dir}/.git {gitcommand} https://oauth2:{secret}@github.com/{repo}.git"
os.system(cmd_string)
del cmd_string
del secret
if remove_secret:
with open(os.path.join(repo.split("/")[1], ".git", "config"), "rt+") as f:
gitconfig = f.read()
f.seek(0)
f.write(
re.sub(r"https://[A-Za-z0-9]*:.*@", f"https://", gitconfig)) # ASSUMPTION: [A-Za-z0-9]* covers GitHub usernames
f.truncate()
else:
print("WARNING: you chose not to remove your secret. Everybody with access to files in this directory will be able to read your password or token in plaintext from the cloned repos .git/config file!")
#################################################
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment