# HG changeset patch # User Patrick Mezard # Date 1255641330 -7200 # Node ID d08099e74b819ae4b9d4faf1c55b5eefc218584f # Parent ea1935e2020a666e888cd8564295601ae8140c70 patch: handle symlink updates/replacements (issue1785) diff -r ea1935e2020a -r d08099e74b81 mercurial/patch.py --- 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() diff -r ea1935e2020a -r d08099e74b81 tests/test-mq-symlinks --- 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 diff -r ea1935e2020a -r d08099e74b81 tests/test-mq-symlinks.out --- 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