-
Notifications
You must be signed in to change notification settings - Fork 0
repositories
How URGithub discovers your repositories, keeps them in sync, and what happens when a repository cannot be pushed.
URGithub discovers Git repositories within its configured repository area (repos in github\) and reconciles the local state against GitHub using gh repo list.
A repository generally needs to:
- exist as a valid directory
- contain a Git working tree
- have valid Git metadata
- have an appropriate remote
- be accessible by the authenticated GitHub account
On the first run it clones your entire GitHub account — private repos and forks included (unless skip_forks is enabled).
flowchart TD
A[repos in github folder] --> B{Valid git repo?}
B -->|yes| C[Has remote?]
B -->|no| D[ignored / flagged missing]
C -->|yes| E[reconcile with gh repo list]
C -->|no| F[flagged: no remote configured]
E --> G{Exists on GitHub?}
G -->|yes| H[tracked]
G -->|no| I[deleted-repo policy / quarantine]
E --> J{Exists locally but<br/>not on GitHub?}
J -->|yes| K[new repo — tracked]
J -->|no| L[clone_missing_repos<br/>clones it]
Inspect what was found with:
python urgithub.py --repos
python urgithub.py --verify--verify checks registry entries, folders, Git state, and remote information.
Every managed repository has a registry entry in database\registry.json (status, SHAs, quarantine state).
-
--forget NAME— remove one repository from the registry (folder left on disk). -
--prune— remove all stale registry entries (missing / quarantined / deleted). -
--yes— skip confirmation prompts for--forget/--prune.
GitHub is the source of truth for names.
-
Renamed on GitHub only → URGithub detects it via
gh apireturning the new name and renames the local folder + registry entry automatically. -
Renamed locally only → URGithub adopts it: on the next run it reads the folder's
origin, matches it to the existing registry entry (whose path is gone), and reuses that entry — updating the path, no duplicate clone, no quarantine. Then justgh repo rename NewName --repo owner/OldNameon GitHub to match. - Leftover ghost entries (from manual moves) can be dropped with
--forget NAMEor bulk-cleaned with--prune.
Repositories confirmed deleted on GitHub are not silently deleted. They are moved to deleted repos\ (a quarantined archive) and only with confirmation:
flowchart TD
A[GitHub returns 404] --> B{3 consecutive scans?}
B -->|no| C[wait / keep scanning]
B -->|yes| D{7 days elapsed?}
D -->|no| E[wait]
D -->|yes| F{Remote confirms deletion?}
F -->|no| G[do nothing]
F -->|yes| H{User confirms?}
H -->|no| G
H -->|yes| I["Move to deleted repos folder"]
I --> J[reported in report.html]
Configurable via deleted_repo_policy.* (defaults: 3 scans, 7 days, both confirmations required).
Synchronization is deliberately conservative — never reset, --force, rebase, or clean.
gitGraph
commit id: "base"
branch local
checkout local
commit id: "local change"
checkout main
commit id: "remote change"
checkout local
merge main
commit id: "pushed"
The safe pull/commit/push sequence:
fetch → fast-forward-only pull → commit (per policy) → push
| Situation | Result |
|---|---|
Secret files found (block_on_secrets) |
blocked: secrets — by filename pattern and file content |
File larger than limits.max_file_mb
|
blocked: oversize files |
| Local ahead and remote ahead | blocked: divergence |
| Remote unreachable | blocked: remote unreachable |
| No push permission on the repo | blocked: no push permission |
No origin remote |
blocked: no remote configured |
| Folder missing / not a git repo / quarantined | blocked: missing |
Dirty tree + auto_commit off |
skipped (never silently commits) |
Fetch / git add / commit / push fails |
failed (journaled with the reason) |
Every case is journaled and visible in report.html. Repos that pass are still pushed — one bad repo never blocks the others.
If the local and remote histories diverged (both ahead of the common base), the repo is blocked instead of clobbered.
flowchart LR
A{Local ahead?} --> C{Remote ahead?}
A -->|no| B[clean / push]
C -->|yes| D[BLOCKED: divergence<br/>you review, you decide]
C -->|no| E[fast-forward safe]
You review, you decide. URGithub never force-pushes and never merges divergent history automatically.
A global PID-based lock (locks\run.lock) serializes runs:
- A second run while another is active reports
skipped — lock held. - A stale lock expires after 15 seconds.
sequenceDiagram
participant R1 as Run 1
participant R2 as Run 2
participant L as Lock
R1->>L: acquire
R2->>L: try acquire → held
L-->>R2: skipped — lock held
R1->>L: release
See Security for what stops a sync, and Report for what each run records.
Discover · Scan · Synchronize · Commit · Push · Verify · Report — with safety gates and an HTML activity report after every run.
| About | Quick links | Status |
|---|---|---|
| Home · Installation · Architecture | Repositories & Sync · Security · Report & Journal | Configuration · Automation · Operations & Updating |
| FAQ · Troubleshooting · Wiki home | Repository · Issues · Releases |
|
URGithub never runs git reset, --force, rebase, or clean — anything unsafe is blocked and reported, never silently destroyed.
MIT License · © 2026 Ganesh Bakkera · learnerforge/push-to-github
Getting started
- Home — overview, pipeline, quick start
- Installation — requirements, setup wizard, first run
Concepts
- Architecture — one engine, every trigger
- Repositories & Sync — discovery, rename, quarantine, block codes
- Security — safety model, secret detection, blocked operations
-
Report & Journal —
report.htmland the JSONL journal
Operation
-
Configuration — every config key,
--configCLI - Automation — triggers and scheduling per OS
- Operations & Updating — production setup, upgrades, maintenance
Help
- FAQ — common questions
- Troubleshooting — symptoms and fixes
Quick reference
-
--setup· one-time registration wizard -
--scan· discover repositories (never syncs) -
--sync· full safe synchronization -
--report· regeneratereport.html -
--schedule install· install Windows scheduling -
--run manual· run the manual trigger
Repository ↗ · Issues ↗ · Releases ↗
v0.1.0 · MIT License · © 2026 Ganesh Bakkera