Files
llvm-project/llvm/utils/git-llvm-push.md
Aiden Grossman d7a39cc97e [Utils] Add ability to configure git-llvm-push from .gitconfig (#187398)
This lets someone set git config options at whatever scope (per-repo,
global, etc.) for the options that they care about. This provides
similar functionality to just wrapping the script in a shell script with
one's desired options without the need to do that.

We need to be careful about how when we get the flags and how to execute
the git command to get the flags. For now, we do this before normal
argument parsing and fail silently to avoid printing output if someone
passes something like --quiet through the git config. This means options
like --verbose and --dry-run don't work for this specific command, but I
think that is a reasonable tradeoff.
2026-03-25 17:10:50 -07:00

7.6 KiB

How to Use the LLVM Pull Request Automator

This script is designed to automate the process of creating and landing a stack of pull requests from a local commit branch to the main branch of LLVM's GitHub repository. While it's possible to use this for normal workflows, its main purpose is to give contributors a practical alternative to pushing directly to LLVM's main branch. See the discussion at https://discourse.llvm.org/t/rfc-require-pull-requests-for-all-llvm-project-commits/88164 for more context.

Prerequisites

Before running the script, ensure you have the following set up:

  1. git command line tool: The script relies on git for all local repository operations.

  2. GitHub Token: You must have a GitHub Personal Access Token with repo scope. This token must be set as an environment variable:

    export LLVM_GITHUB_TOKEN="your_github_token_here"
    

    or to avoid having your token in your shell history something like:

    export LLVM_GITHUB_TOKEN="$(gh auth token)"
    
  3. Git Remotes: Your local repository should be configured with remotes for the upstream LLVM repository and your personal fork.

    • The script defaults to using upstream (e.g., https://github.com/llvm/llvm-project.git) for the main LLVM repository and origin for your personal fork.
    • If your remotes are named differently, you can override these defaults using the --upstream-remote and --remote flags.

Basic Usage

To run the script, navigate to your local llvm-project repository, check out the branch containing your stack of commits, and run:

python3 git-llvm-push

Assuming your remotes are configured with upstream pointing to https://github.com/llvm/llvm-project.git and origin pointing to your personal fork:

This will:

  1. Fetch the latest changes from upstream/main.
  2. Rebase your current branch on top of upstream/main.
  3. For each commit in your branch (from oldest to newest): a. Push the commit to a temporary branch on your fork (origin). b. Create a pull request targeting the upstream repository's main branch. c. Attempt to merge the pull request. d. If the merge is successful, it will rebase the local branch again and proceed to the next commit.

If any rebase or merge fails, the script will abort and clean up after itself, leaving your repository in the last good state. This means any commits that were successfully merged before the failure will remain merged, but temporary branches and other transient state will be removed.

Cleanup Steps

Regardless of success or failure, the script performs the following cleanup steps to ensure your local repository is left in a consistent state:

  1. Checkout Original Branch: The script will check out the branch you were on when you started the script.
  2. Delete Temporary Remote Branches: Any temporary branches created on your fork (e.g., users/johndoe/my-feature-1) will be deleted from the remote. This prevents clutter in your fork.

Configuration

In addition to accepting command line flags, git-llvm-push can also be configured through the git config. To do this, edit your git config (using a command like git config --edit to edit your repo specific configuration) and add the following section header:

[git-llvm-push]
    <flag> = <flag value>

The flags are spelled the exact same as they are on the command line. All flags are supported, although --verbose and --dry-run will not have an impact on the git invocation to read the configuration.

Examples

Dry Run (Safe Mode)

To see what actions the script would perform without actually creating branches, pushing code, or opening pull requests, use the --dry-run flag.

python3 git-llvm-push --dry-run

Creating Draft Pull Requests

If you want to create pull requests but not have them ready for review immediately, use the --draft flag.

python3 git-llvm-push --draft

Enabling Auto-Merge

You can use the --auto-merge flag to create a pull request and enable the "auto-merge" feature on GitHub, rather than having the script try to merge it directly. This is only supported for a single commit, as the script would need to block until your first PR landed to move onto the next, or otherwise be too complex for a simple script.

python3 git-llvm-push --auto-merge

Creating PRs Without Merging

If you only want to create the pull requests and then merge them manually later, use the --no-merge flag. Currently, this is only supported for single-commit branches.

python3 git-llvm-push --no-merge

Working with alternate remotes

If you have cloned the main llvm/llvm-project.git repository directly, your origin remote will point to upstream. If your personal fork is tracked under a different remote name (e.g., my-fork), you will need to specify both the --upstream-remote and --remote flags:

python3 git-llvm-push --upstream-remote origin --remote my-fork

Alternate usage via git llvm-push

If the script is available on your PATH, you can use it as a git subcommand, similar to git clang-format.

git llvm-push [FLAGS] ...

Auto-Detection Features

To simplify usage, the script attempts to auto-detect certain values if they are not explicitly provided via command-line arguments:

  • GitHub Login (--login): If the --login flag is omitted, the script will attempt to fetch your GitHub username using the provided LLVM_GITHUB_TOKEN by making an API call to GitHub.
  • Temporary Branch Prefix (--prefix): If the --prefix flag is omitted, temporary branches created on your fork will be prefixed with users/<your_github_login>/. For example, if your login is johndoe, branches will be named like users/johndoe/my-feature-1.

Command-Line Options

Flag Description Default
--base The base branch to target with the pull requests. main
--remote The remote for your personal fork to push temporary branches to. origin
--upstream-remote The remote for the upstream repository to create pull requests against. upstream
--login Your GitHub username. If not provided, it will be queried from the token. (auto-detected)
--prefix The prefix for temporary branches created on your fork. users/<username>/
--draft Create pull requests as drafts. (not set)
--no-merge Create pull requests but do not attempt to merge them. (Single commit only) (not set)
--auto-merge Enable auto-merge on created pull requests instead of merging directly. (Single commit only) (not set)
--dry-run Print the commands that would be run without executing them. (not set)
-v, --verbose Print all commands being run and other verbose output. (not set)
-q, --quiet Print only essential output and errors, suppressing progress messages. (not set)
--use-gh-cli-token Automatically acquires a token by calling gh auth token (not set).