Mercurial > hgsubversion
comparison push_cmd.py @ 70:49b7cbe4c8e3
push_cmd: handle copies at file level
Mercurial store knows only file-level copies, directory copies are handle with
heuristics. Implement the former one in svn backends.
| author | Patrick Mezard <pmezard@gmail.com> |
|---|---|
| date | Wed, 05 Nov 2008 13:37:08 +0100 |
| parents | b33940d54fe2 |
| children | 6c9b7cf1c5aa |
comparison
equal
deleted
inserted
replaced
| 69:63ece4ea25c9 | 70:49b7cbe4c8e3 |
|---|---|
| 99 if parent_branch and parent_branch != 'default': | 99 if parent_branch and parent_branch != 'default': |
| 100 branch_path = 'branches/%s' % parent_branch | 100 branch_path = 'branches/%s' % parent_branch |
| 101 | 101 |
| 102 added_dirs = [] | 102 added_dirs = [] |
| 103 props = {} | 103 props = {} |
| 104 copies = {} | |
| 104 for file in rev_ctx.files(): | 105 for file in rev_ctx.files(): |
| 105 new_data = base_data = '' | 106 new_data = base_data = '' |
| 106 action = '' | 107 action = '' |
| 107 if file in rev_ctx: | 108 if file in rev_ctx: |
| 108 new_data = rev_ctx.filectx(file).data() | 109 fctx = rev_ctx.filectx(file) |
| 110 new_data = fctx.data() | |
| 109 | 111 |
| 110 if 'x' in rev_ctx.filectx(file).flags(): | 112 if 'x' in fctx.flags(): |
| 111 props.setdefault(file, {})['svn:executable'] = '*' | 113 props.setdefault(file, {})['svn:executable'] = '*' |
| 112 if 'l' in rev_ctx.filectx(file).flags(): | 114 if 'l' in fctx.flags(): |
| 113 props.setdefault(file, {})['svn:special'] = '*' | 115 props.setdefault(file, {})['svn:special'] = '*' |
| 114 | 116 |
| 115 if file not in parent: | 117 if file not in parent: |
| 118 renamed = fctx.renamed() | |
| 119 if renamed: | |
| 120 # TODO current model (and perhaps svn model) does not support | |
| 121 # this kind of renames: a -> b, b -> c | |
| 122 copies[file] = renamed[0] | |
| 123 base_data = parent[renamed[0]].data() | |
| 124 | |
| 116 action = 'add' | 125 action = 'add' |
| 117 dirname = '/'.join(file.split('/')[:-1] + ['']) | 126 dirname = '/'.join(file.split('/')[:-1] + ['']) |
| 118 # check for new directories | 127 # check for new directories |
| 119 if not list(parent.walk(util.PrefixMatch(dirname))): | 128 if not list(parent.walk(util.PrefixMatch(dirname))): |
| 120 added_dirs += _findmissing(dirname, svn, branch_path) | 129 added_dirs += _findmissing(dirname, svn, branch_path) |
| 131 base_data = parent.filectx(file).data() | 140 base_data = parent.filectx(file).data() |
| 132 action = 'delete' | 141 action = 'delete' |
| 133 file_data[file] = base_data, new_data, action | 142 file_data[file] = base_data, new_data, action |
| 134 | 143 |
| 135 # TODO check for directory deletes here | 144 # TODO check for directory deletes here |
| 136 new_target_files = ['%s/%s' % (branch_path, f) for f in rev_ctx.files()] | 145 def svnpath(p): |
| 146 return '%s/%s' % (branch_path, p) | |
| 147 | |
| 148 newcopies = {} | |
| 149 for source, dest in copies.iteritems(): | |
| 150 newcopies[svnpath(source)] = (svnpath(dest), base_revision) | |
| 151 | |
| 152 new_target_files = [svnpath(f) for f in rev_ctx.files()] | |
| 137 for tf, ntf in zip(rev_ctx.files(), new_target_files): | 153 for tf, ntf in zip(rev_ctx.files(), new_target_files): |
| 138 if tf in file_data: | 154 if tf in file_data: |
| 139 file_data[ntf] = file_data[tf] | 155 file_data[ntf] = file_data[tf] |
| 140 if tf in props: | 156 if tf in props: |
| 141 props[ntf] = props[tf] | 157 props[ntf] = props[tf] |
| 147 added_dirs = ['%s/%s' % (branch_path, f) for f in added_dirs] | 163 added_dirs = ['%s/%s' % (branch_path, f) for f in added_dirs] |
| 148 added_dirs = set(added_dirs) | 164 added_dirs = set(added_dirs) |
| 149 new_target_files += added_dirs | 165 new_target_files += added_dirs |
| 150 try: | 166 try: |
| 151 svn.commit(new_target_files, rev_ctx.description(), file_data, | 167 svn.commit(new_target_files, rev_ctx.description(), file_data, |
| 152 base_revision, set(added_dirs), props) | 168 base_revision, set(added_dirs), props, newcopies) |
| 153 except core.SubversionException, e: | 169 except core.SubversionException, e: |
| 154 if hasattr(e, 'apr_err') and e.apr_err == 160028: | 170 if hasattr(e, 'apr_err') and e.apr_err == 160028: |
| 155 raise merc_util.Abort('Base text was out of date, maybe rebase?') | 171 raise merc_util.Abort('Base text was out of date, maybe rebase?') |
| 156 else: | 172 else: |
| 157 raise | 173 raise |
