Mercurial - hg bisect - view simple list of contributing changesets - mercurial

I'm looking to view all the changesets that have been tested by an hg bisect.
I want them in a simple, easy to read format like:
2391928719e - good
7321374343e - good
3232738237e - bad
4873487473e - bad
39732197132 - bad
39732197132 - bad
I know about hg log -r bisect(range), but I don't think that gives me the status?

bisect(range) just gives you the revisions that participated, yes. Your problem is with the output, not with the revset, so look at hg help template instead to get output options.
There you'll find:
$ hg help template | grep ' bisect '
bisect String. The commit bisection status.
Use that in a -T template:
hg log -r 'bisect(range)' -T '{node|short} - {bisect}\n'
This then gives you your list of nodes participating, with their status; one of good, bad, untested, ignored or skipped.
There is even a built-in template for this, named bisect; this is just the default template with a bisect: {bisect} line added:
hg log -r 'bisect(range)' -T bisect
There's also a shortbisect filter; it'll return a single letter for a given bisection status rather than the full text. This is helpful in a -G graph, set the ui.graphnodetemplate option to {bisect|shortbisect} to have the node 'icon' be the status:
hg log -r 'bisect(range)' -G \
--config "ui.graphnodetemplate={bisect|shortbisect}"
-T compact
which produces something like
G 1011 2391928719e 2017-09-21 15:58 +0530 author
| first line of commit message
|
G 1010 7321374343e 2017-09-21 15:58 +0530 author
| first line of commit message
|
B 1009 3232738237e 2017-09-21 15:58 +0530 author
| first line of commit message
|
B 1008 4873487473e 2017-09-21 15:58 +0530 author
| first line of commit message
|
B 1007 39732197132 2017-09-21 15:58 +0530 author
| first line of commit message
|
B 1006 39732197132 2017-09-21 15:58 +0530 author
| first line of commit message
~

Related

How do I update to the last public revision in my repository?

o 911e74cd 44 minutes ago master
|
| # f085ae95 3 minutes ago
| | Testing
| |
| o 4431b579 Today at 11:24
|/ Feature
|
o 4ab195c4 Today at 04:59
I am currently on revision f085ae95 and I would like to use one hg update command to get to 4ab195c4, which is the last ancestor that is on the public branch in the repository.
You can literally do:
hg update 4431b579
and that should work.
This will update the files in your working folder to whatever state they had in the referenced changeset.
You could also use:
hg up -r -2
to go back 2 revisions from the working folder, which I think would do the same thing.
hg log -r "last(public() and ancestors(.))" --template "{node}" will print out the hash of the last commit on the public branch that is also an ancestor of the current commit. As such you can now chain command calss via:
hg update `hg log -r "last(public() and ancestors(.))" --template "{node}"`
or
hg rebase -s `<commit-you-want-to-rebase>` -d `hg log -r "last(public() and ancestors(.))" --template "{node}"`

Hg command to get the file content without switching branch

In HG, is there any command such that i can get the file content of the file from another branch without switching/checkout to the particular branch?
Similar to the other answer, you can use the cat command but in a slightly different way:
hg cat --rev=11204 path/to/file
This will pick the file from revision #11204 which can be any branch.
You may want to add the --output switch lets you use whatever filename and/or location you want:
hg cat --output=C:/new/path/to/file/filename#11204.ext --rev=11204 path/to/file
If you are using TortoiseHG, you can use the "save at revision" command to do this.
Steps:
Run Tortoise Workbench
Find the changeset in history which has the file revision you want (could be in any branch)
Say its changeset #abcd1234
Right click on the specific file in the file list for that changeset
Select "Save at revision..." and tell it where to put the file.
The file would typically be named filename#abcd1234.ext so that you don't mix it up with the current version.
Use the cat subcommand with the revision number of the commit you're looking for.
Here's an example. I create two branches with the contents of the file file indicating which branch it's on. Then I use cat to examine the contents on both branches
% hg init foo
% cd foo
% echo "default branch" > file
% hg add file
% hg ci -m 'default' file
% echo "default 2nd rev" > file
% hg ci -m 'default 2nd rev' file
% hg glog
# changeset: 1:305b2b5ccbd9
| tag: tip
| user: dj
| date: Mon Sep 17 14:11:20 2018 -0400
| summary: default 2nd rev
|
o changeset: 0:6d22c68d8abc
user: dj
date: Mon Sep 17 14:10:56 2018 -0400
summary: default
% hg co -r 0
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
% echo "new branch" > file
% hg branch 'new branch'
marked working directory as branch new branch
(branches are permanent and global, did you want a bookmark?)
% hg ci -m 'new branch'
% hg glog
# changeset: 2:4c8d2181526c
| branch: new branch
| tag: tip
| parent: 0:6d22c68d8abc
| user: dj
| date: Mon Sep 17 14:12:30 2018 -0400
| summary: new branch
|
| o changeset: 1:305b2b5ccbd9
|/ user: dj
| date: Mon Sep 17 14:11:20 2018 -0400
| summary: default 2nd rev
|
o changeset: 0:6d22c68d8abc
user: dj
date: Mon Sep 17 14:10:56 2018 -0400
summary: default
% hg branches
new branch 2:4c8d2181526c
default 1:305b2b5ccbd9
% hg cat -r 2 file
new branch
% hg cat -r 1 file
default 2nd rev

Check who pushed the commit in mercurial HG

Example scenario:
revision #100 - user1 makes a commit on DEV branch in 2017-01-01
revision #101 - user2 cherry picked user1's commit to master branch (hg graft -r 100) in 2017-01-02
hg log:
changeset:101
user: user1
date: 2017-01-01
summary: message 100
changeset:100
user: user1
date: 2017-01-01
summary: message 100
But how would I know user2 pushed revision #101?
You cannot (besides what Lasse suggest in his comment).
Consider:
touch a; hg add a; hg commit -m 'Add a as myself'
touch b; hg add b; hg commit -m 'Add b as you' --user you#foo.com
hg update 0
hg branch stable
hg graft --user 3rd#bar.com --force 1
hg log --graph
# changeset: 2:3078a4888a8a
| branch: stable
| tag: tip
| parent: 0:f7fa0d60eaf2
| user: 3rd#bar.com
| date: Fri Apr 28 20:07:35 2017 +0200
| summary: Add b as you
|
| o changeset: 1:e12471b861d6
|/ user: you#foo.com
| date: Fri Apr 28 20:07:35 2017 +0200
| summary: Add b as you
|
o changeset: 0:f7fa0d60eaf2
user: This Is Me me#me.com
date: Fri Apr 28 20:06:42 2017 +0200
summary: Add a as myself
If you think about it, it is less shocking than what is seems (I am not saying it is not a problem, mind you).
Mercurial has an extension to perform PGP signatures which might help, but not after the fact and requires a certain setup.
To have detailed explanation, have a look at CommitSigningPlan, although I don't know the status.
To my knowledge, monotone was a distributed VCS system designed to solve this kind of problems, I am not sure whether it is still developed.
I would finish with a philosophical observation: if a project has to protect itself from this kind of problems (an authorised developer impersonating another), then maybe that project has other problems... Again, this doesn't mean that authenticating a commit is not important.

how to see all revisions related to a particular string in a file with mercurial?

Is there a way to generate a list of changesets that affected a particular line of a file? Annotate will let me see the last changeset to affect a particular line, I would like to chain annotations for a particular line back until it was first added.
What about:
hg grep --all symbolBeingWatched
or if you really just want the list of revisions
hg grep --all symbolBeingwatched | cut -d : -f 2 | sort -u -n
Extended (and slightly alternated) version of pyfunc comment, without "ready-to-use" solution, only draft, with samples from my repo
Define all changesets, which affect file (I'm lazy to write final gawk-code)
hg log --template "{rev}\n" functions.php
3
2
1
0
For each revision from set:
hg ann -r $REV functions.php | grep "load_theme_" >> string.txt
string.txt will be after all hg ann | (none for rev 0 was grepped)
2: load_theme_textdomain('fiver', get_template_directory() . '/languages');
2: load_theme_textdomain('fiver', get_template_directory() . '/languages');
1: load_theme_textdomain('fiver', get_template_directory() . '/translation');
Remove duplicates with uniq pipe and get final result
Frank says: thanks, that got me started, I ended up using the following from Powershell to watch what changesets affected a particular symbol:
$history = hg log --template "{rev}\n" $filename
$history | % { $_; hg log -vpr $_ $filename | select-string $symbolBeingWatched }

Is there another way of removing multiple heads?

Let's say I have this:
hg init
touch a
hg add a
hg commit -m a
touch b
hg add b
hg commit -m b
hg up -r 0
touch c
hg add c
hg commit -m c
Now I will have multiple heads, because of the last commit. If, for example I want to keep the last head, the one created by commit c ( effectively discarding b, and all other commits made after the first ) , how could I do it? I played a little with mq's strip command, and I'm able to achieve what I want, but I'd like to know if there's another way.
Yes, there is another way. From your example above, the output of hg glog looks a bit like this:
# changeset: 2:925573c7103c
| tag: tip
| parent: 0:4fe26dfe856d
| user: Joel B Fant
| date: Thu Jul 28 23:20:45 2011 -0400
| summary: c
|
| o changeset: 1:9dc928176506
|/ user: Joel B Fant
| date: Thu Jul 28 23:20:24 2011 -0400
| summary: b
|
o changeset: 0:4fe26dfe856d
user: Joel B Fant
date: Thu Jul 28 23:20:12 2011 -0400
summary: a
If you clone test but specify a revision, it will only clone that revision and its ancestors. So if your repo's directory is TwoHeadsMightNotBeBetter, you can go to its parent directory and issue:
hg clone TwoHeadsMightNotBeBetter OneHeadIsFine -r 925573c7103c
I specified changeset id in that, but you could also use -r 2 instead, or even -r tip since it is currently the tip of that repo. Now when you go into the new clone and do hg glog, you have only one head:
# changeset: 1:925573c7103c
| tag: tip
| user: Joel B Fant
| date: Thu Jul 28 23:20:45 2011 -0400
| summary: c
|
o changeset: 0:4fe26dfe856d
user: Joel B Fant
date: Thu Jul 28 23:20:12 2011 -0400
summary: a
If you had 3 heads and wanted to keep 2, it would be a little different. You'd have to clone one of them with -r and the also specify -r on hg pull to pull specific branches.
You can also perform a dummy merge of the changeset containing b (changeset 1 in this case):
$ hg --config ui.merge=internal:fail merge 1
resolving manifests
getting b
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg revert --all --no-backup --rev .
removing b
$ hg status
R b
$ hg commit -m "Dummy merge -- eliminate b"
committed changeset 3:c163151f19df
$ ls
a c
Note that in this case you haven't rewritten any history or created any new repos -- particularly important if b had already been pushed to a centralized repo and pulled by others.