Using/LookForMoves

Use cases of –look-for-moves flag

The –look-for-moves flag is used to autodetect files and folders renames automatically. It do this comparing the inode information of the file/folder with the inode information saved in the index from the last record/pending change. The index is used to save a timestamp of each file in the repository and the tree structure state at the last record/pending change and the inode information. To do this it has to scan all the working copy at it could be relatively slow if you have a large number of files/folders, so “look-for-moves” flag is not set by default.

The simplest case is when you rename a file/folder:

> mv foo foo2
> darcs whatsnew --look-for-moves
move ./foo ./foo2

You could exchange filenames too, the temporal names are added automatically:

> mv foo foo.temp
> mv foo2 foo
> mv foo.temp foo2
> darcs whatsnew --look-for-moves
move foo foo.tmp~
move foo2 foo
move foo.tmp~ foo2

A lot more complicated renames can be autodetected, like this one:

> mv foo2 dir
> mv foo3 dir2
> mv dir dir2/dir2
> mv dir2 dir
> mv foo dir3/foo3
> mv dir3 dir/dir2
> darcs wh --look-for-moves
move ./dir ./dir2/dir2
move ./dir2 ./dir
move ./dir3 ./dir/dir2/dir3
move ./foo ./dir/dir2/dir3/foo3
move ./foo2 ./dir/dir2/foo2
move ./foo3 ./dir/foo3

You could use record or amend-record to add the changes to the repo adding –look-for-moves flag to the respective commands. In the last example:

> darcs record --look-for-moves
move ./dir ./dir2/dir2
Shall I record this change? (1/6)  [ynW...], or ? for more options: y
move ./dir2 ./dir
Shall I record this change? (2/6)  [ynW...], or ? for more options: y
move ./dir3 ./dir/dir2/dir3
Shall I record this change? (3/6)  [ynW...], or ? for more options: y
move ./foo ./dir/dir2/dir3/foo3
Shall I record this change? (4/6)  [ynW...], or ? for more options: y
move ./foo2 ./dir/dir2/foo2
Shall I record this change? (5/6)  [ynW...], or ? for more options: y
move ./foo3 ./dir/foo3
Shall I record this change? (6/6)  [ynW...], or ? for more options: y
Do you want to record these changes? [Yglqk...], or ? for more options: y
Finished recording patch 'lots of renames'

You could select the renames one by one if you like and the dependencies between are resolved automatically.

Things to keep in mind

like you can see, besides the order of the moves, the algorithm to autodetect moves is flawless, except for one exception, a “cycle” inside of another “cycle” is not managed at all. It can work but most of the cases it will not. For example, exchange the names of two dirs and exchange the names of filenames inside of them could let to things like this:

> mv dir dir.tmp
> mv dir2 dir
> mv dir.tmp dir2
> mv dir/foo dir/foo.tmp
> mv dir/foo2 dir/foo
> mv dir/foo.tmp dir/foo2
> darcs wh --look-for-moves
darcs failed:  Error renaming: destination AnchoredPath [Name "dir",Name "foo"] exists.

Some editors(I would love some feedback on which editors do this.) could make use of temporal files or backups and substitute the old file with the backup. If this is the case, darcs will lose track of the file, but in any case will mark the file like a remove unless it is renamed too. i.e.:

> cp foo foo.backup
> mv foo.backup foo
> darcs wh --look-for-moves
No changes!
> mv foo foo2
> darcs wh --look-for-moves --look-for-adds
R ./foo
a ./foo2

Like you can see, when you rename foo to foo2, darcs lost track of the file, because the backup has a different fileid than the original, and foo2 is registered as a new file. It could be possible to implement a brute force algorithm to autodetect this “renames” but is not currently planned.

Faq

Are inodes really unique?

Yes, there are. In any given instance every file have an unique inode number. That’s why it’s pretty much impossible to mis-guess a move unless you really try it, because it means that there are different files with the same inode, and the only way would be to use the same file but change the content and use it like another file. I mean the probability to have the same inode number in a new file is low(once you have deleted the old file of course), and that a file with the same inode ends in the same repo is even lower, much lower. I think the inode number used by a new file is always an increment from the inodes used before, so unless you cover all the numbers in a 64 bit range, you will not face with the same number twice.