If I mark a "missing" file (indicated by a !) for remove, (for example this can be done by accidentally finding the wrong rename), how do I unmark it, and get it to be "missing" again? I find that the file becomes stuck at R state, and then hg rename will give a message like not copying - file has been marked for remove. There are various commands like remove which will mark a file to take some action on the next commit, but is there a way to clear this flag and return the file back to the unmarked state?
Usually if you have sth. like this
! foo.txt
One possible solution:
hg revert foo.txt
Or you can update only the file to latest revision without a conflict like
hg update -r <rev-id> foo.txt
Usually
hg log
should give enough information to perform this step
If you want any further help, please post output of
hg status && hg log
I have a repos which I'm about to split in two (using hg convert). I'd like to take the opportunity to get rid of (exclude) unnecessary directories. However, in some cases, I moved files around using hg cp and so forth, so seemingly unused directories may have old history assocated with them, and in some cases I have verified they do. (In most cases this is very old history (from around 2004/2005). I do this much less now). Is there a way I can check a particular directory does not share history with the current tip? By this I mean that for a directory foo:
hg log -vf filename
for all filename in tip does not mention any files in foo.
I think that is a sufficient criteria.
EDIT: I belatedly realized that the above question is wrong. In my case most of these original directories are still in tip, so what I said above won't work. Instead, say DIR_1, DIR_2, ..., DIR_k is directories which are currently (in tip) no longer relevant. I want to make sure they never were relevant. In other words, consider all files not in any of DIR_1, DIR_2, ..., DIR_k. Then check that their ancestors doesn't include a changeset in any of these DIR. If it does, then I guess you need to exclude that directory from the list of non-relevant directories, and try again.
EDIT2: Ok, let's break this down a bit. Can someone tell me what the expression for the set of all csets which touch files in a specific directory DIR is? The following seems close, but I'm not sure how to interpret the expression **.*.
hg log -vr "file('c++/**.*')"
Try for directory DIR such revset
hg log -r "ancestors(tip) and file('DIR/**.*')"
Any output means "Found in history"
I finally settled on the following script.
Brief description: The basic idea is to find directories which aren't part of the history of the files in the tip. So, this script takes all files in the tip and removes those from the chosen set of directories. Then it does hg log -vf for each of those files, and checks whether any of the files in that log match the files in that set of directories. If they don't, then those directories can be safely deleted.
I am sure this script could be improved - my shell scripting is quite dodgy. Suggestions for improvement appreciated.
#!/bin/sh
hg locate "set:not lisp/** and not boost/** and not trunk/** and not 'c_api_ex/**' and not 'c++-strategy/**' and not parallel/** and not poster/** and not sim/**" > file.txt
while read f; do
filelist=$(hg log -vf $f --template "{files % ' {file}\n'}")
one_file_per_line=""
for file in $filelist
do
one_file_per_line="${one_file_per_line}""\n""${file}"
done
filematches=$(echo -e $one_file_per_line | sort -u | egrep 'lisp/|boost/|trunk/|c_api_ex/|c++-strategy/|parallel/|poster/|sim/')
if [ -n "${filematches}" ]; then
echo file $f has the following files as ancestors in one or more of lisp, boost, trunk, c_api_ex, c++-strategy, parallel, poster, sim directories: $filematches
fi
done < file.txt
I had two very large projects in my Mercurial repository.
I am in the process of refactoring both of them into smaller sub-projects.
That involves moving sets of sources from a parent project directory into a sub-project's sub-directory.
For most files, I simply moved them.
For some files, I also had to make changes.
Before I commit my refactoring changes, I would like to review any edits that I made to any source files. In the GUI tool SourceTree - it shows me any modifications (in addition to indicating that the file has been moved/renamed). Is there any way to determine what files have also been modified from the Mercurial command line?
Here is a specific example of what I am talking about:
iphonedev:EveryScape cdoucette$ hg status -C Engineering/iOS/ESSDK/src/ESSDK-Miscellaneous/ESDataManagerInMemory.m
A Engineering/iOS/ESSDK/src/ESSDK-Miscellaneous/ESDataManagerInMemory.m
Engineering/iOS/ESSDK/src/ESDataManagerInMemory.m
How can I compare the old revision with the current working copy in a different location?
If I just do this:
hg diff Engineering/iOS/ESSDK/src/ESSDK-Miscellaneous/ESDataManagerInMemory.m
It shows me the entire contents of the file (since technically it was added in its new location).
Instead, I want to diff between:
Engineering/iOS/ESSDK/src/ESDataManagerInMemory.m (repository copy - previous revision)
Engineering/iOS/ESSDK/src/ESSDK-Miscellaneous/ESDataManagerInMemory.m (working copy)
I did search for similar questions. This post was close - but appears to only make sense if I went ahead and committed my changes. Instead, I would like to find and review my changes before committing.
Mercurial diff not working after move/rename
I would script it up like this:
hg cat -r <oldrev> <oldfilename> > oldfile.oldrev
diff <newfilename> oldfile.oldrev
I need to extract a list of changed files from Mercurial from the last "revision" tag to the current working version instead of the head. The process is part of a batch script, so the current revision bit needs to be automated.
I know that I can get the current revision using:
hg id -n
or
hg parent --template "{rev}\n"
I also know that I can get a list of changed files from a tagged version ("from") like this:
hg st --rev from > file_list.txt
I also know that I can get a list of changed files from a tagged version ("from") to another tagged version ("to") like this:
hg st --rev from --rev to > file_list.txt
However, is there a tag or a way that one can specify the "to" version to be the current working version automatically? I need to be able to exclude the "tip" or "default" files.
This process happens in a DOS batch file, if that helps, and the results are all output to text files.
Sorry - I got confused about which files actually had changed... The answer is as simple as:
hg st --rev from > file_list.txt
That will list all files that have changed from the named revision to the current working version and NOT the head revision (tip or default).
I have a personal Mercurial repository tracking some changes I am working on. I'd like to share these changes with a collaborator, however they don't have/can't get Mercurial, so I need to send the entire file set and the collaborator will merge on their end. I am looking for a way to extract the "tip" version of the subset of files that were modified between two revision numbers. Is there a way to easily do this in Mercurial?
Adding a bounty - This is still a pain for us. We often work with internal "customers" who take our source code releases as a .zip, and testing a small fix is easier to distribute as a .zip overlay than as a patch (since we often don't know the state of their files).
The best case scenario is to put the proper pressure on these folks to get Mercurial, but barring that, a patch is probably better than a zipped set of files, since the patch will track deletes and renames. If you still want a zip file, I've written a short script that makes a zip file:
import os, subprocess, sys
from zipfile import ZipFile, ZIP_DEFLATED
def main(revfrom, revto, destination, *args):
root, err = getoutput("hg root")
if "no Merurial repository" in err:
print "This script must be run from within an Hg repository"
return
root = root.strip()
filelist, _ = getoutput("hg status --rev %s:%s" % (revfrom, revto))
paths = []
for line in filelist.split('\n'):
try:
(status, path) = line.split(' ', 1)
except ValueError:
continue
if status != 'D':
paths.append(path)
if len(paths) < 1:
print "No changed files could be found."
return
z = ZipFile(destination, "w", ZIP_DEFLATED)
os.chdir(root)
for path in paths:
z.write(path)
z.close()
print "Done."
def getoutput(cmd):
p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return p.communicate()
if __name__ == '__main__':
main(*sys.argv[1:])
The usage would be nameofscript.py fromrevision torevision destination. E.g., nameofscript.py 45 51 c:\updates.zip
Sorry about the poor command line interface, but hey the script only took 25 minutes to write.
Note: this should be run from a working directory within a repository.
Well. hg export $base:tip > patch.diff will produce a standard patch file, readable by most tools around.
In particular, the GNU patch command can apply the whole patch against the previous files. Isn't it enough? I dont see why you would need the set of files: to me, applying a patch seems easier than extracting files from a zip and copying them to the right place. Plus, if your collaborator has local changes, you will overwrite them. You're not using a Version Control tool to bluntly force the other person to merge manually the changes, right? Let patch deal with that, honestly :)
In UNIX this can be done with:
hg status --rev 1 --rev 2 -m -a -n | xargs zip changes.zip
I also contributed an extension, see the hgexportfiles extension on bitbucket for more info. The export files extension works on a given revision or revision range and creates the set of changed files in a specified directory. It's easy to zip the directory as part of a script.
To my knowledge, there's not a handy tool for this (though a mercurial plugin might be doable). You can export a patch for the fileset, using hg export from:to (where from and to identify revisions.) If you really need the entire files as seen on tip, you could probably hack something together based on the output of hg diff --stat -r from:to , which outputs a list of files with annotations about how many lines were changed, like:
...
src/test/scala/RegressionTest.scala | 25 +++++++++++++----------
src/test/scala/SLDTest.scala | 2 +-
15 files changed, 111 insertions(+), 143 deletions(-)
If none of your files have spaces or special characters in their names, you could use something like:
hg diff -r156:159 --stat | head - --lines=-1 | sed 's!|.*$!!' | xargs zip ../diffed.zip
I'll leave dealing with special characters as an exercise for the reader ;)
Here is a small and ugly bash script that will do the job, at least if you work in an Linux environment. This has absolutely no checks what so ever and will most likely break when you have moved a file but it is a start.
Command:
zipChanges.sh REVISION REPOSITORY DESTINATION
zipChanges.sh 3 /home/hg/repo /home/hg/files.tgz
Code:
#!/bin/sh
REV=$1
SRC_REPO=$2
DST_ZIP=$3
cd $SRC_REPO
FILES=$(hg status --rev $1 $SRC_REPO | cut -c3-)
IFS=$'\n'
FILENAMES=""
for line in ${FILES}
do
FILENAMES=$FILENAMES" \""$SRC_REPO"/"$line"\""
done
CMD="tar czf \"$DST_ZIP\" $FILENAMES"
eval $CMD
I know you already have a few answers to this one but a friend of mine had a similar issue and I created a simple program in VB.Net to do this for him perhaps it could help for you too, the prog and a copy of the source is at the bottom of the article linked below.
http://www.simianenterprises.co.uk/blog/mercurial-export-changed-files-80.html
Although this does not let you pick an end revision at the moment, it would be very easy to add that in using the source, however you would have to update to the target revision manually before extracting the files.
If needed you could even mod it to create the zip instead of a folder of files (which is also nice and easy to manually zip)
hope this helps either you or anyone else who wants this functionality.
i just contributed an extension here https://sites.google.com/site/alessandronegrin/pack-mercurial-extension
I ran into this problem recently. My solution:
hg update null
hg debugsetparents (starting revision)
hg update (ending revision)
This will have the effect of deleting all tracked files that were not changed between those two revisions. You will have to remove any untracked files yourself, though. After doing this, the local branch will be in an inconsistent state; you can fix this by running hg debugrebuildstate (or simply deleting the local branch, if you no longer need it).