diff --git a/README.md b/README.md new file mode 100644 index 0000000..df0c94b --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +# git-origin-util + +Small collection of Git utilities I use to keep my local repositories configured between my self-hosted Gitea instance and GitHub. + +Gitea is my primary Git server. GitHub is kept as a secondary/public copy of my repositories. + +## `setup_dual_push.py` + +Scans my local Git repositories and updates repos owned by `SowinskiBraeden` to use: + +- **Fetch:** `git.sowinski.dev` +- **Push:** `git.sowinski.dev` +- **Push:** `github.com` + +Other repositories and repositories without a recognized origin are skipped. + +Useful for configuring existing projects or setting up a new machine. + +## `git-new` + +Small command for initializing new projects with my normal Git configuration. + +Run it from inside the project directory: + +```bash +git-new +``` + +It will: + +Refuse to run if the directory is already inside a Git repository +Initialize a new Git repository +Set the default branch to main +Set Gitea as the fetch origin +Set Gitea and GitHub as push origins + +The repo name does not need to match the local directory name. + +## Setup + +Make the script executable: + +```bash +chmod +x git-new +``` + +Symlink it into /usr/local/bin: + +```bash +sudo ln -s "$(pwd)/git-new" /usr/local/bin/git-new +``` + +It can then be used from any directory: + +```bash +mkdir my-project +cd my-project + +git-new my-repo-name +``` + +The repositories must already exist on Gitea and GitHub before pushing. + diff --git a/git-new b/git-new new file mode 100644 index 0000000..b27c216 --- /dev/null +++ b/git-new @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 + +import subprocess +import sys +from pathlib import Path + +OWNER = "SowinskiBraeden" +GITEA_HOST = "git.sowinski.dev" +GITHUB_HOST = "github.com" + + +def git(*args: str, check: bool = True) -> subprocess.CompletedProcess: + return subprocess.run( + ["git", *args], + text=True, + capture_output=True, + check=check, + ) + + +def main(): + if len(sys.argv) != 2: + print("Usage: git-new ") + sys.exit(1) + + repo_name = sys.argv[1].strip() + + if not repo_name: + print("Error: repository name cannot be empty.") + sys.exit(1) + + current_dir = Path.cwd() + + # Refuse to run anywhere inside an existing Git repository. + existing_repo = git("rev-parse", "--show-toplevel", check=False) + + if existing_repo.returncode == 0: + repo_root = existing_repo.stdout.strip() + + print("Error: already inside a Git repository.") + print(f"Repository root: {repo_root}") + sys.exit(1) + + gitea_url = f"git@{GITEA_HOST}:{OWNER}/{repo_name}.git" + github_url = f"git@{GITHUB_HOST}:{OWNER}/{repo_name}.git" + + print(f"Initializing: {current_dir}") + print(f"Remote repo: {OWNER}/{repo_name}") + print() + + # Initialize repository. + git("init") + + # Use main as the initial branch. + git("branch", "-m", "main") + + # Gitea is canonical: fetch + first push destination. + git("remote", "add", "origin", gitea_url) + + git( + "remote", + "set-url", + "--push", + "origin", + gitea_url, + ) + + # GitHub is the secondary push destination. + git( + "remote", + "set-url", + "--add", + "--push", + "origin", + github_url, + ) + + print("Repository initialized.") + print() + print("Remotes:") + print(f" fetch -> {gitea_url}") + print(f" push -> {gitea_url}") + print(f" push -> {github_url}") + + +if __name__ == "__main__": + main()