git-merge-one-file
Merge changes from another branch into one file
SYNOPSIS
git-merge-one-file <base> <ours> <theirs> [<path>]
PARAMETERS
<base>
Path to the common ancestor version of the file. This represents the state of the file before divergent changes were made on 'ours' and 'theirs' branches.
<ours>
Path to our version of the file. This is the content of the file from the current branch or working tree.
<theirs>
Path to their version of the file. This is the content of the file from the branch being merged into 'ours'.
<path>
Optional path to the file in the working tree. This argument is crucial when git-merge-one-file is used as a merge driver, as it allows the script to query Git's configuration (e.g., merge.<driver>.name) based on the file's attributes or context. The merged content might also be written to this path.
DESCRIPTION
git-merge-one-file is a low-level, internal Git helper script designed to perform a 3-way merge operation on a single file. Unlike user-facing commands like git merge, this script is not typically invoked directly by end-users. Instead, it serves as a plumbing command that can be used by other Git components, such as git mergetool, or more commonly, as a custom merge driver configured via .gitattributes.
It takes three versions of a file—the common ancestor (base), our version (ours), and their version (theirs)—and attempts to combine them. If the merge is successful, the merged content is usually written to standard output or directly into the specified working tree path. If conflicts arise, it attempts to mark them using standard Git conflict markers.
Its primary purpose is to provide a reusable primitive for merging individual files, allowing Git to delegate specific merge logic for particular file types or scenarios.
CAVEATS
This command is an internal Git plumbing script and is generally not meant for direct invocation by end-users. Its behavior and specific arguments can vary slightly between Git versions or even depending on how it's integrated within a specific Git installation (e.g., if it's a shell script in contrib/). It relies on Git's internal merge machinery and configuration to perform its task, especially when acting as a custom merge driver.
RETURN VALUE
The script typically exits with a status code of 0 if the merge is successful and no conflicts remain. A non-zero exit code (e.g., 1) indicates that conflicts were detected and the merged output contains conflict markers, or that an error occurred during the merge process.
USAGE AS CUSTOM MERGE DRIVER
One of the most common applications of git-merge-one-file is as a custom merge driver. This allows users to define specific merge strategies for particular file types. To do this, you would:
1. Configure a merge driver in your Git configuration (e.g., .git/config or ~/.gitconfig):
[merge "your-driver-name"]
name = Your Custom Merge Driver
driver = /path/to/git-merge-one-file %O %A %B %L %P
Note: The parameters for driver are standard for Git merge tools (%O=base, %A=ours, %B=theirs, %L=output, %P=path), and git-merge-one-file expects them in a specific order.
2. Associate the driver with file patterns in .gitattributes:
*.your_extension merge=your-driver-name
This setup ensures that when Git merges files matching *.your_extension, it will invoke your custom driver, which in turn leverages git-merge-one-file to perform the actual 3-way merge.
HISTORY
The concept behind git-merge-one-file has been fundamental to Git's merge strategy since its early days. As Git evolved, the need for a standardized, reusable component to handle single-file merges became apparent, especially for custom merge drivers. While often implemented as a shell script in the contrib/ directory of the Git source, its role is to provide a clean interface for external tools or internal components to leverage Git's powerful 3-way merge capabilities on a granular, per-file basis, without needing to understand the complexities of full repository merging.
SEE ALSO
git-merge(1), git-mergetool(1), gitattributes(5), git-config(1)