How to find (latest) descendant revision of given ( possibly renamed ) file - mercurial

Assuming a hg repository with arbitrary changes incl file renames/copies.
Some time in the past I picked an arbitrary file revision from repo and noted down it’s changeset/revision :
File A revision 2 changed with changeset aaabbbccceeefffggg
I now ( after several possible committed changes ) want to know which current file in my repo is descendant of the original noted file/revision.
For example the following file history ( incl. renames of A ) :
C tip ( renamed from B rev 7 )
B 7
B 6
B 5
B 4 ( renamed from A rev 3 )
A 3
A 2
A 1
Starting point of my problem is file A revision 2.
How do I traverse to C ( find out the path C and get revision of C too ) ?
Problem is hat A is currently not visible at all in my repo ( because it was renamed to something else ) :
hg log --follow A
abort: cannot follow file not in parent revision: "A"
Somehow I need a reversed “--follow”, i.e. going up the version history (future) instead of down (past).

Update to revision 2 and than call the log --follow command.
I did not tried it, but the message "cannot follow file not in parent revision" suggests that the file should be in the parent of the working directory.

Related

How do I copy commits from one branch to another?

I have a branch with a few revisions in it. I want to try making some code changes that require reordering and patching those commits with histedit, but I want to keep the original branch around in case it doesn't go well. How can I do that?
Example
Before:
master -> change 1 -> change 2 (branch A)
After:
master -> change 1 -> change 2 (branch A)
-> change 1 -> change 2 (branch B)
The integrated and recommended way to copy or cherry-pick commits from one branch to another is using
hg graft -r XX YY ZZ.
where XX YY ZZ etc. are the revisions to copy to your currently checked-out branch. By default they are committed, but you can also use the --no-commit flag so that you can edit changes. Or do it one-by-one and make additions using hg commit --amend.
Compared to exporting and importing it has the added benefit of using the configured merge programme, should a merge be required - but it will NOT be a merge, so no line of ancestors is established from the current commit to the one you copy from.

With Mercurial, how to run a job for each changeset when doing an update?

Question: When I update my working directory from one revision to the other, I'd like to run a script for each revision passed. How can I do this?
Important Constraints
The script is always the same
Traversal should happen iteratively (I don't want to do all this by hand for 100 revisions...)
The incoming hook is no option. It must happen not only after pushes or pulls, but for all updates, no matter how often I switch between revisions.
For illustration:
r1(*) -- r2 -- r3 -- r4(head)
Basically, I'd like to do
r1(*) --> r2 (then run script) --> r3 (then run script) --> r4 (then...
Let's say, my working directory is currently at r1, and now I want to update it to r4. Instead of doing a direct update (like with hg update), I'd like to update to r2 first and then run a script (update-my-database, for example). Afterwards I'd like to update to r3, then run the same script and so on.
It is doable but we must be careful to select a linear piece from the revision graph.
Consider a minimal repository with two heads (same thing would be if two branches or two bookmarks):
$ hg log -G --template "{rev}\n"
o 4
|
| o 3
| |
| o 2
|/
o 1
|
o 0
Say we start from 1. We want to go along either head 4 (so the linear piece would be: 1, 4) or along head 3 (so the linear piece would be: 1, 2, 3).
So we will use a script with two parameters: the beginning and the end of the linear piece.
This is bare-bones but works:
for rev in `hg log -r "descendants(1) and ancestors(3)" --template "{rev}\n"`
do
echo Updating to $rev:
hg update $rev
echo Executing our script:
hg id --id --num
done
Here is the output:
Updating to 1:
0 files updated, 0 files merged, 2 files removed, 0 files unresolved
Executing our script:
4d5aba4313ce 1
Updating to 2:
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
Executing our script:
f0de0712ec00 2
Updating to 3:
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
Executing our script:
d052bd7c310b 3
The script works no matter what is the current revision of the working directory.
Before starting it, you have to do hg fetch to get the changes from the remote without applying them to the working directory and hg log --graph to understand the topology and so select the starting and ending points of the linear piece.
You also have to replace the hardcoded 1 and 3 with the $1 and $2 shell positional parameters and replace the hg id line with your actual script :-)
To understand how it works, we use a feature of mercurial called revsets (do hg help revsets to learn more) that allows to perform queries on the history graph (a bit like SQL :-)

TortoiseHg Workbench Mercurial: Update to old version without creating new branch

I have the following versions
v 3
v 2
v 1
I want to create a new version, v 4, that looks exactly like v 2. I do not want to create a new branch.
I have tried:
Right-click v 2 and then "browse at revision" and then 'revert to revision' and 'revert all file'. Committing this does create v 4 looking like v 2, but it also creates duplicate '.orig' copies of all the files, which are a bother to delete.
Right-click v 2: "Update". This creates a new branch, which I do not want. This used to work without creating a new branch, but it now longer does and I don't know what is different.
EDIT: there can be any number of version between the one that I want to copy and the latest version.
Backout v.3:
Select this changeset in CSET-view - RClick - Backout
hg update tip
hg revert -r V2 -C
hg commit -m deja vu

revision errors in feauture branches while converting from cvs to mercurial

We are converting the cvs repository which has two branches (one is the MAIN and the other is the FEATURE,rest all can be ignored) into a mercurial repository.
We are using the inbuilt tool convert with the following command.
hg convert cvs_source_dir hg_new
where cvs_source_dir = Updated Directory with only Feauture branch changes from CVS.
hg_new= new name of mercurial repository .
After converting ,the hg_new repo has all History data from CVS.
when we did an hg update it points to MAIN branch code .
And if we update it to FEATURE to get the code from FEAUTURE branch as per CVS , by using
hg update FEAUTURE , all the files which dont have a revision in the FEAUTURE branch is getting deleted.
How can this be solved?
If I understand correctly, branch FEATURE doesn't have some files that exist in branch MAIN, so when you hg up to branch FEATURE, these files are missing.
I think it is a feature that hg up brings your working directory into the status when you committed (-c will check the uncommitted changes), so the files that do not exist in branch FEATURE will gone.
This post shows a method to get the file you want from another branch. If you have a list of files, iterate the list and get every file to your current working directory.
[Updated]
A graph to show how to make it right:
(1) your current status
A -- B -- C -- D (MAIN)
\
- E -- F -- G (FEATURE, missing files)
(2) step 1:
A -- B -- C -- D (MAIN)
\
- E -- F -- G (FEATURE, missing files)
\
-H (FEATURE, a head adding all missing files from A)
(3) step 2:
A -- B -- C -- D (MAIN)
\
- H - (rebase) - E' -- F' -- G' (FEATURE, missing files)

Hg select file based on status?

Is there a way to select only those files that have the Modified status?
And is it possible to chain the selection to add more specific selectors?
I want to export the changes in those Modified files, revert to a changeset before I installed the plugin, and re-import changes.
hg diff -I with pattern matching could help, but in this case, and very often, I just want to select files based on their status.
Example of hg st (actual content varies with different folder and filenames/extension):
M /readme.txt
M /dir1/somefile1.txt
M /dir2/somefile2.txt
M /dir3/somefile3.txt
M /dir4/somefile4.txt
! /plugin/lotsoffileshere.txt
! /plugin/lotsoffileshere.txt
! /plugin/lotsoffileshere.txt
Read about filesets in mercurial: hg help filesets
If you want get diff for all modified files (hg diff FILE1 FILE2 ... FILE), build filest for "modified files in repo" in will be (only help was used)
hg diff "set:modified()"