hg status list without status - mercurial

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()"

Related

hg incoming display the repository root path

Executing the Mercurial command:
hg in -q
produces a list like below.
123:b64543
124:ef312a
This command will be execute on multiple repo's. How can we append the repository path to the above output to identify the repo? Executing command 'hg root' gives us that information but we only want to know about the path if the repo has new changeset. We looked at template but could not find a variable that gave us the right information.
Apppreciate any help.
The easiest solution for appending the root path to hg incoming is to concatenate the two commands with && (assuming you're using Unix):
hg in -q && hg root
This works because hg incoming will return 0 if there are incoming changes, 1 otherwise (or a non-zero value if there was an error).
For more sophisticated manipulation of the output, sed can usually do it. For example, the following command prepends the root to the output:
hg in -q | sed -e "1i$(hg root)"
I'd resort to a bit bash and call hg root within the template. Assuming all directories are sub-directories of the current one (otherwise give the list of dirs differently):
for i in *; do [ -d $i/.hg ] && hg incoming -R$i --template "$(hg root -R$i) {rev}:{node|short}\n"; done

How to drop a prefix from hg archive?

I would like to export files from a repository, ignoring changes in the working tree. Furthermore, rather than exporting everything, I would like to see a subset of it. The destination directory might already contain some files and those must be overwritten.
Given:
project/some/sub/dir/
I would like to export it to:
output/dir/
In git, I can use:
git archive --prefix=dir/ HEAD -- some/sub/dir/ | tar -xv -C output
What is the equivalent command in hg? If I use hg archive -t files -I some/sub/dir output/, then I get output/some/sub/dir. I could pipe the result through tar, but then I have to manually calculate the prefix that should be dropped:
hg archive -t tar -I some/sub/dir/ - |
tar -xv -C output --strip-components=3
(in reality, I have some other tar patterns that should be ignored such as --exclude='.*'). Any ideas? This export will be done for three other directories located in the repository.
Current situation:
srcdir=some/sub/dir
dstdir=output/dir
# hg archive auto-adds a 'proj-version' prefix. Given the srcdir,
# proj-version/some/sub/dir/X should become dstdir/X, so strip 4 components
prefixlength=$(grep -c / <<<"/${srcdir%%/}/")
hg archive -t tar -I "$srcdir" - |
tar -xv -C "$dstdir" --strip-components=$prefixlength
You can
hg archive ... && cd output/some/sub/dir && tar ... isn't it?
Build intermediate repo (Convert Extension), where some/sub/dir/ will be root of this repository (understand also sample from Converting from Mercurial topic) and get tar'red archive directly from hg archive for intermediate repository

how to turn off hg status -S

I want my default hg status to recirse into subrepos. This is easy enough to do in .hgrc:
[alias]
status = status -S
But I want to have another alias, say hg status-no-subrepo, that does not.
[alias]
status-no-subrepo = status
Unfortunately, this does not work, because status-no-subrepo --expands-to--> status --expands-to--> status -S. I imagine there is something to stop the recursion at that point.
Any ideas?
By the way, this seems to be a violation of one of Glew's Rules: any command line option that can be turned on should be possible to turn off. Possibly -S == -S:1, -S:0 to turn off.
Simple, have your original alias under a different name
[alias]
sstat = status -S
Not the answer you were looking for, I know, but it's easy. It also means that you don't get confused if you move to a system without your alias installed (you'll get a proper error to remind you), and others don't get confused when they do things in your account.
I cant tell you how many times I've helped someone out just to get annoyed that they've aliased ls to ls -l or rm to rm -i.
In general I see overriding common commands with personalised versions as ill-conceived.
You need to disable the status alias when running status-no-subrepo.
[alias]
status = status -S
status-no-subrepo = !$HG --config alias.status=status status $#
I don't use subrepos, but I tested similar functionality with my glog alias.
glog = !$HG log --graph --branch $($HG branch) $#
glog-all-branches = !$HG --config alias.glog=glog glog $#
The ! tells Mercurial this is a shell command, not a Mercurial sub-command. When running a shell command, Mercurial sets $HG to the path to the running hg executable. Arguments after the alias are not passed into shell commands by default, so $# adds them back. This allows you to run commands like hg status-no-subrepo --no-status to show changes without subrepos and hide the status prefix.

Mercurial: diffs in a particular changeset?

This is almost exactly a duplicate of Examining a single changeset in Mercurial, and without doubt a duplicate of another question I can't find on SO through Google alone.
I'm looking back through a Mercurial repo, and I want to see what exactly changed between two revisions (let's say 2580 and 2581):
hg log -v -r 2581
gives me all the files that changed.
How can I also see the diffs of these files?
Thanks.
Revision 2580 isn't necessasrily the parent revision of 2581. It's easy to check if it is, of course, but easier yet is to just do:
hg log -p -r 2581
That compares 2581 to its (first) parent revision no matter what it is, and most clearly encompasses the answer to the question "what the hell did 2581 do?"
Try hg diff -r 2580 -r 2581.
hg diff -r 2580 -r 2581
This is a wrong example. The revision 2580 can be in another branch and you get diff between two branches.
Use
hg log -p -r 2581
or hg diff -c 2581
The difference between them in the first lines. Hg log also show information about changeset (parent, author, date, ...)
I prefer second variant hg diff -c ... because it can store to patch files.
hg diff -c 2581 > revision_2581.patch
Another solution is to use revset notation which IMO is a better solution as you can use it in more places consistently (ie you don't need to know about diff -c and log -p ).
hg diff -r 'last(ancestors(2581),2)'
Yes that is rather verbose compared to -c (for diff) and -p (for log).
However mercurial allows you to create revset aliases
In your .hgrc:
[revsetalias]
next(s) = descendants(s, 1)
prev(s) = last(ancestors(s),2)
Now you can do
hg diff -r 'prev(2581)'
hg log -r 'prev(2581)'

Showing renames in hg status?

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.