Nicolas Goy
Nicolas Goy

Reputation:

Mercurial symlinks on Windows

I've been googling for a while now but I was surprised to be unable to find an answer to this, quite simple, question.

With mercurial 1.4, when I clone a repository on a windows client, symlinks appear as a file containing the path to the original file.

I don't use symlinks extensively, but I do use them for shared lib handling (libpng.so ->libpng.so.2->libpng.so.2.43.0 for example) .

The windows box is here only for testing, which means I'd be very hapy if the symlinks where actual copies of the original file, this would let me compile.

I saw http://markmail.org/message/7d353ucvivhphvvk which is basically the same question, but without any real answer.

Upvotes: 7

Views: 3237

Answers (2)

TBBle
TBBle

Reputation: 1476

Using @pmezard's example as a base, here's my thrown-together hook:

import os
import os.path
import string
import subprocess

def symlinktojunction( ui, repo, hooktype, parent1, **kwargs ):
    ctx = repo[ parent1 ]
    for f in ctx:
        if 'l' in ctx.flags( f ):
            fsrc = ctx[ f ].data()
            winf = string.replace( f, "/", "\\" )
            winfsrc = string.replace( fsrc, "/", "\\" )
            base = os.path.dirname( winf )
            winfsrc = os.path.join( base, winfsrc )
            print "'%s' is symlink to '%s'" % ( f, fsrc )
            os.remove( winf )
            subprocess.call( [ "mklink", "/j", winf, winfsrc ], shell = True )

Upvotes: 3

pmezard
pmezard

Reputation: 427

Well, the usual answer is it's not worth the pain, at least at VCS level. Sure, the solution you propose would work for you, but what about editing symlinked file copies: should they be updated as well ? What happen when you edit the source and copy file in a different manner? And so forth.

Still, nobody prevents you from implementing an extension, or a simple (update) hook scanning the manifest and overwriting links with the original file. It will make the symlinks look as changed but you probably don't care in your test setup.

Here is the hook code (symcopy.py):

def symcopy(ui, repo, hooktype, parent1, **kwargs):
    ctx = repo[parent1]
    for f in ctx:
        if 'l' in ctx.flags(f):
            # overwrite symlink with original file content
            print 'overwriting', f
            fsrc = ctx[f].data()
            repo.wwrite(f, ctx[fsrc].data(), '')

Then in the repo hgrc put something like:

[hooks]
update = python:c:/path/to/symcopy.py:symcopy

And test with running:

$ hg up -C somerev

You really want to --clean when updating since the hook will mark symlinks as modified and you don't want to trigger a merge.

Perhaps fsrc must be cleaned up a bit but you get the idea.

Upvotes: 5

Related Questions