Utility for keeping a Perforce workspace and local git repo in sync
Project description
Git Perforcesson
git-p4son is a tool for managing a local git repository within a Perforce workspace.
This way you can use the familiar local git development flow even though you are
working on a project where perforce is used for source control.
The idea is to have a main git branch that is kept in sync with a branch of a Perforce depot.
From main you branch out into feature branches, where you do local changes
and rebase on main whenever it is updated.
Once your changes is ready to be submitted in perforce git-p4son can help you create both
changelists and push them for reviews. You can even push individual git commits as patches
for review, so that the reviewer can see the changes in the order you made them locally. Similar
to the pull request worfkflow on github.
This is a bit cumbersome to do manually, but this package provides commands that help out with the repetitive and error prone stuff.
On big workspaces
Sometimes git struggles to keep entire perforce workspaces in the repo, like when working
on a Unreal Engine game with all source code in the workspace. If so, it helps to edit
.gitignore and include only the subdirectories in which you work, the rest of the files
will still be managed by perforce of course.
Usage Example
Here's a typical workflow when developing a feature using git-p4son:
# Sync main with latest changes from perforce
git checkout main
git p4son sync
# Start work on a new feature
git checkout -b my-fancy-feature
# Change some code
git add .
git commit -m "Feature part1"
# Sync to the latest changelist affecting the workspace
git checkout main
git p4son sync
# Rebase your changes on main
git checkout my-fancy-feature
git rebase main
# Change even more code
git add .
git commit -m "Feature part2"
# Create a Swarm review with all commits since main in one go.
# This opens an interactive rebase with pre-filled exec lines updating
# the changelist with git-p4son after each picked commit.
# An alias called "my-fancy-feature" (derived from the branch name) is
# saved so you can refer to this CL by name in follow-up commands.
git p4son review -m "My fancy feature" -b main
# After review feedback, make more changes
git add .
git commit -m "Address review feedback"
# Update the changelist with latest commit, re-open files, and re-shelve.
# The changelist is looked up by branch name automatically.
git p4son update --shelve
# After approval, submit in p4v
# Sync to the latest changelist from perforce
git checkout main
git p4son sync
# Force remove old branch as you don't need it anymore
git branch -D my-fancy-feature
# Remove changelist alias for the branch
git p4son alias delete my-fancy-feature
# Start working on the next feature
git checkout -b my-next-fancy-feature
Installation
pip install git-p4son
Requires Python 3.11 or later.
Updating
pip install --upgrade git-p4son
For tab completion (zsh and PowerShell), see Shell Completions.
Development
To install from source in editable mode:
git clone https://github.com/neoboid/git-p4son.git
cd git-p4son
pip install -e .
The -e flag installs the package in "editable" mode, meaning changes to the code are immediately available
without reinstalling. This is also handy if you want to auto-update git-p4son whenever you pull from GitHub.
git-p4son only uses Python standard library modules - no additional packages are required.
Git Hooks
The repository includes git hooks in the hooks/ directory:
- pre-commit - verifies that staged Python files are formatted with
autopep8. Install it withpip install autopep8. - pre-push - runs the test suite and blocks the push if any test fails.
To activate the hooks, run:
scripts/setup-hooks.sh
This configures core.hooksPath so git uses the hooks from the repository. You only need to run this once after
cloning.
Setup
These steps set up git-p4son in an existing Perforce workspace. You only need to do this once.
-
Enable clobber on your Perforce workspace. Edit the workspace in P4V to set the clobber flag, or run
p4 clientand changenoclobbertoclobberin the Options line. See Why clobber? for rationale. -
Set a git editor if you don't have one already. The
reviewcommand opens an interactive rebase in your editor. If you haven't configured one, set it with:git config --global core.editor <editor> # e.g. vim, nano, code --wait
-
Sync your workspace to a known changelist. Pick a changelist to use as the starting point for your git history:
p4 sync //...@12345
-
Run
git p4son init. This can be anywhere inside your Perforce workspace — it doesn't have to be at the root:cd /path/to/your/workspace # or a subdirectory of it git p4son init
The command verifies that you are inside a P4 workspace with clobber enabled, prompts you to select a depot root (entire workspace or current directory subtree), runs
git init, sets up.gitignore(copying from.p4ignoreif available), and creates an initial commit. -
Review
.gitignore. Edit the file to ensure build artifacts and other unwanted files are excluded. -
Add and commit all files manually the first time
git add . git commit -m "Initial submit all files"
-
Run
git p4son syncto get your first official sync commitgit p4son sync
This creates a commit with message that records the CL you have synced.
From here, branch off main for local development. See the Usage Example for a typical
workflow.
Why clobber?
When you switch branches with git checkout, git overwrites the files that differ between the source and target branch.
In doing so, it always removes the read-only flag - this is just how git works.
Now imagine one of those files has also been modified in Perforce. The next time p4 sync runs, Perforce will complain
that a file was changed outside its control. At that point you have two options: either force-sync the individual file
with p4 sync -f //path/to/file, or enable the clobber flag on your workspace so that Perforce silently overwrites
writable files.
This is not specific to git-p4son - any workflow that combines git and Perforce in the same workspace will run into it.
And in practice it is harmless: your local changes live on feature branches in git, so when you rebase onto main after
a sync, your changes are reapplied on top of the latest Perforce state.
Usage
git-p4son provides eight commands: init, sync, new, update, review, list-changes, alias,
and completion.
To see help for any command, use -h:
git p4son -h
git p4son sync -h
Note: When invoking via git p4son, the --help flag is intercepted by git (to look for man pages). Use -h
instead, or git p4son -- --help to force it through.
Alternatively, call the executable directly: git-p4son --help.
Global options:
-v, --verbose: Show verbose output (commands, elapsed times, raw subprocess output)--version: Show program version
Init Command
Initialize a git repository inside a Perforce workspace:
git p4son init
This command checks preconditions (Perforce workspace, clobber flag), configures the depot root, runs git init,
sets up .gitignore, and creates an initial commit.
The depot root determines which part of the Perforce workspace git-p4son syncs. You can choose to sync the entire
workspace or just the directory's subtree where the git root is placed. The selection is saved in
.git-p4son/config.toml and used by all subsequent commands.
The .gitignore is set up using this priority:
- If
.gitignorealready exists, it is left as is - If
.p4ignoreexists, it is copied to.gitignoreas a starting point - Otherwise, an empty
.gitignoreis created
Sync Command
Sync local git repository with a Perforce workspace:
git p4son sync [changelist] [--force]
Arguments:
changelist(optional): Changelist number, orlast-syncedto re-sync the last synced changelist. Omit to sync to the latest changelist affecting the workspace.
Options:
-f, --force: Force sync encountered writable files and allow syncing to older changelists.
Examples:
git p4son sync # sync to latest
git p4son sync 12345
git p4son sync last-synced
git p4son sync 12345 --force
New Command
Create a new Perforce changelist and add changed files to it. Description will contain an enumerated list of git commits since the base branch. Optionally creates a Swarm review.
git p4son new -m <message> [alias] [--base-branch BASE_BRANCH] [--force] [--dry-run] [--no-edit] [--no-alias]
[--shelve] [--review]
Arguments:
alias(optional): Alias name to save the new changelist number under. Defaults to the current branch name.
Options:
-m, --message MESSAGE: Changelist description message (required)-b, --base-branch BASE_BRANCH: Base branch for enumerating commits and finding changed files. Default isHEAD~1-f, --force: Overwrite an existing alias file-n, --dry-run: Pretend and print what would be done, but do not execute--no-edit: Skip opening changed files for edit in Perforce--no-alias: Skip saving a changelist alias--shelve: Shelve the changelist after creating it--review: Add#reviewkeyword and shelve to create a Swarm review-s, --sleep SECONDS: Sleep for the specified number of seconds after the command is done
Examples:
git p4son new -m "Fix login bug"
git p4son new -m "Add feature" -b main
git p4son new -m "Fix bug" myalias
git p4son new -m "Fix bug" --no-alias
git p4son new -m "New feature" --review -b main
Update Command
Update an existing Perforce changelist description by replacing the enumerated commit list with the current commits since the base branch. By default also opens changed files for edit.
git p4son update [changelist] [--base-branch BASE_BRANCH] [--dry-run] [--no-desc] [--no-edit] [--shelve]
Arguments:
changelist(optional): Changelist number or named alias to update. Defaults to the current branch name.
Options:
-b, --base-branch BASE_BRANCH: Base branch for enumerating commits and finding changed files. Default isHEAD~1-n, --dry-run: Pretend and print what would be done, but do not execute--no-desc: Skip updating the changelist description--no-edit: Skip opening changed files for edit in Perforce--shelve: Re-shelve the changelist after updating-s, --sleep SECONDS: Sleep for the specified number of seconds after the command is done
Examples:
git p4son update # update changelist for current branch
git p4son update --shelve # update and re-shelve
git p4son update 12345
git p4son update myalias -b main
Review Command
Automate the interactive rebase workflow for creating Swarm reviews. This command generates a rebase todo with exec lines that run git p4son new --review on the first commit and git p4son update --shelve on each subsequent commit, then opens it in your editor for review before executing.
git p4son review [alias] -m <message> [--base-branch BASE_BRANCH] [--force] [--dry-run]
Arguments:
alias(optional): Alias name for the new changelist. Defaults to the current branch name.
Options:
-m, --message MESSAGE: Changelist description message (required)-b, --base-branch BASE_BRANCH: Base branch to rebase onto and find commits since. Default isHEAD~1-f, --force: Overwrite an existing alias file-n, --dry-run: Print the generated rebase todo without executing
When run, the command generates a todo like this and opens it in your editor:
pick abc1234 First commit
exec git p4son new my-feature --review -m 'My feature'
pick def5678 Second commit
exec git p4son update my-feature --shelve
pick ghi9012 Third commit
exec git p4son update my-feature --shelve
You can edit the todo before saving (e.g. reorder commits, remove lines), or abort by clearing the file — just like a normal git rebase -i. Each exec line automatically sleeps after shelving to give Perforce/Swarm time to process.
If the rebase fails mid-way, you can fix the issue and run git rebase --continue as usual.
Examples:
# Review all commits since main (alias defaults to branch name)
git p4son review -m "Add my feature" -b main
# Review just the last commit (default base branch)
git p4son review -m "Fix bug"
# Preview the generated todo without executing
git p4son review -m "Add my feature" -b main --dry-run
List-Changes Command
List commit subjects since a base branch in chronological order (oldest first):
git p4son list-changes [--base-branch BASE_BRANCH]
Options:
-b, --base-branch BASE_BRANCH: Base branch to compare against. Default isHEAD~1.
Examples:
git p4son list-changes
git p4son list-changes --base-branch main
This command is useful for generating changelist descriptions by listing all commit messages since the base branch, numbered sequentially.
Alias Command
Manage changelist aliases stored in .git-p4son/changelists/.
alias list
List all aliases and their changelist numbers:
git p4son alias list
Examples:
git p4son alias list
alias new
Save a changelist number under a named alias:
git p4son alias new <changelist> [alias] [--force]
Arguments:
changelist: Changelist number to savealias(optional): Alias name to save the changelist number under. Defaults to the current branch name.
Options:
-f, --force: Overwrite an existing alias file
Examples:
git p4son alias new 12345 # alias defaults to branch name
git p4son alias new 12345 myfeature
git p4son alias new 67890 myfeature -f
alias delete
Delete a changelist alias:
git p4son alias delete [alias]
Arguments:
alias(optional): Alias name to delete. Defaults to the current branch name.
Examples:
git p4son alias delete # delete alias for current branch
git p4son alias delete myfeature
alias clean
Interactively review and delete changelist aliases:
git p4son alias clean
This command iterates through each alias, displays it, and prompts for action:
y(yes): Delete this aliasn(no): Keep this aliasa(all): Delete this and all remaining aliasesq(quit): Stop and keep remaining aliases
Examples:
git p4son alias clean
Completion Command
Print the path to a shell completion script:
git-p4son completion <shell> [--dirname]
Arguments:
shell: Shell to print completion script path for (bash,zsh, orpowershell)
Options:
-d, --dirname: Print the directory containing the completion script instead of the full file path
See Shell Completions below for installation instructions.
The branch keyword
Most commands that accept an alias or changelist argument default to the current branch name. You can also pass the
branch keyword explicitly — it resolves to an alias name derived from the current git branch.
The keyword cannot be used in a detached HEAD state. Use --no-alias (on new and review) or supply an
explicit alias name instead.
Shell Completions
Tab completion is available for bash, zsh, and PowerShell, including commands, flags, and dynamic alias names.
bash
Add the following to ~/.bashrc:
source $(git-p4son completion bash)
zsh
Add the following to ~/.zshrc before compinit:
fpath=($(git-p4son completion -d zsh) $fpath)
autoload -Uz compinit && compinit
PowerShell
Add the following to your PowerShell profile ($PROFILE):
. $(git-p4son completion powershell)
All three enable completion for git p4son <TAB> and git-p4son <TAB>.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file git_p4son-0.2.8.tar.gz.
File metadata
- Download URL: git_p4son-0.2.8.tar.gz
- Upload date:
- Size: 53.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f07348e9b9b1028ddce8cc00114fc5f03555c6ad8eab1160db427e176145e78
|
|
| MD5 |
23680af667c2d551e106312b1a8a3396
|
|
| BLAKE2b-256 |
aa69962fbafe86edc4b9790cc1c33953fdaf50144990dc0831340ce471f65591
|
Provenance
The following attestation bundles were made for git_p4son-0.2.8.tar.gz:
Publisher:
publish.yml on neoboid/git-p4son
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
git_p4son-0.2.8.tar.gz -
Subject digest:
7f07348e9b9b1028ddce8cc00114fc5f03555c6ad8eab1160db427e176145e78 - Sigstore transparency entry: 1172214692
- Sigstore integration time:
-
Permalink:
neoboid/git-p4son@47632939fac552abf5261df1504bef2591c71489 -
Branch / Tag:
refs/tags/v0.2.8 - Owner: https://github.com/neoboid
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@47632939fac552abf5261df1504bef2591c71489 -
Trigger Event:
push
-
Statement type:
File details
Details for the file git_p4son-0.2.8-py3-none-any.whl.
File metadata
- Download URL: git_p4son-0.2.8-py3-none-any.whl
- Upload date:
- Size: 40.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
83c59b632f54457c20822e4997042c2210d2a6c97f2a54b9c54ab7989b4fdb64
|
|
| MD5 |
b1fd5f1dfb787619cbdb0d28174215ae
|
|
| BLAKE2b-256 |
bc4e0360867ac99bb32185ad82229c8c076468d6413e047a08a5881aeaa27516
|
Provenance
The following attestation bundles were made for git_p4son-0.2.8-py3-none-any.whl:
Publisher:
publish.yml on neoboid/git-p4son
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
git_p4son-0.2.8-py3-none-any.whl -
Subject digest:
83c59b632f54457c20822e4997042c2210d2a6c97f2a54b9c54ab7989b4fdb64 - Sigstore transparency entry: 1172214711
- Sigstore integration time:
-
Permalink:
neoboid/git-p4son@47632939fac552abf5261df1504bef2591c71489 -
Branch / Tag:
refs/tags/v0.2.8 - Owner: https://github.com/neoboid
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@47632939fac552abf5261df1504bef2591c71489 -
Trigger Event:
push
-
Statement type: