# shadps4-emu Version Control Strategy: How shadPS4 Manages Git-Based Build Metadata

> Discover the shadps4-emu version control strategy. Learn how Git-based build metadata ensures accurate version reporting for every shadPS4 build across all platforms.

- Repository: [shadps4-emu/shadPS4](https://github.com/shadps4-emu/shadPS4)
- Tags: internals
- Published: 2026-03-19

---

**shadPS4 uses a Git-driven CMake configuration to automatically embed commit SHAs, branch names, and version metadata into every build, ensuring accurate version reporting across all platforms.**

The shadps4-emu version control strategy eliminates manual version bumps by deriving build identity directly from Git state. This approach ensures that every binary—whether built by a developer locally or by CI pipelines—carries precise provenance information visible in the UI and crash logs.

## How shadPS4 Implements Git-Driven Version Detection

The build system executes Git commands during the CMake configuration phase to capture repository state before compilation begins.

### Extracting Commit Metadata with git rev-parse

In [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt) (lines 107–112), the build system invokes `git rev-parse` and `git describe` to obtain two critical identifiers:

- `GIT_REV`: The full 40-character commit SHA
- `GIT_DESC`: A human-readable string combining the nearest tag, number of commits since that tag, and short SHA

```cmake
execute_process(
    COMMAND git rev-parse HEAD
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    OUTPUT_VARIABLE GIT_REV
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

```

### Resolving Remote and Branch Information

The strategy handles complex Git states including detached HEAD, shallow clones, and CI environments. Lines 116–184 of [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt) implement a fallback chain:

1. Check GitHub Actions environment variables (`GITHUB_HEAD_REF`, `GITHUB_REF`)
2. Parse `git rev-parse --abbrev-ref HEAD` for local builds
3. Detect pull request contexts and synthesize branch names as `pr-<num>-<ref>`
4. Default to "origin" for remotes and "detached-head" for branch when Git metadata is unavailable

## Generating Compile-Time Version Constants

Once CMake captures the Git metadata, it injects these values into the source code through template generation.

### The scm_rev.cpp.in Template System

The file `src/common/scm_rev.cpp.in` serves as a template containing placeholders like `@APP_VERSION@`, `@GIT_REV@`, and `@GIT_BRANCH@`. During configuration, CMake processes this template into [`src/common/scm_rev.cpp`](https://github.com/shadps4-emu/shadPS4/blob/main/src/common/scm_rev.cpp) (lines 10–18), replacing placeholders with actual values:

```cpp
constexpr char g_version[] = "@APP_VERSION@";
constexpr char g_scm_rev[] = "@GIT_REV@";
constexpr char g_scm_branch[] = "@GIT_BRANCH@";
constexpr char g_scm_desc[] = "@GIT_DESC@";
constexpr bool g_is_release = @IS_RELEASE@;

```

The generated [`scm_rev.cpp`](https://github.com/shadps4-emu/shadPS4/blob/main/scm_rev.cpp) is excluded from version control (via `.gitignore`) to prevent stale metadata from being committed.

### Windows Resource File Integration

For Windows builds, the three-part semantic version (`EMULATOR_VERSION_MAJOR`, `MINOR`, `PATCH`) defined in CMake (lines 200–210) propagates into `src/shadps4.rc`. This embeds version information into the Windows executable properties dialog, ensuring consistency between the application's internal version API and the operating system's file metadata.

## Conditional Updater Logic Based on Repository Origin

The shadps4-emu version control strategy includes safety mechanisms to prevent auto-updates from unofficial forks. Lines 176–180 of [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt) implement the following logic:

- If `GIT_REMOTE_URL` does not match the official `shadps4-emu/shadPS4` repository, disable the updater
- If `GIT_BRANCH` is not `main` or a release tag, disable the updater
- Set `ENABLE_UPDATER` to `OFF` in these cases to prevent builds from non-standard sources from attempting to auto-update

This ensures that development builds from feature branches or personal forks do not accidentally overwrite themselves with upstream binaries.

## Accessing Version Data at Runtime

Applications and developers can query the embedded metadata through the `Common` namespace defined in [`src/common/scm_rev.h`](https://github.com/shadps4-emu/shadPS4/blob/main/src/common/scm_rev.h).

### Reading Version Information

```cpp
#include "common/scm_rev.h"
#include <iostream>

void print_build_info() {
    std::cout << "Version: " << Common::g_version << '\n';
    std::cout << "Commit: " << Common::g_scm_rev << '\n';
    std::cout << "Branch: " << Common::g_scm_branch << '\n';
    std::cout << "Description: " << Common::g_scm_desc << '\n';
    std::cout << "Release build: " << (Common::g_is_release ? "Yes" : "No") << '\n';
}

```

### Conditional Compilation Based on Updater Availability

```cpp
#if defined(ENABLE_UPDATER) && ENABLE_UPDATER
    // Safe to call auto-update logic
    Updater::CheckForUpdates();
#else
    LOG_WARNING(Updater, "Auto-updater disabled for this build configuration.");
#endif

```

## Summary

- **Git-driven metadata**: shadPS4 extracts commit SHAs, branch names, and tags during CMake configuration using `git rev-parse` and `git describe`.
- **Template generation**: The build system processes `src/common/scm_rev.cpp.in` to create compile-time constants in [`scm_rev.cpp`](https://github.com/shadps4-emu/shadPS4/blob/main/scm_rev.cpp), ensuring version data is embedded without manual editing.
- **Cross-platform consistency**: Windows resource files (`shadps4.rc`) receive the same semantic version defined in CMake, aligning OS-level metadata with application internals.
- **Safety mechanisms**: The updater automatically disables itself when building from unofficial remotes or non-main branches, preventing accidental updates from development forks.

## Frequently Asked Questions

### How does shadPS4 handle version information when building from a shallow clone?

When Git history is limited (shallow clone), the `git describe` command may fail to find tags. The CMake logic in [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt) (lines 107–112) still captures the commit SHA via `git rev-parse`, ensuring `GIT_REV` is always accurate even if `GIT_DESC` falls back to a short SHA without tag information.

### Can I override the automatic version detection in shadPS4 builds?

Yes. While the build system automatically populates [`src/common/scm_rev.cpp`](https://github.com/shadps4-emu/shadPS4/blob/main/src/common/scm_rev.cpp) from the template, you can manually define the CMake variables (`GIT_REV`, `GIT_BRANCH`, `APP_VERSION`) before configuration to override the Git-driven values. However, this is discouraged for official builds as it breaks the single-source-of-truth principle.

### Why does shadPS4 disable the updater on non-main branches?

The conditional logic in [`CMakeLists.txt`](https://github.com/shadps4-emu/shadPS4/blob/main/CMakeLists.txt) (lines 176–180) sets `ENABLE_UPDATER=OFF` when the detected branch is not `main` or a release tag. This prevents development builds, feature branches, and pull request artifacts from attempting to auto-update to upstream releases, which could overwrite unstable test builds with incompatible stable binaries.

### Where does shadPS4 store the generated version constants for runtime access?

The CMake configuration generates [`src/common/scm_rev.cpp`](https://github.com/shadps4-emu/shadPS4/blob/main/src/common/scm_rev.cpp) from the template `src/common/scm_rev.cpp.in`. This generated file defines `constexpr` constants in the `Common` namespace (such as `g_version`, `g_scm_rev`, and `g_scm_branch`) which are declared in [`src/common/scm_rev.h`](https://github.com/shadps4-emu/shadPS4/blob/main/src/common/scm_rev.h) and accessible throughout the codebase at runtime.