Utility script that synchronizes a local repository with all remotes:
- fetches all remotes
- fast-forwards all local branches that have a remote upstream
- pushes upstream changes to the default push remote
- fast-forwards or deletes branches associated with merged PRs to the merge commit
- deletes merged fork branches from your push remote if they are unchanged since the merge
Not all git configuration is taken into account; please open an issue if this causes problems.
As an example, suppose you have a local repository with a main branch, your main branch has upstream/main as its upstream, and your remote.pushdefault config is origin. What happens when you run git sync?
If you are currently working on main, it will use git pull --all to fetch all remotes and update main in a single step; otherwise, it will run git fetch --all, then use git fetch . upstream/main:main to fast-forward in changes. Finally, in both cases it will run git push origin main.
Git understands merge commits and handles them nicely. For instance, if a branch F is merged to main with a merge commit, the git command git branch -d F will succeed without warning, as it knows F is merged to main. If you have further work on a child branch, git pull will know to drop any merged commits automatically.
Squash commits break this model, as they deliberately do not record the information git needs to determine that a branch commit is in the history of main. This means having to do branch -D and risking mistakenly deleting unmerged commits if you have misremembered which branches have merged.
If you have remote.pushdefault set and $GITHUB_TOKEN in your environment, git sync will query the last 50 PRs from each remote, and if it finds a merge commit for a local branch, will fast-forward that branch to the merge commit. This gives git enough information to reenable the safer workflows.
GitHub can be configured to delete the PR branch on merge, but not everything that merges PRs respects that setting. git sync will delete any leftover merged PR branch from your push remote, provided the branch is still at the commit it was merged at, and the PR was raised from a fork (that is, the branch is in your own repository, not one shared with colleagues).
To install, use pipx:
pip install pipx
python -m pipx ensurepath # Permanently updates your $PATH
pipx install git+https://github.com/alicederyn/git-sync.git