I've got a web application I want to be able to create patches for. Specifically I want to create patches for enabling specific functionality in the web server.
JAVA_OPTS="-Xms128m -Xmx256m $JAVA_OPTS -Djava.awt.headless=true -Datlassian.standalone=JIRA -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true "
# Perm Gen size needs to be increased if encountering OutOfMemoryError: PermGen problems. Specifying PermGen size is not valid on IBM JDKs
PRGDIR=`dirname $0`
JIRA_MAX_PERM_SIZE=128m
if [ -f "${PRGDIR}/permgen.sh" ]; then
echo "Detecting JVM PermGen support..."
. ${PRGDIR}/permgen.sh
if [ $JAVA_PERMGEN_SUPPORTED = "true" ]; then
echo "PermGen switch is supported. Setting to ${JIRA_MAX_PERM_SIZE}"
JAVA_OPTS="-XX:MaxPermSize=${JIRA_MAX_PERM_SIZE} ${JAVA_OPTS}"
else
echo "PermGen switch is NOT supported and will NOT be set automatically."
fi
fi
# use this if you want to import data without notifications
#JAVA_OPTS=" -Datlassian.mail.senddisabled=true -Datlassian.mail.fetchdisabled=true -Datlassian.mail.popdisabled=true $JAVA_OPTS "
export JAVA_OPTS
echo "If you encounter issues starting up JIRA Standalone Edition, please see the Troubleshooting guide at http://confluence.atlassian.com/display/JIRA/Installation+Troubleshooting+Guide"
What I want to do is save a patch for each individual modification I need to make to this file in such a way that the patches can be applied individually (using qpush -move) or all together (qpush -a)
I first tried the following with a clean version of the file:
hg qnew jmx.patch
Then I modified the first line of the file to include the following
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8089 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
then refreshed the patch
hg qrefresh
The popped the patch to begin work on the second modification from the clean base
hg qpop
hg qnew jelly.patch
The I modified the first line of the file to include the following
-Djira.jelly.on=true
then refreshed the patch
When I then tried to qpush the older patch, it failed to apply.
Then I tried an alternate approach, which was to first create a base patch:
hg qpop -a
hg qnew base.patch
,that added the following to the file
JMX_OPTS=
JELLY_OPTS=
JAVA_OPTS=" ${JAVA_OPTS} ${JELLY_OPTS} ${JMX_OPTS} "
,then refresh base.patch
hg qrefresh
Then create a new patch for jmx while base.patch was still applied:
hg qnew jmx.new
edit the file as follows:
JMX_OPTS=" -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8089 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false "
refresh the patch and pop :
hg qrefresh
hg qpop
Create new patch for jelly:
hg qnew jelly.patch
Edited the file as follows:
JELLY_OPTS=" -Djira.jelly.on=true "
refreshed the patch:
hg qrefresh
But again, when I tried to qpush the jmx.patch on top of the newly created jelly.patch, there was conflicts.
I thinking Mercurial is behaving as expected, but I'm wondering if I can structure the patches I'm making differently so they can apply individually or combined without rejection
Your second approach will work if you insert at least 3 empty lines between the lines you want to change.
And you could also shuffle your queue (after qpop!), apply jmx first, then jelly. You'll get "offset x lines" but the file will be correctly patched.
MQ has a hardcoded fuzz number 3 (see patchfile() in patch.py). When you have your JMX_OPTS and JELLY_OPTS in adjacent lines, MQ can't find the context in jmx.patch because it's changed in jelly.patch.
Related
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.
Mercurial Queues is about patches, and patches know nothing about file renames. Is this the reason why Mercurial Queues don't support file renames, or am I doing something wrong renaming the file? I have worked on a patch queue modifying just one file called foo. Now I go back to patch 4 and rename the file via hg mv:
hg qpop 4 # Unapply all patches until patch 4.
hg mv foo bar # Rename file and led Mercuial know about it.
hg qrefresh # Should apply changes to unapplied patch 4.
hg qpush -a # Should apply all unapplied patches.
I get the following error:
unable to find 'foo' for patching
1 out of 1 hunks FAILED -- saving rejects to file foo.rej
patch failed, unable to continue (try -v)
patch failed, rejects left in working dir
errors during apply, please fix and refresh 5.diff
So how should I do to handle file renames with Mercurial Queues? Mercurial commits handle file renames for a reason (as without, it would lose the whole history about the editing of the file after renaming).
Update
Just noticed that hg histedit folding changesets and hg collapse also lose the information of file renaming, the file shows up as a new one instead of a renamed one, and I guess this is for the same reason. Seems like collapsing private changesets is not possible in Mercurial without loosing that information?
Update 2
Found out collapsing private changesets without loosing rename information is possible with hg rebase and its --collapse option, e.g. hg rebase -s 5 -d 4 --collapse. The issue that the other commands should sostain rename information is still vacant, but using the hg rebase command there is at least a way to achieve the desired result.
Is this the reason why Mercurial Queues don't support file renames,
no.
or am I doing something wrong renaming the file?
no.
Yes, patches in chain will have troubles, if they was prepared for foo file, but later in will be bar, but due to different reasons: patches are independent, and every and each patch know nothing about changes in others - they work with context, not with sequence of operations in separate patches. You done rename correctly, but this changeset invalidates later changesets, prepared on old content
A little while ago I noticed that hg started creating unversioned copies of files in the repository at seemingly random times when I update between branches. I can't for the life of me think of what I might have changed for this to start happening. There is nothing in the verbose or trace output to indicate that these files are being created.
The new unversioned filenames all end with what seems to be a random string added to the end of the extension:
file1.txt-23121dd1
someotherfile.sql-bc769bd2
bizarrofile.cs-40a93ed0
hgisinvadingurhead.ppt-f8e9015a
When trying to determine the pattern of this happening I've noticed the following:
The added characters in the filenames do not correspond with any changeset ID in the repository. I have done a grep -i to the output of hg history and the string in the filename does not appear anywhere in the output.
In all cases the files existed in the branch I was working on but do not exist in the branch I update to.
Sometimes it's only one or two files, sometimes it's several.
It is never the case that these are all of the files that exist in one branch but not the other.
It is never the case that it is the same set of unversioned files between updates.
Others on my team who are cloning the same repositories do not seem to be experiencing this
I thought maybe it was something within the repository but it also happens in other existing repositories and in brand new ones as well.
For example, I have done this (hg output omitted except for hg status output at the end, but no errors come from the output):
c:\> mkdir repo
c:\> cd repo
c:\repo\> hg init
c:\repo\> echo default > default.txt
c:\repo\> hg add
c:\repo\> hg commit -m "Commit default"
c:\repo\> hg branch branch1
c:\repo\> echo branch1 > branch1.txt
c:\repo\> hg add
c:\repo\> hg commit -m "Commit branch1"
c:\repo\> hg update default
c:\repo\> hg status
? branch1.txt-23121dd1
This is not repeatable every time. I could repeat these steps and sometimes the unversioned file will be there at the end and sometimes it won't. It's very sporadic. In larger repositories, though, I almost always see at least one unversioned file between branch updates.
Full output of hg update default follows. The output always displays as such whether or not the unversioned file is created.
resolving manifests
calling hook preupdate.eol: <function preupdate at 0x0000000002571668>
removing branch1.txt
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
I was using an older version of hg when I first noticed it but the problem still exists after updating to 2.3.2. I am using Windows 7 Pro x64 with TortoiseHG 2.5.1 x64. I don't think it's related to Tortoise, however, because I can replicate the problem by just using hg from the command line.
The contents of my mercurial.ini file are:
[ui]
username=myname <myname#mydomain.com>
ignore=C:\users\myusername\.hgignore
verbose=true
trace=true
[eol]
native = CRLF
only-consistent = False
[extensions]
purge =
eol =
I can live with it, but it's a pain to make sure I'm not accidentally adding these files to the repository in changesets with other new files.
If someone has seen this and could point me to the culprit I'd be most appreciative!
If a file is in use when updating between changesets, the in-use file is renamed with the added numbers so the update can succeed.
Does disabling the eol extension help matters? I noticed that your test did not use a .hgeol file as well (that's one of the things associated with this extension). There's another thread hereabouts that is dedicated to some problems with this extension.
You can use qdiff to see the differences between the repository and the changes you've made in your patch queue thus far (even with qrefreshed changes). Is there a similar command for status, so that you can see all the files that are modified, even once you have qrefreshed the changes to those files?
This will show you changes in the currently applied patch:
$ hg status --change .
And this one will include changes also in your working dir:
$ hg status --rev .^
The process of creating patches in Mercurial is as follows:
Create patch with qnew -> Make changes -> Refresh patch
What if I have already made (uncommited) changes and I want to add them to the queue?
It depends on your version, and it looks like it changed in 1.5.1.
1.5.1 or later
The command will add any uncommitted changes by default
qnew creates a new patch on top of the currently-applied patch (if any).
The patch will be initialized with any outstanding changes in the working
directory.
earlier than 1.5.1
You want to use qnew -f. From the docs:
-f: Create a new patch if the contents of the working directory are modified. Any outstanding modifications are added to the newly created patch, so after this command completes, the working directory will no longer be modified.
Actually, the patch process works the same whether there are uncommitted changes or not. I always do it as follows:
[... make changes ...]
hg qnew -m "foo bar changes" foobar.patch
--> new empty patch at top of queue
hg qrefresh
--> this adds all diffs from 'hg diff' into the current top patch
EDIT: #CaseBash has correctly pointed out that I'm wrong about the current default behavior!