Scenario: I've "inherited" a program, kept under Mercurial, that only works on my system with specific tweaks to certain files that are checked in. I do not want to check these tweaks in.
My most recent solution to this is to create a mercurial patch file (hg diff > patchfile) containing these tweaks; when I need to check in my changes, I'll just reverse-apply the patch, commit, and re-apply the patch. (If I had full control of the source, I'd just move all these little tweaks to a single configuration file that isn't under version control, putting a "sample" config file under version control)
Unfortunately, it seems that while the GNU patch
command supports the --reverse
flag, it does not support hg's multi-file diff format as a single patch file (or maybe it does, and I just don't know the switches for it?). OTOH, hg has its own patch
command that can apply the diff, but that doesn't support any kind of reverse
flag.
So my question is twofold:
Reverse a Patch that is Already Applied (Undo a Patch) You can use the -R option to reverse a patch which is applied already. You can notice from the filesize, that the patch, which is applied already is reversed when we used the -R option.
There is only one level of rollback, and there is no way to undo a rollback. It will also restore the dirstate at the time of the last transaction, losing any dirstate changes since that time. This command does not alter the working directory.
Mercurial's patch
command (really import
) doesn't support reverse, but hg diff
does. Use --reverse
on that and you'll have a reversed patch that Mercurial can apply.
However, what you're describing is a very common vendor-branch style workflow, which mercurial can better support using features other than diff and patch.
Specfically, Mercurial Queues does exactly what you want.
I found --reverse approach did not work when you have sub repos. i.e.
hg diff --reverse -S
. In case it helps anyone, this barely tested script seems to do the job:
#!/bin/bash
DIRS="$*"
if [[ $DIRS = "" ]]; then
DIRS=$(echo *)
fi
for arg in $DIRS; do
arg=$(echo $arg | sed 's/^\.\/*//g')
repo=$(echo $arg | cut -d'/' -f-1)
grep -q "^$repo = " .hgsub 2>/dev/null
if [ $? -eq 0 ]; then
if [ -d $repo ]; then
cd $repo
hg diff --reverse | sed -e "s;--- a;--- a/$repo;g" -e "s;+++ b;--- b/$repo;g"
cd ..
else
echo Error, unknown repo $repo
fi
else
hg diff $arg --reverse
fi
done
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With