Skip to content

xjayash/gitpush

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 

Repository files navigation

gitpush

Push a folder of scripts or code to GitHub with one command. Pure Python — no git installation required, works anywhere Python runs (including iOS shells like a-Shell).

python gitpush.py push ./myscripts

That single command will:

  1. Turn the folder into a git repo (if it isn't one yet)
  2. Detect every new, changed, and deleted file
  3. Skip junk (__pycache__, .venv, node_modules, .pyc, .DS_Store, editor folders...)
  4. Commit everything
  5. Create the GitHub repo if it doesn't exist (named after the folder)
  6. Push

Install (one time)

pip install dulwich

Get a GitHub token (one time)

  1. Go to github.com → Settings → Developer settings → Personal access tokens → Fine-grained tokens → Generate new token
  2. Repository access: All repositories (or select specific ones)
  3. Permissions:
    • Contents: Read and write — needed to push
    • Administration: Read and write — needed to auto-create repos
  4. Copy the token (github_pat_...)

Set your environment (each session, or add to ~/.profile)

export GITHUB_TOKEN=github_pat_yourtoken
export GITHUB_USER=yourusername
export GITHUB_EMAIL=you@example.com    # optional, see below
export GITPUSH_ROOT=~/Documents/projects  # optional safety fence, see below

All are optional — if token or username is missing, gitpush simply asks you when it needs them. Setting them just skips the prompts.

GITHUB_EMAIL controls the author email on your commits. If unset, gitpush derives your GitHub noreply address from your username automatically — commits still link to your profile and count on your contribution graph, without exposing a real email.

First push of a new repo interactively asks for optional extras — description, website, topics — press Enter to skip any of them.

GITPUSH_ROOT is a safety fence: when set, gitpush refuses to push or pushall any folder outside that directory. Useful to guarantee you can never accidentally push your Downloads folder.

Ignoring things

Three layers keep junk out of your repos:

  1. Built-in filters__pycache__, .venv, node_modules, .pyc, .DS_Store, editor folders are always skipped (edit SKIP_PARTS etc. at the top of the script to change).
  2. .gitignore — Dulwich honors standard .gitignore files, same as regular git.
  3. .gitpushignore (or _gitpush_ignore.txt — handy on iOS, where dotfiles are awkward) — auto-created with a commented template on your first push or pushall in a folder, so you always have somewhere to add exclusions. One pattern per line, # for comments, wildcards allowed. The ignore file itself is never pushed to GitHub:
    • In a project folder: those files/folders are never staged by push.
    • In a parent folder: pushall skips those subfolders entirely.
# _gitpush_ignore.txt in ~/Documents
models
experiments
*.bin

pushall also lists every folder → repo mapping and asks for confirmation before touching anything (-y skips the prompt for scripting).

Commands

Command What it does
push FOLDER The main one: commit everything + push. Creates the GitHub repo if needed.
status FOLDER List what would be pushed, change nothing
log FOLDER Show recent commits
pushall FOLDER Push every subfolder to its own repo in one go (same flags as push)
pull FOLDER or pull user/name Fetch + merge the latest from GitHub (clones if you don't have it yet)
clone user/name Copy a GitHub repo down
create NAME Create an empty repo on GitHub (rarely needed — push does it)
init FOLDER Make a folder a git repo without pushing (rarely needed — push does it)

Flags

Flag Works on Meaning Default
-r, --repo push, pull, clone Target repo. name or user/name $GITHUB_USER/foldername
-m, --message push Commit message made some changes
-n, --dry-run push Preview only, touch nothing off
-p, --private push, create Make auto-created repo private public
-f, --force push, pushall Force push - overwrite remote history (use after rewriting local history) off
-y, --yes pushall Skip the are-you-sure confirmation off
-b, --branch push, pull Branch to use main
-t, --token all remote commands Token override $GITHUB_TOKEN or prompt
-c, --count log How many commits to show 10

Examples

# Push a folder - repo "myscripts" is created automatically if missing
python gitpush.py push ./myscripts

# Same, but with a proper commit message
python gitpush.py push ./myscripts -m "add backup script"

# Push to a repo with a different name than the folder
python gitpush.py push ./myscripts -r utilities
python gitpush.py push ./myscripts -r someoneelse/shared-repo

# Auto-create as a PRIVATE repo on first push
python gitpush.py push ./secrets-lab -p

# See what would be pushed without doing anything
python gitpush.py push ./myscripts -n

# Check for unpushed changes / recent history
python gitpush.py status ./myscripts
python gitpush.py log ./myscripts -c 5

# Get a repo onto a new device
python gitpush.py clone yourname/myscripts
python gitpush.py clone myscripts            # your own repos: name alone is enough

# Pull changes made elsewhere - by folder or by repo name
python gitpush.py pull ./myscripts
python gitpush.py pull yourname/myscripts    # clones automatically if not present

Push ALL your project folders at once - each becomes its own repo

python gitpush.py pushall ~/Documents/projects
python gitpush.py pushall ~/Documents/projects -n     # preview first

Everyday workflow

# hack on your scripts...
python gitpush.py push ./myscripts        # done. that's the whole workflow.

FAQ / gotchas

"Repo X already exists but your token can't see it" — fine-grained token without that repo under Repository access. Edit the token on GitHub and add it.

GitHub refused to create the repo (401/403/404) — token is missing Administration: write, or is expired.

pull fails on a brand-new repo — the branch must exist on GitHub first. Push once, then pull works.

Where does the token go? — only into memory for the API call and push URL. Never written to disk.

Something's junk-filtered that you actually want — edit SKIP_PARTS / SKIP_NAMES / SKIP_SUFFIXES at the top of gitpush.py.

Works with classic tokens too (ghp_... with repo scope) — everything behaves the same.

About

A dulwich based pure python git interface for a-Shell

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages