Anyway to automatically merge or concatenate hgtags (Mercurial)?
We are trying to run a chron job that automatically converts seperate CVS modules to mercurial modules and finally, consolidate those converted mercurial modules to in a single mercurial repo.
I've been trying to find ways to automatically merge .hgtags (from the converted hg repos) without having a user window prompt (thus usage in a chron job).
Is there a way to tell mercurial when using hg merge to just to take the local file and appen开发者_运维问答d it to the incoming file?
thanks for any info or any suggestions
Yes, you can setup a merge tool like Krtek describes. I just tried it out and this works:
[merge-tools]
merge-tags.executable = cat
merge-tags.args = $local $other | sort -u >> $output
[merge-patterns]
.hgtags = merge-tags
Put that in your .hg/hgrc
file on the server and future merges will just append the tags. What happens is that hg merge
will execute
cat /tmp/hgtags.local /tmp/hgtags.other | sort -u >> .hgtags
where the first argument to cat
is the local version of the .hgtags
file, and the second argument is the version you are merging with.
I sort and make the output unique in order to avoid duplicating lines that are common in the two files. As long as you only add tags, this will work fine -- but if you also delete tags, then the order of lines in the .hgtags
file matters and so you cannot just sort it like this. Please see my extended answer for handling this situation.
This is my test session. I start by making a repository with two heads:
$ hg init
$ echo a > a.txt
$ hg add a.txt
$ hg commit -m a
$ echo b > b.txt
$ hg add b.txt
$ hg commit -m b
$ hg tag b
$ hg update 0
0 files updated, 0 files merged, 2 files removed, 0 files unresolved
$ echo c > c.txt
$ hg add c.txt
$ hg commit -m c
created new head
$ hg tag c
The branches are visible in the output from the graphlog extension:
@ changeset: 4:54c5397a23a4
| tag: tip
| user: Martin Geisler <mg@aragost.com>
| date: Wed Mar 02 11:45:20 2011 +0100
| summary: Added tag c for changeset aff5fe9be7d9
|
o changeset: 3:aff5fe9be7d9
| tag: c
| parent: 0:0db5fae8b6cc
| user: Martin Geisler <mg@aragost.com>
| date: Wed Mar 02 11:45:17 2011 +0100
| summary: c
|
| o changeset: 2:a9af8514a64e
| | user: Martin Geisler <mg@aragost.com>
| | date: Wed Mar 02 11:45:02 2011 +0100
| | summary: Added tag b for changeset 0518533f37f6
| |
| o changeset: 1:0518533f37f6
|/ tag: b
| user: Martin Geisler <mg@aragost.com>
| date: Wed Mar 02 11:44:44 2011 +0100
| summary: b
|
o changeset: 0:0db5fae8b6cc
user: Martin Geisler <mg@aragost.com>
date: Wed Mar 02 11:44:33 2011 +0100
summary: a
There is a conflict in the .hgtags
file:
$ hg cat -r 2 .hgtags
0518533f37f6f37edbea5b46d9af2192f69ddecd b
$ hg cat -r 4 .hgtags
aff5fe9be7d9b021e55dfb522b29fd03cbcf5cb7 c
but the merge is still non-interactive:
$ hg merge
merging .hgtags
1 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
You can see how the files were appended:
$ cat .hgtags
aff5fe9be7d9b021e55dfb522b29fd03cbcf5cb7 c
0518533f37f6f37edbea5b46d9af2192f69ddecd b
sort -mu
gave me what i want. This command do not sorts, but removes duplicates.
sort -u
breaking time order.
The window prompt will only happen if you have a conflict in your .hgtags file, which should be pretty rare. However, here's maybe an idea that will work.
Mercurial let you use a different merge tool than the internal one, for more information, see MergeToolConfiguration. You can also change the mergetool via the command line with the --tool
option (see hg merge --help
).
Maybe you can write some little program to serve as a special merge tool for .hgtags which do exactly what you want, ie append the local file to the incoming file. You can then modify your hgrc to use this new tool when merging .hgtags.
I never tried this solution, it's just an idea, but maybe it will help you.
Here's a simple merge tool in python. It also tries to maintain the existing order of lines in .hgtags file.
Same caveats apply as in Martin's answer.
import sys
from heapq import merge
local = sys.argv[1]
other = sys.argv[2]
output = sys.argv[3]
merged_tags = merge(file(local).readlines(), file(other).readlines())
unique_tags = []
for tag in merged_tags:
if tag not in unique_tags:
unique_tags.append(tag)
file(output, 'w').writelines(unique_tags)
The suggestion in https://stackoverflow.com/a/9783478/1183010:
hgtags.merge.template: changeset = "{tags}" tag = "{node} {tag}\n"
[merge-tools] hgtags.executable = hg hgtags.args = log -r "tagged()" --style hgtags.merge.template > $output hgtags.premerge = False
[merge-patterns] .hgtags = hgtags
works for us.
精彩评论