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:
- How should this be done in mercurial? Surely hanging on to a "tweak patch" isn't 开发者_如何学Pythonthe only way to handle this situation. Maybe mercurial has a plugin or something built in for such temporary, uncommittable changes.
- Aside from how things should be done, is there any way to reverse-apply such a mercurial diff-patch to a mercurial repo like this? There are other situations where such functionality would be useful.
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
精彩评论