开发者

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 pa开发者_Go百科th 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.


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.


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 )
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜