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
Related
I have a large project with unittest binaries running on the other machines. So, the gcda files were generated on the other machines. Then, I download them to the local machine but the different dirs. Each of the dirs has the sources code.
For example: dir gcda1/src/{*.gcda, *.gcno, *.h, *.cpp}..., dir gcda2/src/{*.gcda, *.gcno, *.h, *.cpp}....
Because the project is very large, so I have to run multiple lcov processes at the same time to generate info files to save time. And then merge these info files.
The problem is, when I merge these info files, it will take dir infos, for example:
gcda1/src/unittest1.cpp
gcda2/src/unittest1.cpp
I want this:
src/unittest1.cpp
#src/unittest1.cpp # this is expected to merge with above
The commands I use:
$ cd gcda1
$ lcov --rc lcov_branch_coverage=1 -c -d ./ -b ./ --no-external -o gcda1.info
$ cd ../gcda2
$ lcov --rc lcov_branch_coverage=1 -c -d ./ -b ./ --no-external -o gcda2.info
$ cd ..
$ lcov -a gcda1/gcda1.info -a gcda1/gcda2.info -o gcda.info
$ genhtml gcda.info -o output
The root dir contains the source code.
Description
Well, I have found a method to solve this problem finally.
The info files lcov generated are plain text file. So we can edit them directly.
Once you open these files, you will see every file line start with SF. Like below:
SF:/path/to/your/source/code.h
SF:/path/to/your/source/code.cpp
...
Problem
In my problem, these will be:
// file gcda1.info
SF:/path/to/root_dir/gcda1/src/unittest1.cpp
// file gcda2.info
SF:/path/to/root_dir/gcda2/src/unittest1.cpp
And, after lcov merge, it will be:
// file gcda.info
SF:/path/to/root_dir/gcda1/src/unittest1.cpp
SF:/path/to/root_dir/gcda2/src/unittest1.cpp
But, I expect this:
// file gcda.info
SF:/path/to/root_dir/src/unittest1.cpp
Method
My method to solve the problem is editing the info files directly.
First, edit gcda1.info and gcda2.info, change /path/to/root_dir/gcda1/src/unittest1.cpp to /path/to/root_dir/src/unittest1.cpp, and /path/to/root_dir/gcda2/src/unittest1.cpp to /path/to/root_dir/src/unittest1.cpp.
Then merge them like below and generate html report:
$ lcov -a gcda1.info -a gcda2.info -o gcda.info
$ genhtml gcda.info -o output
In a large project, we could not manually edit each info file, otherwise you will collapse.
We can use sed to help us. Like below:
$ sed "s/\(^SF.*\/\)gcda[0-9]+\/\(.*\)/\1\2/g" gcda_tmp.info > gcda.info
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 am trying to move(via the rename tool) a group of source files but still keep them tracked. Mercurial's rename tool has the --include option for handling multiple names. When I a try to move the files, I get the current directory added to the final name. When I remove the preceding "./" only the file name is referenced.
I am using the -I option to include a pattern of files. For reference:
https://www.selenic.com/mercurial/hg.1.html#rename
I am using Mercurial on windows through Cygwin64.
This is the directory that I am in:
$ pwd
/cygdrive/c/Users/me/thisProject/apple
This is what I want.
$ hg rename -f -v -I '*.c' ./ banana
moving one.c to .banana\one.c
moving two.c to .banana\two.c
moving three.c to .banana\three.c
This is what I don't want.
$ hg rename -f -v -I '*.c' ./ ./banana
moving one.c to banana\apple\one.c
moving two.c to banana\apple\two.c
moving three.c to banana\apple\three.c
Why does adding a "./" to the destination add the current directory name as an extra folder in the output?
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.