patch: handle symlink updates/replacements (
issue1785)
--- a/mercurial/patch.py Thu Oct 15 23:15:30 2009 +0200
+++ b/mercurial/patch.py Thu Oct 15 23:15:30 2009 +0200
@@ -301,7 +301,14 @@
fp.close()
def writelines(self, fname, lines):
- fp = self.opener(fname, 'w')
+ # Ensure supplied data ends in fname, being a regular file or
+ # a symlink. updatedir() will -too magically- take care of
+ # setting it to the proper type afterwards.
+ islink = os.path.islink(fname)
+ if islink:
+ fp = cStringIO.StringIO()
+ else:
+ fp = self.opener(fname, 'w')
try:
if self.eol and self.eol != '\n':
for l in lines:
@@ -310,6 +317,8 @@
fp.write(l)
else:
fp.writelines(lines)
+ if islink:
+ self.opener.symlink(fp.getvalue(), fname)
finally:
fp.close()
--- a/tests/test-mq-symlinks Thu Oct 15 23:15:30 2009 +0200
+++ b/tests/test-mq-symlinks Thu Oct 15 23:15:30 2009 +0200
@@ -10,7 +10,8 @@
hg qnew base.patch
echo aaa > a
echo bbb > b
-hg add a b
+echo ccc > c
+hg add a b c
hg qrefresh
$TESTDIR/readlink.py a
@@ -25,6 +26,28 @@
hg qpush
$TESTDIR/readlink.py a
+echo '% test updating a symlink'
+rm a
+ln -s c a
+hg qnew --git -f updatelink
+$TESTDIR/readlink.py a
+hg qpop
+hg qpush --debug
+$TESTDIR/readlink.py a
+hg st
+
+echo '% test replacing a symlink with a file'
+ln -s c s
+hg add s
+hg qnew --git -f addlink
+rm s
+echo sss > s
+hg qnew --git -f replacelinkwithfile
+hg qpop
+hg qpush
+cat s
+hg st
+
echo '% test symlink removal'
hg qnew removesl.patch
hg rm a
--- a/tests/test-mq-symlinks.out Thu Oct 15 23:15:30 2009 +0200
+++ b/tests/test-mq-symlinks.out Thu Oct 15 23:15:30 2009 +0200
@@ -5,8 +5,23 @@
applying symlink.patch
now at: symlink.patch
a -> b
+% test updating a symlink
+a -> c
+now at: symlink.patch
+applying updatelink
+patching file a
+a
+now at: updatelink
+a -> c
+% test replacing a symlink with a file
+now at: addlink
+applying replacelinkwithfile
+now at: replacelinkwithfile
+sss
% test symlink removal
-now at: symlink.patch
+now at: replacelinkwithfile
applying removesl.patch
now at: removesl.patch
C b
+C c
+C s