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 )
精彩评论