Situation
$ cat .hgignore
.hgignore
$ hg status
M file1
M file2
M src/project.xml
I don't want to track the project.xml so I run
echo "project.xml" >> .hgignore
and the result is
$ cat .hgignore
.hgignore
project.xml
$ hg status
M .hgignore
M file1
M file2
M src/project.xml
So the .hgignore is now as modified even though it shouldn't be tracked and nothing happend with the project.xml. What does this mean?
You wrote:
"M src/project.xml"
which means that src/project.xml is under version control.
A file already under version control cannot be ignored! The
.hgignore file is for ignoring files that are untracked (status
will show a "?").
You have two solutions to ignore your file:
You can either "hg forget" the file, the opposite of "hg add" (i.e.,
telling Mercurial not to track this file anymore), or
You can use the ”-X” option as a default for status/diff/commit
in your .hg/hgrc configuration file, e.g.,
[defaults]
status = -X <file>
diff = -X <file>
commit = -X <file>
which will tell hg not to include this file in the use of status, diff, and commit.
Related
1) How to get the list of files with their sizes of some commit through command line like this:
hg files --template "{name} {length}\n"
2) How to get the size of Mercurial through command line like this:
hg size my_directory
To my knowledge there's no straight forward way without any external utilities.
Make use of the appropriate OS utilities, answering both of your question at once (should work on *nix and OSX):
hg files -rXXX | xargs du -h
To report information about the size of a particular file as of a particular revision, you can use the pattern:
hg cat --rev REV FILE | wc -c
Generalizing this a bit, if REV is a specific revision of interest, we could obtain a listing of filenames and file sizes by writing:
hg files --rev $REV . |
while read -r f ; do
echo $f $(hg cat --rev $REV "$f" | wc -c)
done
I have to get list of changed, added or removed files since last commit.
command: hg status gives me for example
M file_path
C other_file_path
I need:
file_path
other_file_path
Solution have to work in Unix & Windows.
If you want to list all of the files, you can simply add -n to the hg status command:
$ hg status
M modded.txt
A added.txt
R removed.txt
? unknown.txt
$ hg status -n
modded.txt
added.txt
removed.txt
unknown.txt
However, this will also list unknown files (those that are new, but have not been specifically added to the repository with a hg add command). You can get around this by adding either -q (as Lazy Badger points out), or by using filesets (see hg help filesets) to specify all files that aren't unknown:
$ hg status -n -q
modded.txt
added.txt
removed.txt
$ hg status -n "set:!unknown()"
modded.txt
added.txt
removed.txt
You can specify which types of files are listed by combining the other options (-a -r for example will show added and removed files). Alternatively you can do clever things with filesets: for example, only listing the names of files that are removed by using "set:removed()"
working directory
Did a
hg commit (resulted in rev3)
Copied some directories inside ... changed some files. Did
hg add
hg commit (resulted in rev4 - tip)
How to get back exactly to the state of rev3. hg update 3 will change the files to the state they were in rev3, but it will also leave all the copied directories inside. I want to get the working directory without the copied directories and files, which were added after rev3.
That doesn't happen for me:
> hg init
> mkdir first
> jed first/foo.txt
> hg add
adding first/foo.txt
> hg commit -m asd
> mkdir second
> jed second/foo.txt
> hg add
adding second/foo.txt
> hg commit -m asd
> hg update 0
Now first exists, but second doesn't...
Are you sure you added everything in the new directories before your commit?
Like Jon writes, Mercurial will normally try to clean up after itself. So when you hg update you should get back exactly what you committed. What I guess you're seeing is the following behavior:
$ hg init repo
$ cd repo
$ echo "# some C program" > foo.c
$ hg add foo.c
$ hg commit -m first
$ mkdir dir
$ echo "$ other C program" > dir/bar.c
$ hg add dir/bar.c
$ hg commit -m second
$ echo "object file" > dir/bar.o
$ hg update 0
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ ls
foo.c dir
$ ls dir
bar.o
So the untracked dir/bar.o file has been left behind, but the tracked dir/bar.c file has been correctly removed. That is: Mercurial wont delete untracked files since it doesn't know if they contain valuable data. This applies even if the files are ignored by a pattern in .hgignore. If the directory had only contained the tracked dir/bar.c file, then the directory would have been completely removed when you update to a revision where it isn't needed.
The normal way to clean up untracked files is to use the purge extension.
I know that Mercurial can track renames of files, but how do I get it to show me renames instead of adds/removes when I do hg status? For instance, instead of:
A bin/extract-csv-column.pl
A bin/find-mirna-binding.pl
A bin/xls2csv-separate-sheets.pl
A lib/Text/CSV/Euclid.pm
R src/extract-csv-column.pl
R src/find-mirna-binding.pl
R src/modules/Text/CSV/Euclid.pm
R src/xls2csv-separate-sheets.pl
I want some indication that four files have been moved.
I think I read somewhere that the output is like this to preserve backward-compatibility with something-or-other, but I'm not worried about that.
There are several ways to do this.
Before you commit, you can use hg diff --git to show what was renamed:
$ hg diff --git
diff --git a/theTest.txt b/aTest.txt
rename from theTest.txt
rename to aTest.txt
Note that this only works if you used hg mv, hg rename, or mv and hg addremove --similarity 100.
After you commit, you can still use hg diff, but you'll have to specify the change using -r:
$ hg diff -r 0 -r 1 --git
diff --git a/test.txt b/theTest.txt
rename from test.txt
rename to theTest.txt
For both hg status and hg log, use the -C command-line flag to see the source that a file was copied from.
$ hg status -C
A aTest.txt
theTest.txt
R theTest.txt
The line just below aTest.txt indicates the source it was copied from (theTest.txt).
$ hg log -v -C
changeset: 1:4d7b42489d9f
tag: tip
user: jhurne
date: Tue Apr 20 20:57:07 2010 -0400
files: test.txt theTest.txt
copies: theTest.txt (test.txt)
description:
Renamed test.txt
You can see the files that were affected (test.txt and theTest.txt), and that "theTest.txt" was copied from test.txt.
You can find out how many files have been renamed with hg summary. If you want to see the actual files that were renamed, the fastest way I've found is to do:
hg st -a -C
This will output something like this:
A <path\to\renamed\file>
<path\copied\from>
A <path\to\added\file>
A <path\to\renamed\file>
<path\copied\from>
Since hg status considers a rename to be a copy and a remove, your renamed files will list a copied from file. Files that were added but not renamed will not list a copied from file.
Related to Mercurial: Merging one file between branches in one repo , I'm trying to perform a backout operation on a single file, even though that file was one of many participants in the revision being backed out.
HG being the changeset-oriented tool that it is, it doesn't want to operate on files.
Closest I could find was to use hg export to create a diff, hand-edit the diff, and then hg import to patch the file in reverse order.
..but then I hit this annoying situation where http://hgbook.red-bean.com/read/finding-and-fixing-mistakes.html claims that there is a --reverse option to hg patch when there is not.
So the closest thing I can think of is to generate a hand-edited patch as above, and then using vanilla patch -R to apply a reverse patch.
The hg backout command would seem to be useful here, but is actually a red herring.
There has GOT to be a better way, no?
You can do it using just the -I (include names matching the given patterns) argument for backout with a single line:
hg backout --merge -I thefiletorevert -m 'message' OFFENDINGREVISIONID
Example Script:
hg init testrepo
cd testrepo
echo -e "line1\n\nline3" > file1
echo -e "line1\n\nline3" > file2
hg commit -A -m 'changes to two files'
perl -pi -e 's/line1/line 1/' file1
perl -pi -e 's/line1/line 1/' file2
hg commit -m 'put spaces in line1'
perl -pi -e 's/line3/line 3/' file1
perl -pi -e 's/line3/line 3/' file2
hg commit -m 'put spaces in line3'
hg backout --merge -I file1 -m 'remove spaces from line1' 1
Sample output:
adding file1
adding file2
reverting file1
created new head
changeset 3:6d354f1ad4c5 backs out changeset 1:906bbeaca6a3
merging with changeset 3:6d354f1ad4c5
merging file1
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
Resulting File Contents:
file1:line1
file1:line 3
file2:line 1
file2:line 3
notice that file1 is missing it's space in line one after the backout of the middle changeset, and the verbose log shows only one file changed in the backout:
$ hg log -v -r tip
changeset: 3:6d354f1ad4c5
tag: tip
parent: 1:906bbeaca6a3
user: Ry4an Brase <ry4an#mini>
date: Mon Sep 14 12:17:23 2009 -0500
files: file1
description:
remove spaces from line1
Here's what I would do: Use a fresh clone of the tip revision.
hg backout --merge -r revision_where_the_change_happened
to merge the reversed changes into the working copy.
Now copy the file in question to your regular working copy and commit
hg commit -m "Reversed the changes to file.h made in revision bla"
and throw away the clone you created above.
This way, mercurial doesn't know that there is a connection between revision_where_the_change_happened and this commit. If you want mercurial to remember this, instead do a
hg revert {all files except the one in question}
after merging the backout commit into the working copy and before commiting. For the second way, you don't need to work on a clone, because you want to keep the backout commit.
I would guess that the choice of which way you use depends on how big a part of the changeset the particular file change was.
Use the revert command.
hg revert -r1 file
This should revert the contents of file to the version in revision 1.
You can then further edit it and commit as normal.