Mercurial > hgsubversion
annotate push_cmd.py @ 87:b033d74be76b
fetch_command: in stupid non-diffy mode, take changed paths in account
Former code was checkouting all branch files for every converted
revision when diffs were not available in stupid mode. Now, only
changed items are requested.
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Fri, 14 Nov 2008 16:18:24 -0600 |
parents | 6ecdbd22eb1d |
children | 1da7aafdd323 |
rev | line source |
---|---|
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
1 from mercurial import util as merc_util |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
2 from mercurial import hg |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
3 from svn import core |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
4 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
5 import util |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
6 import hg_delta_editor |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
7 import svnwrap |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
8 import fetch_command |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
9 import utility_commands |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
10 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
11 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
12 @util.register_subcommand('push') |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
13 @util.register_subcommand('dcommit') # for git expats |
86
6ecdbd22eb1d
push_cmd: add option to push in stupid mode
Patrick Mezard <pmezard@gmail.com>
parents:
85
diff
changeset
|
14 def push_revisions_to_subversion(ui, repo, hg_repo_path, svn_url, |
6ecdbd22eb1d
push_cmd: add option to push in stupid mode
Patrick Mezard <pmezard@gmail.com>
parents:
85
diff
changeset
|
15 stupid=False, **opts): |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
16 """Push revisions starting at a specified head back to Subversion. |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
17 """ |
44
85fcac4e2291
Fix an encoding bug that would occur if the local encoding was not utf-8.
Augie Fackler <durin42@gmail.com>
parents:
39
diff
changeset
|
18 oldencoding = merc_util._encoding |
85fcac4e2291
Fix an encoding bug that would occur if the local encoding was not utf-8.
Augie Fackler <durin42@gmail.com>
parents:
39
diff
changeset
|
19 merc_util._encoding = 'UTF-8' |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
20 hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
21 ui_=ui) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
22 svn_commit_hashes = dict(zip(hge.revmap.itervalues(), |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
23 hge.revmap.iterkeys())) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
24 # Strategy: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
25 # 1. Find all outgoing commits from this head |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
26 outgoing = utility_commands.outgoing_revisions(ui, repo, hge, |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
27 svn_commit_hashes) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
28 if not (outgoing and len(outgoing)): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
29 ui.status('No revisions to push.') |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
30 return 0 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
31 if len(repo.parents()) != 1: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
32 ui.status('Cowardly refusing to push branch merge') |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
33 return 1 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
34 while outgoing: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
35 oldest = outgoing.pop(-1) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
36 old_ctx = repo[oldest] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
37 if len(old_ctx.parents()) != 1: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
38 ui.status('Found a branch merge, this needs discussion and ' |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
39 'implementation.') |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
40 return 1 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
41 base_n = old_ctx.parents()[0].node() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
42 old_children = repo[base_n].children() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
43 # 2. Commit oldest revision that needs to be pushed |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
44 base_revision = svn_commit_hashes[old_ctx.parents()[0].node()][0] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
45 commit_from_rev(ui, repo, old_ctx, hge, svn_url, base_revision) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
46 # 3. Fetch revisions from svn |
86
6ecdbd22eb1d
push_cmd: add option to push in stupid mode
Patrick Mezard <pmezard@gmail.com>
parents:
85
diff
changeset
|
47 r = fetch_command.fetch_revisions(ui, svn_url, hg_repo_path, |
6ecdbd22eb1d
push_cmd: add option to push in stupid mode
Patrick Mezard <pmezard@gmail.com>
parents:
85
diff
changeset
|
48 stupid=stupid) |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
49 assert not r or r == 0 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
50 # 4. Find the new head of the target branch |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
51 repo = hg.repository(ui, hge.path) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
52 base_c = repo[base_n] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
53 replacement = [c for c in base_c.children() if c not in old_children |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
54 and c.branch() == old_ctx.branch()] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
55 assert len(replacement) == 1 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
56 replacement = replacement[0] |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
57 # 5. Rebase all children of the currently-pushing rev to the new branch |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
58 heads = repo.heads(old_ctx.node()) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
59 for needs_transplant in heads: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
60 hg.clean(repo, needs_transplant) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
61 utility_commands.rebase_commits(ui, repo, hg_repo_path, **opts) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
62 repo = hg.repository(ui, hge.path) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
63 if needs_transplant in outgoing: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
64 hg.clean(repo, repo['tip'].node()) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
65 hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, ui_=ui) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
66 svn_commit_hashes = dict(zip(hge.revmap.itervalues(), |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
67 hge.revmap.iterkeys())) |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
68 outgoing = utility_commands.outgoing_revisions(ui, repo, hge, |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
69 svn_commit_hashes) |
44
85fcac4e2291
Fix an encoding bug that would occur if the local encoding was not utf-8.
Augie Fackler <durin42@gmail.com>
parents:
39
diff
changeset
|
70 merc_util._encoding = oldencoding |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
71 return 0 |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
72 |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
73 def _getdirchanges(svn, branchpath, parentctx, ctx, changedfiles): |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
74 """Compute directories to add or delete when moving from parentctx |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
75 to ctx, assuming only 'changedfiles' files changed. |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
76 |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
77 Return (added, deleted) where 'added' is the list of all added |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
78 directories and 'deleted' the list of deleted directories. |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
79 Intermediate directories are included: if a/b/c is new and requires |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
80 the addition of a/b and a, those will be listed too. Intermediate |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
81 deleted directories are also listed, but item order of undefined |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
82 in either list. |
65
b33940d54fe2
push: Fix missing directory creation for the case of a new dir inside a new dir.
Augie Fackler <durin42@gmail.com>
parents:
62
diff
changeset
|
83 """ |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
84 def exists(svndir): |
65
b33940d54fe2
push: Fix missing directory creation for the case of a new dir inside a new dir.
Augie Fackler <durin42@gmail.com>
parents:
62
diff
changeset
|
85 try: |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
86 svn.list_dir('%s/%s' % (branchpath, svndir)) |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
87 return True |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
88 except core.SubversionException: |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
89 return False |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
90 |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
91 def finddirs(path): |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
92 pos = path.rfind('/') |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
93 while pos != -1: |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
94 yield path[:pos] |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
95 pos = path.rfind('/', 0, pos) |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
96 |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
97 def getctxdirs(ctx, keptdirs): |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
98 dirs = {} |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
99 for f in ctx.manifest(): |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
100 for d in finddirs(f): |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
101 if d in dirs: |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
102 break |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
103 if d in keptdirs: |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
104 dirs[d] = 1 |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
105 return dirs |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
106 |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
107 deleted, added = [], [] |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
108 changeddirs = {} |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
109 for f in changedfiles: |
85
05a0c4f6060f
push_cmd: consider only dirs with added/removed files for addition or deletion
Patrick Mezard <pmezard@gmail.com>
parents:
83
diff
changeset
|
110 if f in parentctx and f in ctx: |
05a0c4f6060f
push_cmd: consider only dirs with added/removed files for addition or deletion
Patrick Mezard <pmezard@gmail.com>
parents:
83
diff
changeset
|
111 # Updated files cannot cause directories to be created |
05a0c4f6060f
push_cmd: consider only dirs with added/removed files for addition or deletion
Patrick Mezard <pmezard@gmail.com>
parents:
83
diff
changeset
|
112 # or removed. |
05a0c4f6060f
push_cmd: consider only dirs with added/removed files for addition or deletion
Patrick Mezard <pmezard@gmail.com>
parents:
83
diff
changeset
|
113 continue |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
114 for d in finddirs(f): |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
115 changeddirs[d] = 1 |
85
05a0c4f6060f
push_cmd: consider only dirs with added/removed files for addition or deletion
Patrick Mezard <pmezard@gmail.com>
parents:
83
diff
changeset
|
116 if not changeddirs: |
05a0c4f6060f
push_cmd: consider only dirs with added/removed files for addition or deletion
Patrick Mezard <pmezard@gmail.com>
parents:
83
diff
changeset
|
117 return added, deleted |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
118 olddirs = getctxdirs(parentctx, changeddirs) |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
119 newdirs = getctxdirs(ctx, changeddirs) |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
120 |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
121 for d in newdirs: |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
122 if d not in olddirs and not exists(d): |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
123 added.append(d) |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
124 |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
125 for d in olddirs: |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
126 if d not in newdirs and exists(d): |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
127 deleted.append(d) |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
128 |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
129 return added, deleted |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
130 |
65
b33940d54fe2
push: Fix missing directory creation for the case of a new dir inside a new dir.
Augie Fackler <durin42@gmail.com>
parents:
62
diff
changeset
|
131 |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
132 def commit_from_rev(ui, repo, rev_ctx, hg_editor, svn_url, base_revision): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
133 """Build and send a commit from Mercurial to Subversion. |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
134 """ |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
135 file_data = {} |
9
9eb6bf2be1e7
Fix adding files that require new directories.
Augie Fackler <durin42@gmail.com>
parents:
6
diff
changeset
|
136 svn = svnwrap.SubversionRepo(svn_url, username=merc_util.getuser()) |
9eb6bf2be1e7
Fix adding files that require new directories.
Augie Fackler <durin42@gmail.com>
parents:
6
diff
changeset
|
137 parent = rev_ctx.parents()[0] |
9eb6bf2be1e7
Fix adding files that require new directories.
Augie Fackler <durin42@gmail.com>
parents:
6
diff
changeset
|
138 parent_branch = rev_ctx.parents()[0].branch() |
9eb6bf2be1e7
Fix adding files that require new directories.
Augie Fackler <durin42@gmail.com>
parents:
6
diff
changeset
|
139 branch_path = 'trunk' |
9eb6bf2be1e7
Fix adding files that require new directories.
Augie Fackler <durin42@gmail.com>
parents:
6
diff
changeset
|
140 |
9eb6bf2be1e7
Fix adding files that require new directories.
Augie Fackler <durin42@gmail.com>
parents:
6
diff
changeset
|
141 if parent_branch and parent_branch != 'default': |
9eb6bf2be1e7
Fix adding files that require new directories.
Augie Fackler <durin42@gmail.com>
parents:
6
diff
changeset
|
142 branch_path = 'branches/%s' % parent_branch |
9eb6bf2be1e7
Fix adding files that require new directories.
Augie Fackler <durin42@gmail.com>
parents:
6
diff
changeset
|
143 |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
144 addeddirs, deleteddirs = _getdirchanges(svn, branch_path, parent, |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
145 rev_ctx, rev_ctx.files()) |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
146 deleteddirs = set(deleteddirs) |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
147 |
10
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
148 props = {} |
70
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
149 copies = {} |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
150 for file in rev_ctx.files(): |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
151 new_data = base_data = '' |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
152 action = '' |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
153 if file in rev_ctx: |
70
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
154 fctx = rev_ctx.filectx(file) |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
155 new_data = fctx.data() |
10
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
156 |
70
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
157 if 'x' in fctx.flags(): |
10
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
158 props.setdefault(file, {})['svn:executable'] = '*' |
70
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
159 if 'l' in fctx.flags(): |
10
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
160 props.setdefault(file, {})['svn:special'] = '*' |
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
161 |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
162 if file not in parent: |
70
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
163 renamed = fctx.renamed() |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
164 if renamed: |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
165 # TODO current model (and perhaps svn model) does not support |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
166 # this kind of renames: a -> b, b -> c |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
167 copies[file] = renamed[0] |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
168 base_data = parent[renamed[0]].data() |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
169 |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
170 action = 'add' |
9
9eb6bf2be1e7
Fix adding files that require new directories.
Augie Fackler <durin42@gmail.com>
parents:
6
diff
changeset
|
171 dirname = '/'.join(file.split('/')[:-1] + ['']) |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
172 else: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
173 base_data = parent.filectx(file).data() |
62
cc5ebdb1e8d4
push_cmd: Further simplified some logic thanks to an improved test.
Augie Fackler <durin42@gmail.com>
parents:
60
diff
changeset
|
174 if ('x' in parent.filectx(file).flags() |
cc5ebdb1e8d4
push_cmd: Further simplified some logic thanks to an improved test.
Augie Fackler <durin42@gmail.com>
parents:
60
diff
changeset
|
175 and 'x' not in rev_ctx.filectx(file).flags()): |
cc5ebdb1e8d4
push_cmd: Further simplified some logic thanks to an improved test.
Augie Fackler <durin42@gmail.com>
parents:
60
diff
changeset
|
176 props.setdefault(file, {})['svn:executable'] = None |
60
41dc00c7aef1
Fixed a problem where if you edited an existing symlink by replacing with another symlink, things would get corrupt.
Augie Fackler <durin42@gmail.com>
parents:
57
diff
changeset
|
177 if ('l' in parent.filectx(file).flags() |
41dc00c7aef1
Fixed a problem where if you edited an existing symlink by replacing with another symlink, things would get corrupt.
Augie Fackler <durin42@gmail.com>
parents:
57
diff
changeset
|
178 and 'l' not in rev_ctx.filectx(file).flags()): |
41dc00c7aef1
Fixed a problem where if you edited an existing symlink by replacing with another symlink, things would get corrupt.
Augie Fackler <durin42@gmail.com>
parents:
57
diff
changeset
|
179 props.setdefault(file, {})['svn:special'] = None |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
180 action = 'modify' |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
181 else: |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
182 pos = file.rfind('/') |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
183 if pos >= 0: |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
184 if file[:pos] in deleteddirs: |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
185 # This file will be removed when its directory is removed |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
186 continue |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
187 base_data = parent.filectx(file).data() |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
188 action = 'delete' |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
189 file_data[file] = base_data, new_data, action |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
190 |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
191 # Now we are done with files, we can prune deleted directories |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
192 # against themselves: ignore a/b if a/ is already removed |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
193 deleteddirs2 = list(deleteddirs) |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
194 deleteddirs2.sort() |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
195 deleteddirs2.reverse() |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
196 for d in deleteddirs2: |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
197 pos = d.rfind('/') |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
198 if pos >= 0 and d[:pos] in deleteddirs: |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
199 deleteddirs.remove(d[:pos]) |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
200 |
70
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
201 def svnpath(p): |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
202 return '%s/%s' % (branch_path, p) |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
203 |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
204 newcopies = {} |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
205 for source, dest in copies.iteritems(): |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
206 newcopies[svnpath(source)] = (svnpath(dest), base_revision) |
49b7cbe4c8e3
push_cmd: handle copies at file level
Patrick Mezard <pmezard@gmail.com>
parents:
65
diff
changeset
|
207 |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
208 new_target_files = [svnpath(f) for f in file_data] |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
209 for tf, ntf in zip(file_data, new_target_files): |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
210 if tf in file_data: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
211 file_data[ntf] = file_data[tf] |
10
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
212 if tf in props: |
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
213 props[ntf] = props[tf] |
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
214 del props[tf] |
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
215 if merc_util.binary(file_data[ntf][1]): |
dfdc078661db
Auto-set executable, symlink, and auto-props.
Augie Fackler <durin42@gmail.com>
parents:
9
diff
changeset
|
216 props.setdefault(ntf, {}).update(props.get(ntf, {})) |
12
c5039390332f
Fix partial implementation.
Augie Fackler <durin42@gmail.com>
parents:
10
diff
changeset
|
217 props.setdefault(ntf, {})['svn:mime-type'] = 'application/octet-stream' |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
218 del file_data[tf] |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
219 |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
220 addeddirs = [svnpath(d) for d in addeddirs] |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
221 deleteddirs = [svnpath(d) for d in deleteddirs] |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
222 new_target_files += addeddirs + deleteddirs |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
223 try: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
224 svn.commit(new_target_files, rev_ctx.description(), file_data, |
83
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
225 base_revision, set(addeddirs), set(deleteddirs), |
6c9b7cf1c5aa
push_cmd: delete empty svn directories, refactor directory creation
Patrick Mezard <pmezard@gmail.com>
parents:
70
diff
changeset
|
226 props, newcopies) |
0
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
227 except core.SubversionException, e: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
228 if hasattr(e, 'apr_err') and e.apr_err == 160028: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
229 raise merc_util.Abort('Base text was out of date, maybe rebase?') |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
230 else: |
f2636cfed115
Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff
changeset
|
231 raise |