mercurial diff + unxutil "patch" - mercurial

How do you make the mercurial "diff" command produce output that is compatible with the unix or unxutil patch command?
I need to create a patch file that I can send to a coworker who doesn't have Mercurial installed.
I've tried using hg diff -r 3:5 > patch1.diff and I get an error from the patch command when applying it. (hold on, I will post the error message as soon as I have a chance....)
OK, here is a test case that I've uploaded to bitbucket:
hg clone https://bitbucket.org/jason_s/test-patch-apply P2base
hg update -r 2 -R P2base
hg diff -r 2:4 -R P2base > p2base.patch
rm -r P2base/.hg
cd P2base
patch < ../p2base.patch
I get this on my Windows PC:
C:\tmp\hg\P2base>patch < ../p2base.patch
patching file bar.txt
Assertion failed: hunk, file ../patch-2.5.9-src/patch.c, line 354
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Never mind, this is a documented problem (with a REALLY POOR ERROR MESSAGE) that can be overcome. From http://gnuwin32.sourceforge.net/packages/patch.htm :
On MS-Windows, the patchfile must be a text file, i.e. CR-LF must be
used as line endings. A file with LF may give the error: "Assertion
failed, hunk, file patch.c, line 343," unless the option '--binary' is
given.
I used --binary and it worked fine.

Related

Why don't mercurial file sets work when adding files?

I'm trying to use mercurial file sets to add all the files in a directory tree, excluding very large files and any binary files. Cribbing from the mercurial documentation, this command should do it:
hg init
hg add 'set: size("<1M") and not binary()'
However this returns a status code of 0, and hasn't added anything to my new, empty repo. I've tried just 'set: not binary()' and that didn't work either.
The frustrating thing is that although I can google for mercurial file sets, and find lots of examples, I can't find anything to help troubleshoot when it doesn't work!
I don't have a .hgignore file, and it's a fresh empty repo. Mercurial 4.2.2.
The directory where I'm testing this has a couple of artificially created files for the purpose of testing. In my real use case, I inherit a multi-gigbyte tarball of assorted sources and binaries from a client, and I want to get all the sources into mercurial before I start hacking to fix their problems, hence the need to exclude the binaries and large files that otherwise choke mercurial.
Here's my little test script:
#!/bin/sh -ex
dd if=/dev/urandom of=binary_1k bs=1 count=1024
dd if=/dev/urandom of=binary_2M bs=1 count=2097152
echo "This. Is, a SMALL text file." > text_small
hexdump binary_1k > text_1k
hexdump binary_2M > text_2M
ls -lh
file binary_1k
file binary_2M
file text_1k
file text_2M
hg init
hg add 'set: size("<1M") and not binary()'
hg status -a
hg add 'set: not binary()'
hg status -a
hg add 'set: size("<1M")'
hg status -a
At the end of this, each status command reports no files in the repo, and the add commands report no errors.
The problem is that file sets do a query of Mercurial's repository data base, which knows only about files that are part of the repository or have been added.
One solution is to add all, and then to get rid of the files that you don't like, e.g.:
hg forget 'set:size(">1M") or binary()'
This works, because the query also requires recently added files, even if they haven't been committed yet.

Get rid of "nameless" node in mercurial repository

I found a nameless node in my mercurial repository.
On executing the tag listing command "hg tags" as part of the generated output, I find the same node mentioned twice.
The output of hg tags command contains the following duplicate nodes:
xyz_release_tag daa262c10
daa262c10
In one of the entries, the node has a name but the other entry the node does not have a name.
I am in the process of migrating the mercurial repository to git and I am using fast-export to do the conversion.
The presence of this "nameless" node causes errors during the conversion process. Similar issue has been discussed at: https://github.com/frej/fast-export/issues/1.
As a quick workaround, I made a quick change to my local repository cache file. There is a file by name "tags2-visible" that gets created after I run the hg tags command for listing. Once I modify this file to remove the entry for the nameless node, it disappears and the conversion process succeeds.
I am not very sure if this is the right way to do it or if at all there is any other way.
Any thoughts ?
Resulting quickfix:
hg tags # Creates .hg/cache/tags2-visible
# Fix the nameless tag
sed -rie 's/^([^ ]+) $/\1 \1/' .hg/cache/tags2-visible
How I came to the solution:
$ hg tags | tail -3
PRODUCION_18032010 216:3e0a6415bbde
166:809065c08005
PRODUCION 125:d98f65c06bac
$ # Where is the problem?
$ grep -r 809065c08005
.hg/cache/tags2-visible:809065c08005ef2d261f10f72f17ea5fcd1e7540
$ # Add " test" to the end of this line
$ sed -i .hg/cache/tags2-visible -e 's/809065c08005ef2d261f10f72f17ea5fcd1e7540/809065c08005ef2d261f10f72f17ea5fcd1e7540 test/'
$ # Checking the edition
$ grep -r 809065c08005
.hg/cache/tags2-visible:809065c08005ef2d261f10f72f17ea5fcd1e7540 test
$ # Checking the validity of the hack
$ hg tags | tail -3
PRODUCION_18032010 216:3e0a6415bbde
test 166:809065c08005
PRODUCION 125:d98f65c06bac
After editing .hg/cache/tags2-visible adding a label to the branch fast-export worked for me.
Anyone see any problem in editing .hg/cache/tags2-visible in this way?

How to find who edited a line in hg

I'm definitely missing something about how to use hg blame.
I have a particular line in a file Foo.csproj that is suspicious and I want to see who modified it. According to other answers this should be a matter of hg blame Foo.csproj, maybe hg blame -unl Foo.csproj.
Either one of these returns to me
abort: Foo.csproj: no such file in rev xxxxx
I've tried with fully qualified paths and not. What's going on? Am I using the feature wrong? What is it meant for? How do I find out what I want to find out (the last person to modify line 1700 of that file).
Note, that while I'm interested in how this is done in Sourcetree, and TortoiseHg, and I'm sure others might be interested as well, I specifically want to know how to do this with the command line client.
Blame works exactly like you'd expect and your sample commands are correct, so I suspect you're running into something tricky. Here's an example of the normal case:
ry4an#four:~$ hg init GeorgeMauer
ry4an#four:~$ cd GeorgeMauer/
ry4an#four:~/GeorgeMauer$ echo test > afile.txt
ry4an#four:~/GeorgeMauer$ hg commit -Am first --user George
adding afile.txt
ry4an#four:~/GeorgeMauer$ echo more test >> afile.txt
ry4an#four:~/GeorgeMauer$ hg commit -m second --user Other
ry4an#four:~/GeorgeMauer$ hg blame afile.txt
0: test
1: more test
ry4an#four:~/GeorgeMauer$ hg blame -u afile.txt
George: test
Other: more test
ry4an#four:~/GeorgeMauer$
Is it possible that you're running afoul of the hideous "case-insensitive, but case-retentive" properties of Windows (and Mac) default file systems?
Try hg manifest to make sure the case of the filename you're providing is what's recorded in the repo, which may be different from the file you have on disk. For the example above mine looks like:
ry4an#four:~/GeorgeMauer$ hg manifest
afile.txt
If yours includes, for example, foo.csproj then that's how you have to ask about it.
The error message you're getting is the one you see when you ask about a file that's not in your repository:
ry4an#four:~/GeorgeMauer$ hg blame filedoesnotexist
abort: filedoesnotexist: no such file in rev 72a94e6fe429
So either it was never added and committed or, more likely, you're calling it by its wrong name.

Error when splitting a mercurial repository

I have a mercurial repository hosted on bitbucket containing several folders. My goal was to split each of these folder into a separate repository. After trying a few things suggested on stackoverflow, which failed, my last throw of the dice was to replicate a mock example in the bitbucket tutorial
Even though I followed the instructions to the letter, this also failed:
hg convert -s hg -d hg --filemap mymapfile hgsplitpractice hgfreshrepo
initializing destination hgfreshrepo repository
hgsplitpractice is not a local Mercurial repository
abort: hgsplitpractice: missing or unsupported repository
This is the same error that appeared in my previous attempts to split my actual repo.
The questions are:
1. why is this failing?
2. is there any other way to split these repositories?
I was getting the same error as you did.
In my case, the problem was something really silly: I was referring to both repositories by their names instead of specifying their full path.
I hope it helps someone else.
This was failing:
hg convert -s hg -d hg --filemap mymapfile "My-old-repo" "New-repo"
This worked like a charm:
hg convert -s hg -d hg --filemap mymapfile "d:/allrepos/My-old-repo" "d:/allrepos/New-repo"
You can try to use the convert extension.
After the command:
--filemap
you can use:
exclude path/that/you/want/to/split
rename path/that/you/want/to/split .
See this thread for more: Can I split a Mercurial repository?

Convert cvs to mercurial

I'm trying to convert a CVS repository to mercurial but can't get it to work.
I start with a clean checkout:
cvs -d :sspi;username=xxx;hostname=yyy.local:/cvsrepos checkout repo
Which works fine
I then do:
hg convert .
But it fails with:
assuming destination .-hg
initializing destination .-hg repository
connecting to :sspi;username=xxx;hostname=yyy.local:/cvsrepos
abort: unexpected response from CVS server (expected "Valid-requests", but got 'E cvs [server aborted]: Root :sspi;username=xxx;hostname=yyy.local:/cvsrepos must be an absolute pathname\n')
I'm running cvsnt on windows 7
Edit:
Investigated this a bit more and it seems like mercurial starts a local server cvs server and then communicates with that instance instead of the remote server.
I base this on the following observations:
I created a cvs.bat file that sends the command line arguments to a file. The file shows the argument "server".
process monitor shows that hg.exe tries to open the file
C:\cvstest\:sspi;username=xxx;hostname=yyy.local:\cvsrepos which of course fails.
Can it be that hg does not understand the sspi connection string?
Edit 2:
Not a solution but I found a workaround: Copy the complete remote repository to my machine and:
cvs -d :local:\localcopyofrepo checkout repo
hg convert repo
Everything worked fine
Looks like the error message is telling you to use an absolute pathname to the repository, try using
hg convert <full_path_including_drive>
rather than the . path on a checked out sandbox of your CVS repository. You could also try specifying the repository type in the convert command by adding -s cvs to the command, the result would look something like this:
hg convert -s cvs C:\sandbox\cvsrepos
It looks like you are using ConvertExtension. Can you try hg convert from the parent folder and specify the folder name, instead of . and see if it works?