Having used SourceTree in the past and using Reverse Hunk
many times, it’s always been a hassle to accomplish this in Sublime Merge. I finally decided to set out and find a workaround.
Notes/Caveats:
- if an error occurs on first usage about a missing command fully qualify both instances of
filterdiff
in step 2 below - for best results, only right click on any red or green line when using
Reverse Hunk
- there is no way to disable the menu item, so there are 2 safe guards:
- commit hash validation (prevents invalid staged/unstaged usages)
- line number validation (prevents right-clicking too far away from actual changes)
- if anything changes in regards to line numbers between left/right side diffs, this workaround may break
How to install:
-
install patchutils (https://github.com/twaugh/patchutils)
- macOS:
brew install patchutils
- linux:
sudo apt-get install patchutils
- windows: ??
- macOS:
-
add this git alias:
git config --global alias.smreversehunk '!f() {
if [ "1" = "$(git rev-parse --quiet --verify "$2~^{commit}" > /dev/null; echo $?)" ]; then
echo "Cannot reverse hunk due to an unknown commit ($2)" >&2
return 1
fi
local hunk_num="$(git diff --unified=4 "$2..$2~" "$1" | filterdiff --as-numbered-lines=before | awk "/^\.\.\.$/ {count++}; /^$3/ {print count+1}")"
if [ "" = "$hunk_num" ]; then
echo "Cannot reverse hunk due to an unmatched line number ($3)" >&2
return 2
fi
git diff --unified=4 "$2..$2~" "$1" | filterdiff --hunks=$hunk_num | git apply
}; f'
- add this menu item to
Diff Context.sublime-menu
:
[
{
"caption": "Reverse Hunk (mouse location)",
"command": "git",
"args": {"argv": ["smreversehunk", "$path", "$commit", "$line"]},
"context": [ { "key": "control", "operand": "commit_table" } ]
}
]
see also: https://github.com/sublimehq/sublime_merge/issues/7