Note: This alias and the explanation below were created with Gemini 3, and manually edited for clarity and comprehensiveness.
This alias allows you to check whether a branch has been fully merged into a target branch (even if squash-merged or rebase-merged) and, if not, view the exact diff of what remains to be integrated.
Unlike a standard git diff, this approach:
- Ignores history divergence: It bypasses any changes that may have been added to the target branch on top of the point that your branch branched off from. In other words, it compares the final state of your branch against the target, as if you had done a
git rebase <target>followed bygit diff <target>. - Handles conflicts gracefully: It simulates a merge in-memory, resolving any conflicts in favor of your branch (via the
-Xtheirsoption). This means you see a clean diff of "your changes" without being blocked by conflict markers.
Add this to your ~/.gitconfig or .git/config file:
[alias]
# Usage: git merge-diff [target_branch] [source_branch]
# Example: git merge-diff main my-feature
merge-diff = "!f() { \
target=${1:-main}; \
source=${2:-HEAD}; \
target_sha=$(git rev-parse \"$target\"); \
source_sha=$(git rev-parse \"$source\"); \
echo \"Comparing $source changes against $target (resolving conflicts to 'theirs')...\"; \
tree_oid=$(git merge-tree --write-tree -Xtheirs \"$target_sha\" \"$source_sha\" | head -n 1); \
git diff \"$target_sha\" \"$tree_oid\"; \
}; f"The core of this solution is git merge-tree. Introduced in Git 2.38, its --write-tree mode allows us to perform a real merge calculation without touching your working directory or index.
We use the -Xtheirs merge strategy option to instruct Git that if any conflicts occur, it should assume the content from your feature branch is the correct version. This produces a "clean" tree object representing what the project would look like if you merged your branch right now (and "won" all conflicts). We then simply git diff that hypothetical tree against the target branch.
Here is the step-by-step logic of the alias script.
target=${1:-main};
source=${2:-HEAD};We default the target branch to main and the source (the branch you are checking) to HEAD. This allows you to run git merge-diff to check the current branch, or git merge-diff master feature-branch to check others.
target_sha=$(git rev-parse "$target");
source_sha=$(git rev-parse "$source");We verify that both branches exist and resolve them to their full commit hashes using git rev-parse.
tree_oid=$(git merge-tree --write-tree -Xtheirs "$target_sha" "$source_sha" | head -n 1);This is the magic line.
git merge-tree --write-tree: Performs the merge in memory and outputs the resulting Tree Object ID.-Xtheirs: Automatically resolves conflicts by favoring thesourcebranch.| head -n 1:merge-treeoutputs the tree ID on the first line. If there were conflicts (even resolved ones), it might print informational messages on subsequent lines. We only care about the ID.
git diff "$target_sha" "$tree_oid";Finally, we run git diff to compare the target branch (e.g., main) against our generated merge result.
- If the diff is empty, the branch is fully merged.
- If not, the output shows exactly what code your branch adds or modifies.
- Git version: This alias requires Git 2.38 or later (released Oct 2022) for the
--write-treeoption. - Conflict visibility: Because we use
-Xtheirs, this alias hides conflicts. It is designed to answer "What changes does this branch bring?", not "Will this branch merge cleanly?". If you want to check for conflicts, simply rungit merge-tree --write-tree target sourceand check the exit code (1 means conflicts).