tmux portable is maintained from two repositories:
tmuxis the portable repository. It contains the portability layer, autotools build files, regression tests, documentation, and code needed for platforms outside OpenBSD.tmux-openbsd-cutoveris the OpenBSD tmux import repository. Itsmasterbranch is the OpenBSD tmux history after the OpenBSD Git cutover. Portable merges this branch when importing OpenBSD changes.
To create the commits in the tmux-openbsd-cutover repo, the source repo is the Github mirror of OpenBSD's src repo:
https://github.com/openbsd/src.git
The update automation filters the OpenBSD source tree to usr.bin/tmux/,
publishes that filtered history as openbsd-git in the cutover repository,
cherry-picks new filtered commits onto cutover master, then merges cutover
master into portable master.
If you've never used git before, configure your identity before committing:
git config [--global] user.name "Your name"
git config [--global] user.email "you@yourdomain.com"The usual local layout is:
cd /some/where/useful
git clone https://github.com/tmux/tmux.git tmux-portable
git clone https://github.com/tmux/tmux-openbsd-cutover.git tmux-openbsd-cutoverThe exact directory names do not matter, but the examples below use:
/path/to/tmux-portable
/path/to/tmux-openbsd-cutover
The cutover repository has three important branches:
masteris the branch portable consumes. It should contain tmux source only, not automation files.openbsd-gitis the raw filtered OpenBSD tmux branch generated from OpenBSD srcmaster.automationis an orphan branch containing the GitHub Actions workflow. It is separate so that workflow files are not merged into portable.
In the portable repository, add the published cutover repository as a remote. This works regardless of which branch is checked out in a local cutover clone:
cd /path/to/tmux-portable
git remote add tmux-openbsd https://github.com/tmux/tmux-openbsd-cutover.git
git config remote.tmux-openbsd.tagOpt --no-tagsIf the remote already exists, update it instead:
git remote set-url tmux-openbsd https://github.com/tmux/tmux-openbsd-cutover.git
git config remote.tmux-openbsd.tagOpt --no-tagsFetch the cutover master branch explicitly:
git fetch --no-tags tmux-openbsd master:refs/remotes/tmux-openbsd/masterTo merge unpublished changes from a local cutover clone instead, first ensure
it has an up-to-date local master branch. A normal clone may check out
automation and have only origin/master; fetching master from that clone
will then fail with couldn't find remote ref master.
With a clean cutover working tree:
cd /path/to/tmux-openbsd-cutover
git fetch --no-tags origin
git switch master
git merge --ff-only origin/mastergit switch master creates a tracking branch from origin/master if there is
no local master yet. If the fast-forward fails, reconcile the local cutover
changes before continuing; do not reset them away.
Then, in portable, point the remote at that clone and fetch its local master:
cd /path/to/tmux-portable
git remote set-url tmux-openbsd /path/to/tmux-openbsd-cutover
git fetch --no-tags tmux-openbsd master:refs/remotes/tmux-openbsd/masterThe normal sync is performed by the GitHub Actions workflow in the
automation branch of the cutover repository. That workflow:
- Fetches or clones OpenBSD src using a blobless clone.
- Filters
usr.bin/tmux/into a localtmux-openbsdbranch. - Updates
tmux-openbsd-cutover/openbsd-git. - Cherry-picks new
openbsd-gitcommits onto cutovermaster. - Merges cutover
masterinto portablemaster. - Pushes the changed repositories.
The workflow deliberately runs from the orphan automation branch but checks
out cutover master as the branch to update. This keeps .github/ out of
cutover master, so portable does not import workflow files when it merges
OpenBSD changes.
If the workflow fails while merging into portable, do the merge locally and push the result.
Start with a clean working tree and an up-to-date portable master. If a merge is already in progress, skip to resolving conflicts, or abort it before starting again:
cd /path/to/tmux-portable
git fetch origin
git checkout master
git pull --ff-only origin masterFetch the published cutover branch. Update an existing remote as well, since
it may point at a local clone without a master branch or with a stale one:
if git remote get-url tmux-openbsd >/dev/null 2>&1; then
git remote set-url tmux-openbsd https://github.com/tmux/tmux-openbsd-cutover.git
else
git remote add tmux-openbsd https://github.com/tmux/tmux-openbsd-cutover.git
fi
git config remote.tmux-openbsd.tagOpt --no-tags
git fetch --no-tags tmux-openbsd master:refs/remotes/tmux-openbsd/masterMerge it:
git merge --no-ff --log refs/remotes/tmux-openbsd/masterIf merging a local cutover branch instead, use the local-clone preparation and fetch commands above in place of this fetch block.
When the merge reports conflicts, it leaves the merge in progress. List the unresolved files, edit the conflict markers to combine the required portable and OpenBSD changes, then stage each resolved file:
git diff --name-only --diff-filter=U
git diff -- path/to/file
git add path/to/fileFor files that should come entirely from one side, decide whether portable or OpenBSD owns the file before using the commands below. They replace the whole file, including changes outside the conflicting hunks.
Useful commands:
git checkout --ours path/to/file
git add path/to/fileThis keeps the portable version of a conflicted file.
git checkout --theirs path/to/file
git add path/to/fileThis takes the OpenBSD/cutover version of a conflicted file.
For a modify/delete conflict, the side that deleted the file has no version
to check out. For example, portable generates Makefile using autotools and
does not track OpenBSD's Makefile. If Git reports that Makefile was deleted
in HEAD and modified in cutover, keep the portable deletion with:
git rm -- MakefileThis removes the OpenBSD file left by the merge; regenerate the portable
Makefile with your usual configure command before building. Use this only
for the unmerged OpenBSD file, not an existing generated build file.
Before committing, inspect the result:
git status
git diff --check
git diff --cached --check
git diff --cached --statThen finish and publish:
git commit
git push origin masterIf the merge attempt is wrong, abort it:
git merge --abortAfter pushing a manually resolved merge, rerun the workflow. It should either no-op or continue from the now-merged portable state.
Normally this is handled by the workflow. If it must be done manually, update
openbsd-git in the cutover repository from a filtered OpenBSD src checkout,
then cherry-pick the new filtered commits onto cutover master.
The important range is:
origin/openbsd-git..openbsd-git
where origin/openbsd-git is the previously published filtered OpenBSD tmux
branch and openbsd-git is the newly generated filtered branch.
In the cutover repository:
cd /path/to/tmux-openbsd-cutover
git checkout master
git cherry-pick origin/openbsd-git..openbsd-git
git push origin master openbsd-gitDo not put workflow files on cutover master; keep them on the orphan
automation branch.
A lot of the compat/ code in tmux comes from OpenBSD libraries, especially
imsg. Sometimes APIs change in OpenBSD in ways that require corresponding
portable changes. It is worth checking periodically for relevant OpenBSD
libutil changes and syncing those files into compat/ as appropriate.
-
Update and commit README and CHANGES. The former should be checked for anything outdated and updated with a list of things that might break upgrades and the latter should mention all the major changes since the last version.
-
Make sure
configure.achas the new version number. -
Tag with:
% git tag -a 2.X
Where
2.Xis the next version.Push the tag out with:
% git push --tags
-
Build the tarball with
make dist. -
Check the tarball. If it is good, go here to select the tag just pushed:
https://github.com/tmux/tmux/tagsClick "Add release notes", upload the tarball and add a link in the description field to the CHANGES file.
-
Clone the tmux.github.io repository, and change the RELEASE version in the Makefile. Commit it, and run
maketo replace%%RELEASE%%. Push the result out. -
Change version back to master in
configure.ac.