Runbook - arxanas/git-branchless GitHub Wiki

Releasing

To release a new version:

  • Run cargo release patch to update the version number and publish the code to crates.io.
  • Update CHANGELOG.md and add a new header for the about-to-be-released version. Make sure to keep an empty [Unreleased] section header at the top.
  • Commit the above changes with a message like docs: release version v1.2.3.
  • Tag the previous commit with the version number (git tag v1.2.3).
  • Push the commit to Github.
  • Create a Github release for the version tag. Leave the release title empty to automatically use the tag name as the release title. Copy and paste the changelog contents for this version into the release notes.

Unit testing

Running tests locally

Run tests with cargo test. The tests depend on the version of Git you're using, so you need to provide a Git environment via the TEST_GIT and TEST_GIT_EXEC_PATH environment variables. For example:

$ TEST_GIT=$(which git) TEST_GIT_EXEC_PATH=$(git --exec-path) cargo test  # use globally-installed version
$ TEST_GIT=/path/to/build/dir/git TEST_GIT_EXEC_PATH=/path/to/build/dir cargo test  # use the `git` executable inside /path/to/build/dir

To set default values for these environment variables so that you don't have to specify them each time, you can create a config.toml file like this (see the Cargo documentation):

[env]
TEST_GIT = "/usr/local/bin/git"
TEST_GIT_EXEC_PATH = "/usr/local/Cellar/git/2.32.0_1/libexec/git-core"

Run the linter with cargo clippy -- -D warnings (see https://github.com/rust-lang/rust-clippy for installation instructions).

Run the formatter with cargo fmt, or through your editor.

Updating tests

The project uses cargo-insta for snapshot testing. You can download the command-line utility with cargo install cargo-insta to make it easier to update test cases when the output changes:

  • Use cargo insta accept to accept all differences in snapshots.
  • Use cargo insta review to review differences interactively.
  • Use cargo insta reject to reject all differences in snapshots.

Running tests in CI

Tests will automatically run in Github Actions when you open a pull request against the repository. These include various versions of Git on Linux, as well as on Windows.

Some builds only run later, for performance reasons:

Debugging tests in CI

If you're encountering strange test failures that only appear in CI, try adding a Debugging with tmate step to a failing Github Actions .yml workflow file:

- name: Setup tmate session
  uses: mxschmitt/action-tmate@v3

Testing subcommands in isolation

To improve the build feedback loop time, many git-branchless subcommands have been extracted into their own crates (see Improving incremental test times in Rust), so that they can be compiled and run separately. To enable building and testing individual subcommands only, set the TEST_SEPARATE_COMMAND_BINARIES environment variable with a list of space-separated subcommand names to invoke as individual executables (instead of via the main git-branchless binary):

$ TEST_SEPARATE_COMMAND_BINARIES='record' cargo test -p git-branchless-record

Note that this system is hacky and will probably cause mysterious test failures with build artifacts that haven't been properly updated 🙃.

Manual testing

Global installation

If you just want to test out a build without making any changes to it, you can install it directly with cargo install.

To build the latest version from master, use cargo install --git:

$ cargo install --locked --git https://github.com/arxanas/git-branchless git-branchless

If there's a specific branch you want to test, you can add the --branch flag, e.g.:

$ cargo install --locked --git https://github.com/arxanas/git-branchless --branch restack git-branchless

If there's a tagged release candidate you want to test, you can add the --tag flag, e.g.:

$ cargo install --locked --git https://github.com/arxanas/git-branchless --tag v0.7.0-rc.1 git-branchless

Note that if the branch is on a fork of the repository, then you have to specify that repository instead, e.g.:

$ cargo install --locked --git https://github.com/some-other-user/git-branchless --branch some-feature git-branchless

You may want to re-install the released version of git-branchless after you're done (see Installation):

$ cargo install --locked git-branchless

Local installation

If you want to make changes to the codebase and test them out, you probably want to check out the repository locally and build it there:

$ git clone https://github.com/arxanas/git-branchless
$ cd git-branchless

If you have a specific pull request you want to check out, you can use the gh utility to check it out:

$ gh pr checkout 326

Once you've made your changes, you can then use cargo run to build and run git-branchless:

$ cargo run -- smartlog  # runs `git-branchless smartlog`

(You don't need to manually invoke cargo build, as cargo run will do it for you if the executable is out of date.)

To test in a repository other than the git-branchless source code, you can pass the -C flag to git-branchless:

$ cargo run -- -C ~/Workspace/your-other-repository smartlog

Profiling

With tracing

git-branchless uses the tracing library for profiling. Only functions which are annotated with #[instrument] and explicitly-created span!s are captured in the traces. Learn more...

You can produce a profile by running a git-branchless command by setting certain environment variables:

  • RUST_PROFILE=1 to produce a profile with an automatically-generated name.
  • RUST_PROFILE=foo.json to produce a profile written to foo.json-* (see below).
  • RUST_PROFILE_INCLUDE_ARGS=1 to include argument values in the function call traces.

For example:

$ RUST_PROFILE=foo.json cargo run -C /path/to/repo smartlog
...
$ git status
HEAD detached at f08491d
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        foo.json-0

Since git-branchless sometimes invokes itself in a subprocess (via Git hook), the nesting level is tracked internally, and you may see files of the form foo.json-0, foo.json-1, etc.

The produced profiles can be imported into chrome://tracing (on Google Chrome) or https://ui.perfetto.dev/ (all browsers).

With cargo-flamegraph

You can use cargo flamegraph to produce flamegraphs using a system profiler (perf on Linux or dtrace elsewhere). This is a relatively polished and low-configuration setup. In particular, it can be useful if you want to examine performance using a sampling rather than tracing method:

  • Pro: In principle, it should have less runtime overhead.
  • Pro: You can check the performance of function calls which aren't annotated for tracing, such as calls into the libgit2 (a C library).
  • Con: Not all function calls will be tracked, as they're merely sampled.

Note for macOS users: System Integrity Protection may require that you run cargo flamegraph as root, i.e. with sudo. Otherwise, dtrace may fail to attach to the process.

Supported Git versions

See the compatibility matrix at https://github.com/arxanas/git-branchless/wiki/Git-compatibility. For now, git-branchless is committed to supporting Git v2.24 and later, where reasonable.

Note that the reference-transaction hook is only supported from Git v2.29 and later. This means that some tests will have different behavior in older versions of Git. Many tests check to see if reference transactions are supported before proceeding, e.g.

if !git.supports_reference_transactions()? {
    return Ok(());
}
⚠️ **GitHub.com Fallback** ⚠️