annotate hgsubversion/pushmod.py @ 1229:46523cdfd3b0 stable 1.6.3

pushmod: prepend "link " to base text for links http://svn.apache.org/viewvc?view=revision&revision=1223036 exposes what is arguably a bug in hgsubversion push code. Specifically, when we are receiving text from the server in an editor, we prepend a "link " to the text of symlinks when opening a file and strip it when closing a file. We don't, however, prepend "link " to the base we use when sending text changes to the server. This was working before because prior to that revision, the first thing subversion did was to check whether the entirety of the before text or the entirety of the after text was less than 64 bytes. In that case, it just sent the entirety of the after text as a single insert operation. I'd expect most, but not all symlinks to fit under the 64 byte limit, including the leading "link " text on the subversion end. After the change, the first thing subversion does is check for a leading match that is more than 4 bytes long, or that is the full length of the after text. In this case, it sends a copy operation for the leading match, and then goes into the if < 64 bytes remaining send the whole thing behavior. It also looks for trailing matches of more than 4 bytes even in the <64 byte case, but that's not what breaks the tests. Incidentally, changing the destination of long symlinks was broken even before this subversion change. This diff includes test additions that cover that breakage.
author David Schleimer <dschleimer@gmail.com>
date Thu, 07 Aug 2014 19:30:26 -0700
parents 362e359607c1
children cff81f35b31e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
1 from mercurial import util as hgutil
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
2
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
3 import svnwrap
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
4 import svnexternals
760
bf1c27a89c76 Extract files not to be pushed in util
Patrick Mezard <pmezard@gmail.com>
parents: 759
diff changeset
5 import util
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
6
243
2027f851d60c Small cleanups: remove unneeded imports, useless superclass.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 242
diff changeset
7 class NoFilesException(Exception):
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
8 """Exception raised when you try and commit without files.
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
9 """
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
10
254
9ba31af57e4b Move utility_commands.find_wc_parent_rev() to cmdutil.parentrev().
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 244
diff changeset
11
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
12 def _isdir(svn, branchpath, svndir):
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
13 try:
558
e841e65390d0 push: try a little harder to not send invalid paths to svn
Augie Fackler <durin42@gmail.com>
parents: 556
diff changeset
14 path = ''
e841e65390d0 push: try a little harder to not send invalid paths to svn
Augie Fackler <durin42@gmail.com>
parents: 556
diff changeset
15 if branchpath:
e841e65390d0 push: try a little harder to not send invalid paths to svn
Augie Fackler <durin42@gmail.com>
parents: 556
diff changeset
16 path = branchpath + '/'
e841e65390d0 push: try a little harder to not send invalid paths to svn
Augie Fackler <durin42@gmail.com>
parents: 556
diff changeset
17 svn.list_dir('%s%s' % (path, svndir))
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
18 return True
601
0fe490ce2fbb isolate all imports of Subversion modules in svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 568
diff changeset
19 except svnwrap.SubversionException:
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
20 return False
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
21
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
22
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
23 def _getdirchanges(svn, branchpath, parentctx, ctx, changedfiles, extchanges):
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
24 """Compute directories to add or delete when moving from parentctx
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
25 to ctx, assuming only 'changedfiles' files changed, and 'extchanges'
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
26 external references changed (as returned by svnexternals.diff()).
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
27
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
28 Return (added, deleted) where 'added' is the list of all added
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
29 directories and 'deleted' the list of deleted directories.
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
30 Intermediate directories are included: if a/b/c is new and requires
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
31 the addition of a/b and a, those will be listed too. Intermediate
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
32 deleted directories are also listed, but item order of undefined
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
33 in either list.
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
34 """
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
35 def finddirs(path, includeself=False):
785
40ddf8213fa2 pushmod: do not delete the whole branch when deleting .hgsub
Patrick Mezard <pmezard@gmail.com>
parents: 762
diff changeset
36 if includeself and path:
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
37 yield path
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
38 pos = path.rfind('/')
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
39 while pos != -1:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
40 yield path[:pos]
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
41 pos = path.rfind('/', 0, pos)
785
40ddf8213fa2 pushmod: do not delete the whole branch when deleting .hgsub
Patrick Mezard <pmezard@gmail.com>
parents: 762
diff changeset
42 # Include the root path, properties can be set explicitely on it
40ddf8213fa2 pushmod: do not delete the whole branch when deleting .hgsub
Patrick Mezard <pmezard@gmail.com>
parents: 762
diff changeset
43 # (like externals), and you want to preserve it if there are any
40ddf8213fa2 pushmod: do not delete the whole branch when deleting .hgsub
Patrick Mezard <pmezard@gmail.com>
parents: 762
diff changeset
44 # other child item still existing.
40ddf8213fa2 pushmod: do not delete the whole branch when deleting .hgsub
Patrick Mezard <pmezard@gmail.com>
parents: 762
diff changeset
45 yield ''
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
46
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
47 def getctxdirs(ctx, keptdirs, extdirs):
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
48 dirs = {}
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
49 for f in ctx.manifest():
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
50 for d in finddirs(f):
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
51 if d in dirs:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
52 break
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
53 if d in keptdirs:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
54 dirs[d] = 1
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
55 for extdir in extdirs:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
56 for d in finddirs(extdir, True):
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
57 dirs[d] = 1
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
58 return dirs
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
59
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
60 deleted, added = [], []
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
61 changeddirs = {}
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
62 for f in changedfiles:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
63 if f in parentctx and f in ctx:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
64 # Updated files cannot cause directories to be created
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
65 # or removed.
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
66 continue
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
67 for d in finddirs(f):
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
68 changeddirs[d] = 1
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
69 for e in extchanges:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
70 if not e[1] or not e[2]:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
71 for d in finddirs(e[0], True):
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
72 changeddirs[d] = 1
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
73 if not changeddirs:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
74 return added, deleted
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
75 olddirs = getctxdirs(parentctx, changeddirs,
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
76 [e[0] for e in extchanges if e[1]])
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
77 newdirs = getctxdirs(ctx, changeddirs,
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
78 [e[0] for e in extchanges if e[2]])
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
79
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
80 for d in newdirs:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
81 if d not in olddirs and not _isdir(svn, branchpath, d):
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
82 added.append(d)
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
83
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
84 for d in olddirs:
929
8417be758047 pushmod: keep the root svn dir when emptying the hg repo (issue359)
Patrick Mezard <patrick@mezard.eu>
parents: 911
diff changeset
85 if not d:
8417be758047 pushmod: keep the root svn dir when emptying the hg repo (issue359)
Patrick Mezard <patrick@mezard.eu>
parents: 911
diff changeset
86 # Do not remove the root directory when the hg repo becomes
8417be758047 pushmod: keep the root svn dir when emptying the hg repo (issue359)
Patrick Mezard <patrick@mezard.eu>
parents: 911
diff changeset
87 # empty. hgsubversion cannot create branches, do not remove
8417be758047 pushmod: keep the root svn dir when emptying the hg repo (issue359)
Patrick Mezard <patrick@mezard.eu>
parents: 911
diff changeset
88 # them.
8417be758047 pushmod: keep the root svn dir when emptying the hg repo (issue359)
Patrick Mezard <patrick@mezard.eu>
parents: 911
diff changeset
89 continue
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
90 if d not in newdirs and _isdir(svn, branchpath, d):
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
91 deleted.append(d)
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
92
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
93 return added, deleted
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
94
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
95
466
9548b406a2d8 pushmod: pass SubversionRepo directly to commit()
Patrick Mezard <pmezard@gmail.com>
parents: 438
diff changeset
96 def commit(ui, repo, rev_ctx, meta, base_revision, svn):
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
97 """Build and send a commit from Mercurial to Subversion.
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
98 """
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
99 file_data = {}
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
100 parent = rev_ctx.parents()[0]
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
101 parent_branch = rev_ctx.parents()[0].branch()
1017
c6e9889dba27 layouts: use layouts library for branch mappingduring push
David Schleimer <dschleimer@fb.com>
parents: 987
diff changeset
102 branch_path = meta.layoutobj.remotename(parent_branch)
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
103
762
c31a1f92e1c6 svnexternals: preliminary support for subrepos based externals
Patrick Mezard <pmezard@gmail.com>
parents: 760
diff changeset
104 extchanges = svnexternals.diff(svnexternals.parse(ui, parent),
c31a1f92e1c6 svnexternals: preliminary support for subrepos based externals
Patrick Mezard <pmezard@gmail.com>
parents: 760
diff changeset
105 svnexternals.parse(ui, rev_ctx))
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
106 addeddirs, deleteddirs = _getdirchanges(svn, branch_path, parent, rev_ctx,
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
107 rev_ctx.files(), extchanges)
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
108 deleteddirs = set(deleteddirs)
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
109
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
110 props = {}
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
111 copies = {}
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
112 for file in rev_ctx.files():
760
bf1c27a89c76 Extract files not to be pushed in util
Patrick Mezard <pmezard@gmail.com>
parents: 759
diff changeset
113 if file in util.ignoredfiles:
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
114 continue
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
115 new_data = base_data = ''
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
116 action = ''
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
117 if file in rev_ctx:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
118 fctx = rev_ctx.filectx(file)
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
119 new_data = fctx.data()
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
120
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
121 if 'x' in fctx.flags():
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
122 props.setdefault(file, {})['svn:executable'] = '*'
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
123 if 'l' in fctx.flags():
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
124 props.setdefault(file, {})['svn:special'] = '*'
793
e698be84c22d pushmod: fix binary files svn:mime-type (issue255)
Patrick Mezard <pmezard@gmail.com>
parents: 785
diff changeset
125 isbinary = hgutil.binary(new_data)
e698be84c22d pushmod: fix binary files svn:mime-type (issue255)
Patrick Mezard <pmezard@gmail.com>
parents: 785
diff changeset
126 if isbinary:
e698be84c22d pushmod: fix binary files svn:mime-type (issue255)
Patrick Mezard <pmezard@gmail.com>
parents: 785
diff changeset
127 props.setdefault(file, {})['svn:mime-type'] = 'application/octet-stream'
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
128
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
129 if file not in parent:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
130 renamed = fctx.renamed()
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
131 if renamed:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
132 # TODO current model (and perhaps svn model) does not support
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
133 # this kind of renames: a -> b, b -> c
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
134 copies[file] = renamed[0]
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
135 base_data = parent[renamed[0]].data()
1229
46523cdfd3b0 pushmod: prepend "link " to base text for links
David Schleimer <dschleimer@gmail.com>
parents: 1082
diff changeset
136 if 'l' in parent[renamed[0]].flags():
46523cdfd3b0 pushmod: prepend "link " to base text for links
David Schleimer <dschleimer@gmail.com>
parents: 1082
diff changeset
137 base_data = 'link ' + base_data
911
772280aed751 Honor SVN auto-props (solves issue #186)
Ronny Voelker <ronny.voelker@googlemail.com>
parents: 793
diff changeset
138 else:
1017
c6e9889dba27 layouts: use layouts library for branch mappingduring push
David Schleimer <dschleimer@fb.com>
parents: 987
diff changeset
139 autoprops = svn.autoprops_config.properties(file)
911
772280aed751 Honor SVN auto-props (solves issue #186)
Ronny Voelker <ronny.voelker@googlemail.com>
parents: 793
diff changeset
140 if autoprops:
772280aed751 Honor SVN auto-props (solves issue #186)
Ronny Voelker <ronny.voelker@googlemail.com>
parents: 793
diff changeset
141 props.setdefault(file, {}).update(autoprops)
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
142
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
143 action = 'add'
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
144 dirname = '/'.join(file.split('/')[:-1] + [''])
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
145 else:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
146 base_data = parent.filectx(file).data()
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
147 if ('x' in parent.filectx(file).flags()
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
148 and 'x' not in rev_ctx.filectx(file).flags()):
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
149 props.setdefault(file, {})['svn:executable'] = None
1229
46523cdfd3b0 pushmod: prepend "link " to base text for links
David Schleimer <dschleimer@gmail.com>
parents: 1082
diff changeset
150 if 'l' in parent.filectx(file).flags():
46523cdfd3b0 pushmod: prepend "link " to base text for links
David Schleimer <dschleimer@gmail.com>
parents: 1082
diff changeset
151 base_data = 'link ' + base_data
46523cdfd3b0 pushmod: prepend "link " to base text for links
David Schleimer <dschleimer@gmail.com>
parents: 1082
diff changeset
152 if 'l' not in rev_ctx.filectx(file).flags():
46523cdfd3b0 pushmod: prepend "link " to base text for links
David Schleimer <dschleimer@gmail.com>
parents: 1082
diff changeset
153 props.setdefault(file, {})['svn:special'] = None
793
e698be84c22d pushmod: fix binary files svn:mime-type (issue255)
Patrick Mezard <pmezard@gmail.com>
parents: 785
diff changeset
154 if hgutil.binary(base_data) and not isbinary:
e698be84c22d pushmod: fix binary files svn:mime-type (issue255)
Patrick Mezard <pmezard@gmail.com>
parents: 785
diff changeset
155 props.setdefault(file, {})['svn:mime-type'] = None
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
156 action = 'modify'
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
157 else:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
158 pos = file.rfind('/')
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
159 if pos >= 0:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
160 if file[:pos] in deleteddirs:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
161 # This file will be removed when its directory is removed
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
162 continue
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
163 action = 'delete'
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
164 file_data[file] = base_data, new_data, action
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
165
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
166 def svnpath(p):
501
c617dcaac86d single: fix push
Vitaliy Filippov <vitalif@yourcmc.ru>
parents: 500
diff changeset
167 return ('%s/%s' % (branch_path, p)).strip('/')
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
168
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
169 changeddirs = []
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
170 for d, v1, v2 in extchanges:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
171 props.setdefault(svnpath(d), {})['svn:externals'] = v2
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
172 if d not in deleteddirs and d not in addeddirs:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
173 changeddirs.append(svnpath(d))
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
174
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
175 # Now we are done with files, we can prune deleted directories
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
176 # against themselves: ignore a/b if a/ is already removed
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
177 deleteddirs2 = list(deleteddirs)
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
178 deleteddirs2.sort(reverse=True)
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
179 for d in deleteddirs2:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
180 pos = d.rfind('/')
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
181 if pos >= 0 and d[:pos] in deleteddirs:
323
067914ecb4eb push: Fix a bug in deletion of an entire tree.
Augie Fackler <durin42@gmail.com>
parents: 311
diff changeset
182 deleteddirs.remove(d)
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
183
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
184 newcopies = {}
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
185 for source, dest in copies.iteritems():
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
186 newcopies[svnpath(source)] = (svnpath(dest), base_revision)
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
187
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
188 new_target_files = [svnpath(f) for f in file_data]
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
189 for tf, ntf in zip(file_data, new_target_files):
501
c617dcaac86d single: fix push
Vitaliy Filippov <vitalif@yourcmc.ru>
parents: 500
diff changeset
190 if tf in file_data and tf != ntf:
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
191 file_data[ntf] = file_data[tf]
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
192 if tf in props:
793
e698be84c22d pushmod: fix binary files svn:mime-type (issue255)
Patrick Mezard <pmezard@gmail.com>
parents: 785
diff changeset
193 props[ntf] = props.pop(tf)
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
194 del file_data[tf]
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
195
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
196 addeddirs = [svnpath(d) for d in addeddirs]
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
197 deleteddirs = [svnpath(d) for d in deleteddirs]
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
198 new_target_files += addeddirs + deleteddirs + changeddirs
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
199 if not new_target_files:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
200 raise NoFilesException()
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
201 try:
1054
131cb06dca76 svnwrap & pushmod: return a Revision when committing
Dan Villiom Podlaski Christiansen <dan@cabo.dk>
parents: 1036
diff changeset
202 return svn.commit(new_target_files, rev_ctx.description(), file_data,
131cb06dca76 svnwrap & pushmod: return a Revision when committing
Dan Villiom Podlaski Christiansen <dan@cabo.dk>
parents: 1036
diff changeset
203 base_revision, set(addeddirs), set(deleteddirs),
131cb06dca76 svnwrap & pushmod: return a Revision when committing
Dan Villiom Podlaski Christiansen <dan@cabo.dk>
parents: 1036
diff changeset
204 props, newcopies)
601
0fe490ce2fbb isolate all imports of Subversion modules in svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 568
diff changeset
205 except svnwrap.SubversionException, e:
1082
362e359607c1 push: allow obtaining the traceback for Subversion exceptions
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 1054
diff changeset
206 ui.traceback()
362e359607c1 push: allow obtaining the traceback for Subversion exceptions
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 1054
diff changeset
207
601
0fe490ce2fbb isolate all imports of Subversion modules in svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 568
diff changeset
208 if len(e.args) > 0 and e.args[1] in (svnwrap.ERR_FS_TXN_OUT_OF_DATE,
1036
e775ffbcb359 push: also suggest user rebase if we get SVN_ERR_FS_ALREADY_EXISTS
Augie Fackler <raf@durin42.com>
parents: 1017
diff changeset
209 svnwrap.ERR_FS_CONFLICT,
e775ffbcb359 push: also suggest user rebase if we get SVN_ERR_FS_ALREADY_EXISTS
Augie Fackler <raf@durin42.com>
parents: 1017
diff changeset
210 svnwrap.ERR_FS_ALREADY_EXISTS):
556
8522f8ef799e pushmod: make outdated parent error message more helpful
Patrick Mezard <pmezard@gmail.com>
parents: 501
diff changeset
211 raise hgutil.Abort('Outgoing changesets parent is not at '
8522f8ef799e pushmod: make outdated parent error message more helpful
Patrick Mezard <pmezard@gmail.com>
parents: 501
diff changeset
212 'subversion HEAD\n'
8522f8ef799e pushmod: make outdated parent error message more helpful
Patrick Mezard <pmezard@gmail.com>
parents: 501
diff changeset
213 '(pull again and rebase on a newer revision)')
987
cf53cfaaa050 Fixes bug #358. Display correct error message if a svn pre-commit hook blocks the push
Anton Agafonov <equeny@fb.com>
parents: 929
diff changeset
214 elif len(e.args) > 0 and e.args[1] == svnwrap.ERR_REPOS_HOOK_FAILURE:
cf53cfaaa050 Fixes bug #358. Display correct error message if a svn pre-commit hook blocks the push
Anton Agafonov <equeny@fb.com>
parents: 929
diff changeset
215 # Special handling for svn hooks blocking error
cf53cfaaa050 Fixes bug #358. Display correct error message if a svn pre-commit hook blocks the push
Anton Agafonov <equeny@fb.com>
parents: 929
diff changeset
216 raise hgutil.Abort(e.args[0])
242
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
217 else:
06130689a2c8 Move push into svncommands.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 241
diff changeset
218 raise