Synopsis
# compare two files or two folders (text / hex / folder is detected)
DiffScope.exe <left> <right> [options]
DiffScope.exe /base:<left> /mine:<right> # TortoiseMerge diff style
DiffScope.exe --left <left> --right <right>
# 3-way merge
DiffScope.exe /base:B /mine:M /theirs:T /merged:OUT
DiffScope.exe --merge --base B --mine M --theirs T -o OUT
DiffScope.exe --merge <base> <mine> <theirs> [-o OUT]
DiffScope.exe <mine> <theirs> <base> <merged> # Beyond Compare order
# no window: unified diff / merge result, exit codes 0, 1, 2
DiffScope.exe --headless <left> <right> > out.diff
DiffScope.exe --headless --merge B M T -o OUT
With no arguments, DiffScope opens the home screen. DiffScope.exe --help prints the built-in summary.
Syntax rules
Slash switches
Slash switches take their value after : or =, for example /base:file.txt or /title1="My file". Keywords are not case-sensitive.
When is /something a switch?
Only when the word after the slash is one of DiffScope's keywords, followed by the end of the argument, : or =. Everything else is a path. So C:\a b\c.txt, a Git Bash path such as /c/Users/me/a.txt, /base/dir/file and /tmp/x are all treated as paths.
The keywords are:
base mine theirs merged savetarget left right basename minename theirsname mergedname lefttitle righttitle centertitle outputtitle title1 title2 title3 title4 readonly ro leftreadonly rightreadonly automerge reviewconflicts help ?
- Values may be wrapped in double quotes; one pair of surrounding quotes is removed.
- A switch that needs a value but has none (
/base) is an error. So is a value on a flag (/readonly:yes). - An argument that is exactly a keyword (
/ro) is always a switch. To pass a file with that name, put it after--or write.\ro.
GNU options
- Long options take values as
--base fileor--base=file. Long option names are not case-sensitive. - Short flags can be grouped (
-wiB), and short values can be attached (-U5,-oout.txt,-o=out.txt). - An unknown option is an error, and DiffScope suggests the closest name (did you mean --ignore-case?).
--ends the options. Everything after it is a path, even-x.txtor/title1:x.
Windows and Git Bash paths
- Relative paths are resolved against the current folder.
- If a Git Bash style path such as
/c/Users/me/a.txtdoes not exist as written, DiffScope converts it toC:\Users\me\a.txt. - Do not end a quoted path with a backslash (
"C:\dir\"): Windows reads\"as an escaped quote. Write"C:\dir". - Reading from standard input (
-) is not supported.
Positional forms
| Paths | Meaning |
|---|---|
| 2 | <left> <right>: a two-way compare of two files or two folders. |
3, with --merge | <base> <mine> <theirs>: a merge. Give the output with -o. Three paths without --merge are rejected as ambiguous. |
| 4 | <mine> <theirs> <base> <merged>: a merge in Beyond Compare order (left, right, center, output). |
| 1 or 5+ | Rejected. |
Positional paths cannot be mixed with named paths (/base, --mine and so on), and the same path cannot be given twice.
Switch reference
Paths
| Slash | GNU | Meaning |
|---|---|---|
/base:P | --base P | Merge: the common ancestor. With only /mine beside it: the left file of a diff. |
/mine:P | --mine P, --local P | Merge: your version. With only /base: the right file of a diff. |
/theirs:P | --theirs P, --remote P | Merge: the incoming version. |
/merged:P, /savetarget:P | -o P, --output P, --merged P, --out P | Merge: the file to write. Optional in the window (you are asked on save); in headless mode the result goes to stdout without it. |
/left:P | --left P | Diff: the left path. |
/right:P | --right P | Diff: the right path. |
A merge starts when /theirs, /merged or --merge is present; it then needs all of base, mine and theirs. /left /right cannot be mixed with /base /mine /theirs.
Titles
| Slash | GNU | Meaning |
|---|---|---|
/title1:T … /title4:T | --title1 T … --title4 T | Diff: 1 = left, 2 = right (3 and 4 are ignored). Merge: 1 = mine, 2 = theirs, 3 = base, 4 = output (Beyond Compare numbering). |
/basename:T, /centertitle:T | --base-title T | Base title. For a TortoiseMerge-style diff: the left title. |
/minename:T | --mine-title T | Mine title. For a TortoiseMerge-style diff: the right title. |
/theirsname:T | --theirs-title T | Theirs title. |
/mergedname:T, /outputtitle:T | --merged-title T | Output title. |
/lefttitle:T | --left-title T | Left title (mine in a merge). |
/righttitle:T | --right-title T | Right title (theirs in a merge). |
| – | -L T, --label T | Repeatable, as in GNU diff and git merge-file. Diff: left, then right. Merge: mine, base, theirs. |
An empty value (/title1:) gives an empty title. Titles also label the conflict markers and the --- / +++ lines of headless output.
Modes
| Option | Meaning |
|---|---|
--merge, -m | 3-way merge. |
--diff, -d | Force a two-way compare (cannot be combined with merge paths). |
--headless | Run without a window. See Headless mode. |
--text | Compare two files as text even if they look binary. |
--hex, --binary | Compare two files byte by byte in the hex view. |
--folder | Require two folders (headless mode fails if they are not). |
Only one of --text, --hex and --folder can be given. Merges are always text, so --hex and --folder are rejected for a merge.
Comparison options
| Option | Meaning |
|---|---|
--ignore-whitespace[=MODE] | MODE is all (default when given without a value), changes, leading-trailing or none. |
-w, --ignore-all-space | Ignore all whitespace. |
-b, --ignore-space-change | Ignore changes in the amount of whitespace. |
--ignore-leading-trailing | Ignore whitespace at the start and end of lines. |
-i, --ignore-case | Ignore case. |
-B, --ignore-blank-lines | Ignore inserted or removed blank lines. |
-U N, --context N, --unified N | Lines of context in headless unified diffs (default 3). |
--diff3 | Add a ||||||| base section to conflict markers (window and headless). See diff3 style. |
These options also set the matching toolbar controls when a text compare window opens.
Folder options
| Option | Meaning |
|---|---|
--compare=MODE | content (default), size or size-mtime. See compare modes. |
--exclude PATTERN | Leave out matching files and folders. Repeat for more patterns. See exclude patterns. |
--no-recursive | Compare the top level only. |
--all | Headless folder output also lists unchanged entries. |
Read-only
| Slash | GNU | Meaning |
|---|---|---|
/leftreadonly | --left-readonly | The left side cannot be edited. |
/rightreadonly | --right-readonly | The right side cannot be edited. |
/readonly, /ro | --readonly, --read-only, -r | Neither side can be edited. |
Other
| Option | Meaning |
|---|---|
--help, -h, /?, /help | Print the usage summary and exit with 0. |
--version, -v, -V | Print DiffScope and the version (for example DiffScope 1.0.1) and exit with 0. |
--smoke-test | Start the window, run a self-check on built-in samples and exit. |
/automerge, /reviewconflicts | Accepted for compatibility with tools that pass them. They have no effect: non-conflicting changes are always merged. |
Headless mode
With --headless, DiffScope runs the comparison or merge without opening a window, prints the result and exits.
Redirect or pipe the output
DiffScope.exe is a Windows GUI program, so its output does not appear in an interactive PowerShell or cmd window. Redirect it to a file (> out.diff) or pipe it (| Out-File, | cat). Pipes, files, git and CI runners receive it normally. The output starts with one empty line, and Chromium may print warnings on stderr. Neither affects the exit code.
What it prints
| Input | Output |
|---|---|
| Two text files | A unified diff (---, +++, @@ hunks) on stdout, nothing when identical. If only the encoding or line endings differ: Files A and B differ only in … |
| Two binary files | Binary files A and B differ, both sizes, the number of differing ranges, the first differing offset, and up to 50 ranges with a 16-byte preview of each side. |
| Two folders | A tree of differences: * different, < left only, > right only, ! type mismatch, ? error (and = same with --all), then a summary line. |
Merge with -o | Writes the merged file (git-style conflict markers where needed) and prints Merged cleanly: OUT or Merged with N conflict(s): OUT on stderr. |
Merge without -o | The merged file's content on stdout. |
| Error | diffscope: error: <message> on stderr. |
Merged output keeps the encoding and line endings of the inputs. The output file is written through a temporary file, so a failed run never leaves a half-written result.
Exit codes
| Code | Diff | Merge |
|---|---|---|
| 0 | Identical (or the only differences are ignored by your options) | Merged cleanly |
| 1 | Different | Conflicts left; the file is written with markers |
| 2 | Error: a path is missing, a folder paired with a file, unreadable input | Error; nothing is written |
In the window, a merge exits with 0 only when it was saved with no conflicts left, otherwise 1. A two-way compare window exits with 0 when closed, or 2 if the comparison could not be opened. See Closing and exit codes.
Invalid command lines fail fast
With --headless, a command line DiffScope cannot parse (an unknown option, a missing value, three paths without --merge) prints the error to stderr and exits with 2, so a CI job fails instead of waiting. Version 1.0.0 opened the error window instead; update to 1.0.1 or later.
Examples for scripts and CI
# Fail the build when generated files drift from what is committed
& "C:\Tools\DiffScope\DiffScope.exe" --headless -w expected\api.json generated\api.json | Out-File drift.diff
if ($LASTEXITCODE -eq 1) { Write-Error "api.json changed, see drift.diff"; exit 1 }
if ($LASTEXITCODE -ge 2) { Write-Error "comparison failed"; exit 2 }
# Compare two release folders by content, skipping build output
& "C:\Tools\DiffScope\DiffScope.exe" --headless --folder --exclude node_modules --exclude "*.pdb" release\2.3 release\2.4 | Out-File tree.txt
# Try a 3-way merge; keep the result only when it is clean
# (the pipe makes PowerShell wait for the GUI program and set $LASTEXITCODE)
& "C:\Tools\DiffScope\DiffScope.exe" --headless --merge --diff3 base.cs mine.cs theirs.cs -o merged.cs | Out-Null
switch ($LASTEXITCODE) {
0 { "merged cleanly" }
1 { "conflicts left in merged.cs" }
default { "merge failed" }
}
rem Unified diff with 5 lines of context, ignoring case and blank lines
"C:\Tools\DiffScope\DiffScope.exe" --headless -U5 -iB old.txt new.txt > changes.diff
echo Exit code %ERRORLEVEL%
# Paths starting with "-" go after --
"/c/Tools/DiffScope/DiffScope.exe" --headless -- -old.txt -new.txt | cat; echo "exit ${PIPESTATUS[0]}"
With cmd the console waits for the GUI program only inside a batch file or with start /wait. In an interactive prompt, use start /wait "" "C:\Tools\DiffScope\DiffScope.exe" … before reading %ERRORLEVEL%.
