Skip to main content

A stack diff poor-man's solution

Project description

git-publish

Push stacked atomic Pull/Merge Requests.

What is this?

git-publish is a Python script that manages your stacked commits into separate PR (GitHub) / MR (GitLab). It assigns a change ID to each commit in the commit message through a commit message hook. When calling git-publish directly, each commit will be pushed to a dedicated remote branch and PR / MR will be created targeting the right branch to retain the commit history. If commits are amended, git-publish will refer to the change ID to find the associated branch and keep everything in order.

Get started

Install git-publish for everyday use:

$ uv tool install git-publish

For local development of this repo:

$ uv build
$ uv tool install . -e

Set the required environment variables (add to your shell profile) or rely on the token resolver:

  • GITHUB_TOKEN — required for GitHub projects (repo scope sufficient for PRs). The tool will also accept GH_TOKEN, or fall back to gh auth token and Git credential helper.
  • GITLAB_TOKEN — required for GitLab projects (api scope)
  • GITLAB_URL — optional GitLab instance URL; default: https://gitlab.com
  • GITPUBLISH_BRANCH_PREFIX — optional branch/id prefix; defaults to your OS username
  • GITPUBLISH_CHANGE_ID_PREFIX — prefix used in commit messages for change ids; defaults to Change-Id:

You can also drop these in a local .env file at the repo root; it will be auto‑loaded when you run the tool:

# .env
GITHUB_TOKEN=ghp_...
GITLAB_TOKEN=glpat-...
GITLAB_URL=https://gitlab.example.com
GITPUBLISH_BRANCH_PREFIX=alice
GITPUBLISH_CHANGE_ID_PREFIX=Change-Id:

Run it in your repository:

$ git-publish

Tips:

  • You can also run it as a Git subcommand: git publish (Git will invoke git-publish on PATH).
  • Make sure you are on one of the main branches (main, master, development, develop) and that it is up-to-date with its tracking branch.
  • After commit, check the commit message contains a line like Change-Id: user/1a2b (or your chosen prefix).

Hooks

When you run the tool, it installs a commit-msg hook at .git/hooks/commit-msg that ensures a Change‑Id is present in every commit.

  • Update: re-run git-publish to validate the existing hook content.
  • Remove: rm .git/hooks/commit-msg.

Safety

This tool will:

  • Stash and later unstash your working tree when dirty
  • Force‑push ephemeral branches (one per commit)
  • Delete temporary local branches after publishing

Make sure your main branch is clean and tracking the correct remote.

Development tasks

Using the task runner:

$ uv run task lint    # ruff (check) + pyright
$ uv run task format  # ruff --fix
$ uv run task test    # pytest

Troubleshooting

  • "Branch is not up‑to‑date with its tracking branch" → git fetch then git pull --ff-only.
  • "Must be on a main branch" → switch to main, master, development, or develop.
  • "Empty GITHUB_TOKEN/GITLAB_TOKEN" → export in your shell or add to .env.

Dev containers and CI-friendly token resolution

git-publish now resolves the GitHub token in this order:

  1. GITHUB_TOKEN (or GH_TOKEN) environment variable
  2. gh auth token if the GitHub CLI is installed and logged in
  3. Git credential helper (git credential fill for github.com)

This works well in VS Code tasks and dev containers where environment variables may not be present.

Dev container task example:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "git-publish",
      "type": "shell",
      "command": "bash",
      "args": [
        "-lc",
        "GITHUB_TOKEN=$(gh auth token 2>/dev/null || true) git publish"
      ],
      "problemMatcher": []
    }
  ]
}

Alternatively, add a .env file in the workspace (not committed) with GITHUB_TOKEN=... which the tool auto‑loads.

Example output

git-publish info: My feature commit
  🔗 https://github.com/owner/repo/pull/123

Next

  • Add nested blocking dependencies (available in GitLab 16.6+)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

git_publish-0.1.0.tar.gz (49.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

git_publish-0.1.0-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

Details for the file git_publish-0.1.0.tar.gz.

File metadata

  • Download URL: git_publish-0.1.0.tar.gz
  • Upload date:
  • Size: 49.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for git_publish-0.1.0.tar.gz
Algorithm Hash digest
SHA256 90ebddd4e7741bf57ecf7b5cb6f5621d2c928be6cd9f45aee0c046fda985f780
MD5 0b7c4cc2a426469e250da41cf1a6edbe
BLAKE2b-256 aa61ddb5cb418518e4d353e7c6b630c64ebecbbac9beb9f87a863c709065989c

See more details on using hashes here.

Provenance

The following attestation bundles were made for git_publish-0.1.0.tar.gz:

Publisher: publish.yml on warrenseine/git-publish

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file git_publish-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: git_publish-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 10.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for git_publish-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8141628b8d48853b3fee44fb7b4aafbedd66ded91b768e7d1d6b75a4c1f978bd
MD5 918ead564688dae727ebd1a5c335342e
BLAKE2b-256 89d8dfaafb001d266bc890d3f1d27a3e994bff4e1c93a689aeaacebed57f6769

See more details on using hashes here.

Provenance

The following attestation bundles were made for git_publish-0.1.0-py3-none-any.whl:

Publisher: publish.yml on warrenseine/git-publish

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page