Sublime Forum

Reverse Hunk Workaround

#1

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:

  1. install patchutils (https://github.com/twaugh/patchutils)

    • macOS: brew install patchutils
    • linux: sudo apt-get install patchutils
    • windows: ??
  2. 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'
  1. 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

2 Likes