annotate hg_delta_editor.py @ 69:63ece4ea25c9

hg_delta_editor: register copies only if files are unchanged between source and dest Handle copies of items from revision X into revision Y where X is not the parent of Y. This cannot happen in Mercurial because copies always happen between parents and children. A file copy is recorded if: 1- Source and destination revs are in the same branch. 2- The file is unchanged (content, type, removal) through all revisions between destination and source, not including source and destination. Directory copies are registered only if the previous rules apply on all copied items. [1] is there because file copies across branches are meaningless in Mercurial world. We could have tried to remap the source rev to a similar one in the correct branch, but anyway the intent is wrong. [2] is more questionable but I think it's better this way for we live in a non-perfect svn world. In theory, 99% of copies out there should come from the direct parent. But the direct parent is a fuzzy notion when you can have a working directory composed of different directory at different revisions. So we assume that stuff copied from past revisions exactly matching the content of the direct parent revision is really copied from the parent revision. The alternative would be to discard the copy, which would always happen unless people kept updating the working directory after every commit (see tests).
author Patrick Mezard <pmezard@gmail.com>
date Wed, 05 Nov 2008 13:37:08 +0100
parents e319c9168910
children 9ec2a12c12ae
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
1 import cStringIO
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
2 import cPickle as pickle
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
3 import os
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
4 import sys
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
5 import tempfile
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
6 import traceback
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
7
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
8 from mercurial import context
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
9 from mercurial import hg
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
10 from mercurial import ui
6
1a5bb173170b Fixes for win32 compatibility. Changes suggested by Shun-ichi GOTO, with some alterations by me.
Augie Fackler <durin42@gmail.com>
parents: 0
diff changeset
11 from mercurial import util
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
12 from mercurial import revlog
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
13 from mercurial import node
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
14 from svn import delta
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
15 from svn import core
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
16
34
50d55c3e0d85 Some refactors of the previous change, including transparent upgrade of old-style pickled dictionaries.
Augie Fackler <durin42@gmail.com>
parents: 33
diff changeset
17 import util as our_util
50d55c3e0d85 Some refactors of the previous change, including transparent upgrade of old-style pickled dictionaries.
Augie Fackler <durin42@gmail.com>
parents: 33
diff changeset
18
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
19 def pickle_atomic(data, file_path, dir=None):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
20 """pickle some data to a path atomically.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
21
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
22 This is present because I kept corrupting my revmap by managing to hit ^C
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
23 during the pickle of that file.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
24 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
25 try:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
26 f, path = tempfile.mkstemp(prefix='pickling', dir=dir)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
27 f = os.fdopen(f, 'w')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
28 pickle.dump(data, f)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
29 f.close()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
30 except:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
31 raise
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
32 else:
6
1a5bb173170b Fixes for win32 compatibility. Changes suggested by Shun-ichi GOTO, with some alterations by me.
Augie Fackler <durin42@gmail.com>
parents: 0
diff changeset
33 util.rename(path, file_path)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
34
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
35 def stash_exception_on_self(fn):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
36 """Stash any exception raised in the method on self.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
37
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
38 This is required because the SWIG bindings just mutate any exception into
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
39 a generic Subversion exception with no way of telling what the original was.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
40 This allows the editor object to notice when you try and commit and really
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
41 got an exception in the replay process.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
42 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
43 def fun(self, *args, **kwargs):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
44 try:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
45 return fn(self, *args, **kwargs)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
46 except:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
47 if not hasattr(self, '_exception_info'):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
48 self._exception_info = sys.exc_info()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
49 raise
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
50 return fun
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
51
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
52
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
53 class HgChangeReceiver(delta.Editor):
33
a9c15cae50e5 Faster append-only revmap implementation.
Andreas Hartmetz <ahartmetz@gmail.com>
parents: 23
diff changeset
54 def add_to_revmap(self, revnum, branch, node_hash):
a9c15cae50e5 Faster append-only revmap implementation.
Andreas Hartmetz <ahartmetz@gmail.com>
parents: 23
diff changeset
55 f = open(self.revmap_file, 'a')
a9c15cae50e5 Faster append-only revmap implementation.
Andreas Hartmetz <ahartmetz@gmail.com>
parents: 23
diff changeset
56 f.write(str(revnum) + ' ' + node.hex(node_hash) + ' ' + (branch or '') + '\n')
a9c15cae50e5 Faster append-only revmap implementation.
Andreas Hartmetz <ahartmetz@gmail.com>
parents: 23
diff changeset
57 f.flush()
a9c15cae50e5 Faster append-only revmap implementation.
Andreas Hartmetz <ahartmetz@gmail.com>
parents: 23
diff changeset
58 f.close()
a9c15cae50e5 Faster append-only revmap implementation.
Andreas Hartmetz <ahartmetz@gmail.com>
parents: 23
diff changeset
59 self.revmap[revnum, branch] = node_hash
a9c15cae50e5 Faster append-only revmap implementation.
Andreas Hartmetz <ahartmetz@gmail.com>
parents: 23
diff changeset
60
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
61 def __init__(self, path, ui_=None, subdir='', author_host='',
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
62 tag_locations=['tags']):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
63 """path is the path to the target hg repo.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
64
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
65 subdir is the subdirectory of the edits *on the svn server*.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
66 It is needed for stripping paths off in certain cases.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
67 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
68 if not ui_:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
69 ui_ = ui.ui()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
70 self.ui = ui_
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
71 self.path = path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
72 self.__setup_repo(path)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
73 self.subdir = subdir
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
74 if self.subdir and self.subdir[0] == '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
75 self.subdir = self.subdir[1:]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
76 self.revmap = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
77 if os.path.exists(self.revmap_file):
34
50d55c3e0d85 Some refactors of the previous change, including transparent upgrade of old-style pickled dictionaries.
Augie Fackler <durin42@gmail.com>
parents: 33
diff changeset
78 self.revmap = our_util.parse_revmap(self.revmap_file)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
79 self.branches = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
80 if os.path.exists(self.branch_info_file):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
81 f = open(self.branch_info_file)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
82 self.branches = pickle.load(f)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
83 f.close()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
84 self.tags = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
85 if os.path.exists(self.tag_info_file):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
86 f = open(self.tag_info_file)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
87 self.tags = pickle.load(f)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
88 f.close()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
89 if os.path.exists(self.tag_locations_file):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
90 f = open(self.tag_locations_file)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
91 self.tag_locations = pickle.load(f)
8
c89f53103502 Another fix for Win32 compat.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 6
diff changeset
92 f.close()
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
93 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
94 self.tag_locations = tag_locations
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
95 pickle_atomic(self.tag_locations, self.tag_locations_file,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
96 self.meta_data_dir)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
97
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
98 self.clear_current_info()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
99 self.author_host = author_host
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
100
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
101 def __setup_repo(self, repo_path):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
102 '''Verify the repo is going to work out for us.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
103
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
104 This method will fail an assertion if the repo exists but doesn't have
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
105 the Subversion metadata.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
106 '''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
107 if os.path.isdir(repo_path) and len(os.listdir(repo_path)):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
108 self.repo = hg.repository(self.ui, repo_path)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
109 assert os.path.isfile(self.revmap_file)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
110 assert os.path.isfile(self.svn_url_file)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
111 assert os.path.isfile(self.uuid_file)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
112 assert os.path.isfile(self.last_revision_handled_file)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
113 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
114 self.repo = hg.repository(self.ui, repo_path, create=True)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
115 os.makedirs(os.path.dirname(self.uuid_file))
34
50d55c3e0d85 Some refactors of the previous change, including transparent upgrade of old-style pickled dictionaries.
Augie Fackler <durin42@gmail.com>
parents: 33
diff changeset
116 f = open(self.revmap_file, 'w')
50d55c3e0d85 Some refactors of the previous change, including transparent upgrade of old-style pickled dictionaries.
Augie Fackler <durin42@gmail.com>
parents: 33
diff changeset
117 f.write('%s\n' % our_util.REVMAP_FILE_VERSION)
50d55c3e0d85 Some refactors of the previous change, including transparent upgrade of old-style pickled dictionaries.
Augie Fackler <durin42@gmail.com>
parents: 33
diff changeset
118 f.flush()
50d55c3e0d85 Some refactors of the previous change, including transparent upgrade of old-style pickled dictionaries.
Augie Fackler <durin42@gmail.com>
parents: 33
diff changeset
119 f.close()
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
120
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
121 def clear_current_info(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
122 '''Clear the info relevant to a replayed revision so that the next
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
123 revision can be replayed.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
124 '''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
125 self.current_files = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
126 self.deleted_files = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
127 self.current_rev = None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
128 self.current_files_exec = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
129 self.current_files_symlink = {}
67
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
130 # Map fully qualified destination file paths to module source path
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
131 self.copies = {}
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
132 self.missing_plaintexts = set()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
133 self.commit_branches_empty = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
134 self.base_revision = None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
135
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
136 def _save_metadata(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
137 '''Save the Subversion metadata. This should really be called after
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
138 every revision is created.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
139 '''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
140 pickle_atomic(self.branches, self.branch_info_file, self.meta_data_dir)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
141 pickle_atomic(self.tags, self.tag_info_file, self.meta_data_dir)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
142
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
143 def branches_in_paths(self, paths):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
144 '''Given a list of paths, return the set of branches that are touched.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
145 '''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
146 branches = set([])
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
147 for p in paths:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
148 if self._is_path_valid(p):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
149 junk, branch = self._path_and_branch_for_path(p)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
150 branches.add(branch)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
151 return branches
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
152
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
153 def _path_and_branch_for_path(self, path):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
154 '''Figure out which branch inside our repo this path represents, and
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
155 also figure out which path inside that branch it is.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
156
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
157 Raises an exception if it can't perform its job.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
158 '''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
159 path = self._normalize_path(path)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
160 if path.startswith('trunk'):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
161 p = path[len('trunk'):]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
162 if p and p[0] == '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
163 p = p[1:]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
164 return p, None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
165 elif path.startswith('branches/'):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
166 p = path[len('branches/'):]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
167 br = p.split('/')[0]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
168 p = p[len(br)+1:]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
169 if p and p[0] == '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
170 p = p[1:]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
171 return p, br
38
9ee7ce0505eb Fixes so that I can clone the melange repository successfully. Fixes a bug that
Augie Fackler <durin42@gmail.com>
parents: 34
diff changeset
172 return None, None
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
173 raise Exception,'Things went boom: ' + path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
174
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
175 def set_current_rev(self, rev):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
176 '''Set the revision we're currently converting.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
177 '''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
178 self.current_rev = rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
179
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
180 def _normalize_path(self, path):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
181 '''Normalize a path to strip of leading slashes and our subdir if we
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
182 have one.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
183 '''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
184 if path and path[0] == '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
185 path = path[1:]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
186 if path and path.startswith(self.subdir):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
187 path = path[len(self.subdir):]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
188 if path and path[0] == '/':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
189 path = path[1:]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
190 return path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
191
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
192 def _is_path_valid(self, path):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
193 path = self._normalize_path(path)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
194 if path.startswith('trunk'):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
195 return True
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
196 elif path.startswith('branches/'):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
197 br = path.split('/')[1]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
198 return len(br) > 0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
199 return False
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
200
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
201 def _is_path_tag(self, path):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
202 """If path represents the path to a tag, returns the tag name.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
203
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
204 Otherwise, returns False.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
205 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
206 path = self._normalize_path(path)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
207 for tags_path in self.tag_locations:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
208 if path and (path.startswith(tags_path) and
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
209 len(path) > len('%s/' % tags_path)):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
210 return path[len(tags_path)+1:].split('/')[0]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
211 return False
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
212
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
213 def get_parent_svn_branch_and_rev(self, number, branch):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
214 number -= 1
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
215 if (number, branch) in self.revmap:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
216 return number, branch
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
217 real_num = 0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
218 for num, br in self.revmap.iterkeys():
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
219 if br != branch:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
220 continue
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
221 if num <= number and num > real_num:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
222 real_num = num
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
223 if real_num == 0:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
224 if branch in self.branches:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
225 parent_branch = self.branches[branch][0]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
226 parent_branch_rev = self.branches[branch][1]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
227 branch_created_rev = self.branches[branch][2]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
228 if parent_branch == 'trunk':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
229 parent_branch = None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
230 if branch_created_rev <= number+1 and branch != parent_branch:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
231 return self.get_parent_svn_branch_and_rev(
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
232 parent_branch_rev+1,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
233 parent_branch)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
234 if real_num != 0:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
235 return real_num, branch
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
236 return None, None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
237
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
238 def get_parent_revision(self, number, branch):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
239 '''Get the parent revision hash for a commit on a specific branch.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
240 '''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
241 r, br = self.get_parent_svn_branch_and_rev(number, branch)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
242 if r is not None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
243 return self.revmap[r, br]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
244 return revlog.nullid
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
245
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
246 def update_branch_tag_map_for_rev(self, revision):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
247 paths = revision.paths
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
248 added_branches = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
249 added_tags = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
250 tags_to_delete = set()
59
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
251 branches_to_delete = set()
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
252 for p in paths:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
253 if self._is_path_valid(p):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
254 fi, br = self._path_and_branch_for_path(p)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
255 if fi == '' and br not in self.branches:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
256 src_p = paths[p].copyfrom_path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
257 src_rev = paths[p].copyfrom_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
258 src_tag = self._is_path_tag(src_p)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
259
59
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
260 if not ((src_p and self._is_path_valid(src_p)) or
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
261 (src_tag and src_tag in self.tags)):
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
262 # we'll imply you're a branch off of trunk
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
263 # if you have no path, but if you do, it must be valid
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
264 # or else we assume trunk as well
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
265 src_branch = None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
266 src_rev = revision.revnum
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
267 elif src_tag:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
268 # this is a branch created from a tag. Note that this
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
269 # really does happen (see Django)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
270 src_branch, src_rev = self.tags[src_tag]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
271 added_branches[br] = (src_branch, src_rev,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
272 revision.revnum)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
273 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
274 # Not from a tag, and from a valid repo path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
275 (src_p,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
276 src_branch) = self._path_and_branch_for_path(src_p)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
277 added_branches[br] = src_branch, src_rev, revision.revnum
59
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
278 elif fi == '' and br in self.branches:
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
279 br2 = br or 'default'
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
280 if br2 not in self.repo.branchtags() and paths[p].action == 'D':
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
281 branches_to_delete.add(br)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
282 elif br in added_branches:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
283 if paths[p].copyfrom_rev > added_branches[br][1]:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
284 x,y,z = added_branches[br]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
285 added_branches[br] = x, paths[p].copyfrom_rev, z
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
286 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
287 t_name = self._is_path_tag(p)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
288 if t_name == False:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
289 continue
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
290 src_p, src_rev = paths[p].copyfrom_path, paths[p].copyfrom_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
291 # if you commit to a tag, I'm calling you stupid and ignoring
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
292 # you.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
293 if src_p is not None and src_rev is not None:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
294 if self._is_path_valid(src_p):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
295 file, branch = self._path_and_branch_for_path(src_p)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
296 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
297 # some crazy people make tags from other tags
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
298 file = ''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
299 from_tag = self._is_path_tag(src_p)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
300 if not from_tag:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
301 continue
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
302 branch, src_rev = self.tags[from_tag]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
303 if t_name not in added_tags:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
304 added_tags[t_name] = branch, src_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
305 elif file and src_rev > added_tags[t_name][1]:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
306 added_tags[t_name] = branch, src_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
307 elif (paths[p].action == 'D' and p.endswith(t_name)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
308 and t_name in self.tags):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
309 tags_to_delete.add(t_name)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
310 for t in tags_to_delete:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
311 del self.tags[t]
59
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
312 for br in branches_to_delete:
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
313 del self.branches[br]
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
314 self.tags.update(added_tags)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
315 self.branches.update(added_branches)
23
1f8854804795 Add tests for tags and fix a bug in the tag-finding code that was found by the tests.
Augie Fackler <durin42@gmail.com>
parents: 8
diff changeset
316 self._save_metadata()
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
317
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
318 def commit_current_delta(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
319 if hasattr(self, '_exception_info'):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
320 traceback.print_exception(*self._exception_info)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
321 raise ReplayException()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
322 if self.missing_plaintexts:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
323 raise MissingPlainTextError()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
324 files_to_commit = self.current_files.keys()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
325 files_to_commit.extend(self.current_files_symlink.keys())
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
326 files_to_commit.extend(self.current_files_exec.keys())
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
327 files_to_commit = sorted(list(set(files_to_commit)))
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
328 branch_batches = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
329 rev = self.current_rev
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
330 date = rev.date.replace('T', ' ').replace('Z', '').split('.')[0]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
331 date += ' -0000'
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
332
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
333 # build up the branches that have files on them
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
334 for f in files_to_commit:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
335 if not self._is_path_valid(f):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
336 continue
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
337 p, b = self._path_and_branch_for_path(f)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
338 if b not in branch_batches:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
339 branch_batches[b] = []
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
340 branch_batches[b].append((p, f))
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
341
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
342 for branch, files in branch_batches.iteritems():
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
343 if branch in self.commit_branches_empty and files:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
344 del self.commit_branches_empty[branch]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
345 extra = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
346 files = dict(files)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
347
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
348 parents = (self.get_parent_revision(rev.revnum, branch),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
349 revlog.nullid)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
350 if branch is not None:
59
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
351 if branch not in self.branches and branch not in self.repo.branchtags():
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
352 continue
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
353 extra['branch'] = branch
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
354 parent_ctx = self.repo.changectx(parents[0])
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
355 def filectxfn(repo, memctx, path):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
356 current_file = files[path]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
357 if current_file in self.deleted_files:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
358 raise IOError()
67
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
359 copied = self.copies.get(current_file)
55
987e44afa71e hg_delta_editor: simplify exec/symlink flags generation
Patrick Mezard <pmezard@gmail.com>
parents: 43
diff changeset
360 flags = parent_ctx.flags(path)
59
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
361 is_exec = self.current_files_exec.get(current_file,
55
987e44afa71e hg_delta_editor: simplify exec/symlink flags generation
Patrick Mezard <pmezard@gmail.com>
parents: 43
diff changeset
362 'x' in flags)
59
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
363 is_link = self.current_files_symlink.get(current_file,
55
987e44afa71e hg_delta_editor: simplify exec/symlink flags generation
Patrick Mezard <pmezard@gmail.com>
parents: 43
diff changeset
364 'l' in flags)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
365 if current_file in self.current_files:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
366 data = self.current_files[current_file]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
367 if is_link:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
368 assert data.startswith('link ')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
369 data = data[len('link '):]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
370 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
371 data = parent_ctx.filectx(path).data()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
372 return context.memfilectx(path=path,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
373 data=data,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
374 islink=is_link, isexec=is_exec,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
375 copied=copied)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
376 current_ctx = context.memctx(self.repo,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
377 parents,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
378 rev.message or '...',
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
379 files.keys(),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
380 filectxfn,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
381 '%s%s' %(rev.author, self.author_host),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
382 date,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
383 extra)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
384 new_hash = self.repo.commitctx(current_ctx)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
385 self.ui.status('committed as %s on branch %s\n' %
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
386 (node.hex(new_hash), (branch or 'default')))
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
387 if (rev.revnum, branch) not in self.revmap:
33
a9c15cae50e5 Faster append-only revmap implementation.
Andreas Hartmetz <ahartmetz@gmail.com>
parents: 23
diff changeset
388 self.add_to_revmap(rev.revnum, branch, new_hash)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
389 # now we handle branches that need to be committed without any files
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
390 for branch in self.commit_branches_empty:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
391 ha = self.get_parent_revision(rev.revnum, branch)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
392 if ha == node.nullid:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
393 continue
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
394 parent_ctx = self.repo.changectx(ha)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
395 def del_all_files(*args):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
396 raise IOError
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
397 extra = {}
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
398 if branch:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
399 extra['branch'] = branch
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
400 # True here means nuke all files
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
401 files = []
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
402 if self.commit_branches_empty[branch]:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
403 files = parent_ctx.manifest().keys()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
404 current_ctx = context.memctx(self.repo,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
405 (ha, node.nullid),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
406 rev.message or ' ',
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
407 files,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
408 del_all_files,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
409 '%s%s' % (rev.author,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
410 self.author_host),
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
411 date,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
412 extra)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
413 new_hash = self.repo.commitctx(current_ctx)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
414 self.ui.status('committed as %s on branch %s\n' %
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
415 (node.hex(new_hash), (branch or 'default')))
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
416 if (rev.revnum, branch) not in self.revmap:
33
a9c15cae50e5 Faster append-only revmap implementation.
Andreas Hartmetz <ahartmetz@gmail.com>
parents: 23
diff changeset
417 self.add_to_revmap(rev.revnum, branch, new_hash)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
418 self.clear_current_info()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
419
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
420 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
421 def meta_data_dir(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
422 return os.path.join(self.path, '.hg', 'svn')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
423
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
424 def meta_file_named(self, name):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
425 return os.path.join(self.meta_data_dir, name)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
426
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
427 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
428 def revmap_file(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
429 return self.meta_file_named('rev_map')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
430
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
431 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
432 def svn_url_file(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
433 return self.meta_file_named('url')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
434
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
435 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
436 def uuid_file(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
437 return self.meta_file_named('uuid')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
438
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
439 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
440 def last_revision_handled_file(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
441 return self.meta_file_named('last_rev')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
442
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
443 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
444 def branch_info_file(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
445 return self.meta_file_named('branch_info')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
446
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
447 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
448 def tag_info_file(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
449 return self.meta_file_named('tag_info')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
450
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
451 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
452 def tag_locations_file(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
453 return self.meta_file_named('tag_locations')
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
454
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
455 @property
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
456 def url(self):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
457 return open(self.svn_url_file).read()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
458
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
459 @stash_exception_on_self
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
460 def delete_entry(self, path, revision_bogus, parent_baton, pool=None):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
461 if self._is_path_valid(path):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
462 br_path, branch = self._path_and_branch_for_path(path)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
463 ha = self.get_parent_revision(self.current_rev.revnum, branch)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
464 if ha == revlog.nullid:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
465 return
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
466 ctx = self.repo.changectx(ha)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
467 if br_path not in ctx:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
468 br_path2 = ''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
469 if br_path != '':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
470 br_path2 = br_path + '/'
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
471 # assuming it is a directory
39
b3c7b844b782 Some more fixes of cases discovered in the melange repo. If anyone knows how I can reproduce a "replaced" state in Subversion, I'd love to be able to make a real test case for this code.
Augie Fackler <durin42@gmail.com>
parents: 38
diff changeset
472 def delete_x(x):
b3c7b844b782 Some more fixes of cases discovered in the melange repo. If anyone knows how I can reproduce a "replaced" state in Subversion, I'd love to be able to make a real test case for this code.
Augie Fackler <durin42@gmail.com>
parents: 38
diff changeset
473 self.deleted_files[x] = True
b3c7b844b782 Some more fixes of cases discovered in the melange repo. If anyone knows how I can reproduce a "replaced" state in Subversion, I'd love to be able to make a real test case for this code.
Augie Fackler <durin42@gmail.com>
parents: 38
diff changeset
474 map(delete_x, [pat for pat in self.current_files.iterkeys()
b3c7b844b782 Some more fixes of cases discovered in the melange repo. If anyone knows how I can reproduce a "replaced" state in Subversion, I'd love to be able to make a real test case for this code.
Augie Fackler <durin42@gmail.com>
parents: 38
diff changeset
475 if pat.startswith(path)])
b3c7b844b782 Some more fixes of cases discovered in the melange repo. If anyone knows how I can reproduce a "replaced" state in Subversion, I'd love to be able to make a real test case for this code.
Augie Fackler <durin42@gmail.com>
parents: 38
diff changeset
476 for f in ctx.walk(our_util.PrefixMatch(br_path2)):
b3c7b844b782 Some more fixes of cases discovered in the melange repo. If anyone knows how I can reproduce a "replaced" state in Subversion, I'd love to be able to make a real test case for this code.
Augie Fackler <durin42@gmail.com>
parents: 38
diff changeset
477 f_p = '%s/%s' % (path, f[len(br_path2):])
b3c7b844b782 Some more fixes of cases discovered in the melange repo. If anyone knows how I can reproduce a "replaced" state in Subversion, I'd love to be able to make a real test case for this code.
Augie Fackler <durin42@gmail.com>
parents: 38
diff changeset
478 if f_p not in self.current_files:
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
479 self.deleted_files[f_p] = True
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
480 self.current_files[f_p] = ''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
481 self.ui.status('D %s\n' % f_p)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
482 self.deleted_files[path] = True
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
483 self.current_files[path] = ''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
484 self.ui.status('D %s\n' % path)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
485
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
486 @stash_exception_on_self
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
487 def open_file(self, path, parent_baton, base_revision, p=None):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
488 self.current_file = 'foobaz'
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
489 if self._is_path_valid(path):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
490 self.current_file = path
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
491 self.ui.status('M %s\n' % path)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
492 if base_revision != -1:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
493 self.base_revision = base_revision
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
494 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
495 self.base_revision = None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
496 self.should_edit_most_recent_plaintext = True
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
497
69
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
498 def _aresamefiles(self, parentctx, childctx, files):
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
499 """Assuming all files exist in childctx and parentctx, return True
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
500 if none of them was changed in-between.
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
501 """
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
502 if parentctx == childctx:
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
503 return True
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
504 if parentctx.rev() > childctx.rev():
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
505 parentctx, childctx = childctx, parentctx
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
506
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
507 def selfandancestors(selfctx):
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
508 yield selfctx
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
509 for ctx in selfctx.ancestors():
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
510 yield ctx
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
511
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
512 files = dict.fromkeys(files)
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
513 for pctx in selfandancestors(childctx):
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
514 if pctx.rev() <= parentctx.rev():
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
515 return True
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
516 for f in pctx.files():
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
517 if f in files:
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
518 return False
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
519 # parentctx is not an ancestor of childctx, files are unrelated
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
520 return False
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
521
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
522 @stash_exception_on_self
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
523 def add_file(self, path, parent_baton, copyfrom_path,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
524 copyfrom_revision, file_pool=None):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
525 self.current_file = 'foobaz'
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
526 self.base_revision = None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
527 if path in self.deleted_files:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
528 del self.deleted_files[path]
67
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
529 if not self._is_path_valid(path):
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
530 return
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
531 fpath, branch = self._path_and_branch_for_path(path)
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
532 if not fpath:
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
533 return
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
534 self.current_file = path
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
535 self.should_edit_most_recent_plaintext = False
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
536 if not copyfrom_path:
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
537 self.ui.status('A %s\n' % path)
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
538 return
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
539 self.ui.status('A+ %s\n' % path)
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
540 (from_file,
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
541 from_branch) = self._path_and_branch_for_path(copyfrom_path)
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
542 if not from_file:
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
543 self.missing_plaintexts.add(path)
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
544 return
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
545 ha = self.get_parent_revision(copyfrom_revision + 1,
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
546 from_branch)
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
547 ctx = self.repo.changectx(ha)
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
548 if from_file in ctx:
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
549 fctx = ctx.filectx(from_file)
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
550 cur_file = self.current_file
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
551 self.current_files[cur_file] = fctx.data()
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
552 self.current_files_symlink[cur_file] = 'l' in fctx.flags()
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
553 self.current_files_exec[cur_file] = 'x' in fctx.flags()
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
554 if from_branch == branch:
69
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
555 parentid = self.get_parent_revision(self.current_rev.revnum,
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
556 branch)
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
557 if parentid != revlog.nullid:
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
558 parentctx = self.repo.changectx(parentid)
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
559 if self._aresamefiles(parentctx, ctx, [from_file]):
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
560 self.copies[path] = from_file
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
561
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
562 @stash_exception_on_self
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
563 def add_directory(self, path, parent_baton, copyfrom_path,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
564 copyfrom_revision, dir_pool=None):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
565 if self._is_path_valid(path):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
566 junk, branch = self._path_and_branch_for_path(path)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
567 if not copyfrom_path and not junk:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
568 self.commit_branches_empty[branch] = True
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
569 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
570 self.commit_branches_empty[branch] = False
41
496c0354019c Improved handling of copies from outside of trunk.
Augie Fackler <durin42@gmail.com>
parents: 39
diff changeset
571 if not self._is_path_valid(path) or not copyfrom_path:
496c0354019c Improved handling of copies from outside of trunk.
Augie Fackler <durin42@gmail.com>
parents: 39
diff changeset
572 return
59
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
573 if copyfrom_path:
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
574 tag = self._is_path_tag(copyfrom_path)
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
575 if tag not in self.tags:
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
576 tag = None
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
577 if not self._is_path_valid(copyfrom_path) and not tag:
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
578 self.missing_plaintexts.add('%s/' % path)
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
579 return
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
580
59
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
581 if tag:
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
582 source_branch, source_rev = self.tags[tag]
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
583 cp_f = ''
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
584 else:
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
585 source_rev = copyfrom_revision
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
586 cp_f, source_branch = self._path_and_branch_for_path(copyfrom_path)
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
587 new_hash = self.get_parent_revision(source_rev + 1,
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
588 source_branch)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
589 if new_hash == node.nullid:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
590 self.missing_plaintexts.add('%s/' % path)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
591 return
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
592 cp_f_ctx = self.repo.changectx(new_hash)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
593 if cp_f != '/' and cp_f != '':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
594 cp_f = '%s/' % cp_f
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
595 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
596 cp_f = ''
69
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
597 copies = {}
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
598 for f in cp_f_ctx:
69
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
599 if not f.startswith(cp_f):
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
600 continue
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
601 f2 = f[len(cp_f):]
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
602 fctx = cp_f_ctx.filectx(f)
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
603 fp_c = path + '/' + f2
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
604 self.current_files[fp_c] = fctx.data()
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
605 self.current_files_exec[fp_c] = 'x' in fctx.flags()
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
606 self.current_files_symlink[fp_c] = 'l' in fctx.flags()
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
607 if fp_c in self.deleted_files:
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
608 del self.deleted_files[fp_c]
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
609 if branch == source_branch:
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
610 copies[fp_c] = f
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
611 if copies:
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
612 # Preserve the directory copy records if no file was changed between
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
613 # the source and destination revisions, or discard it completely.
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
614 parentid = self.get_parent_revision(self.current_rev.revnum, branch)
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
615 if parentid != revlog.nullid:
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
616 parentctx = self.repo.changectx(parentid)
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
617 if self._aresamefiles(parentctx, cp_f_ctx, copies.values()):
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
618 self.copies.update(copies)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
619
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
620 @stash_exception_on_self
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
621 def change_file_prop(self, file_baton, name, value, pool=None):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
622 if name == 'svn:executable':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
623 self.current_files_exec[self.current_file] = bool(value)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
624 elif name == 'svn:special':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
625 self.current_files_symlink[self.current_file] = bool(value)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
626
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
627 @stash_exception_on_self
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
628 def open_directory(self, path, parent_baton, base_revision, dir_pool=None):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
629 if self._is_path_valid(path):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
630 p_, branch = self._path_and_branch_for_path(path)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
631 if p_ == '':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
632 self.commit_branches_empty[branch] = False
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
633
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
634 @stash_exception_on_self
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
635 def apply_textdelta(self, file_baton, base_checksum, pool=None):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
636 base = ''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
637 if not self._is_path_valid(self.current_file):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
638 return lambda x: None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
639 if (self.current_file in self.current_files
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
640 and not self.should_edit_most_recent_plaintext):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
641 base = self.current_files[self.current_file]
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
642 elif (base_checksum is not None or
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
643 self.should_edit_most_recent_plaintext):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
644 p_, br = self._path_and_branch_for_path(self.current_file)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
645 par_rev = self.current_rev.revnum
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
646 if self.base_revision:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
647 par_rev = self.base_revision + 1
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
648 ha = self.get_parent_revision(par_rev, br)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
649 if ha != revlog.nullid:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
650 ctx = self.repo.changectx(ha)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
651 if not p_ in ctx:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
652 self.missing_plaintexts.add(self.current_file)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
653 # short circuit exit since we can't do anything anyway
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
654 return lambda x: None
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
655 base = ctx.filectx(p_).data()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
656 source = cStringIO.StringIO(base)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
657 target = cStringIO.StringIO()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
658 self.stream = target
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
659
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
660 handler, baton = delta.svn_txdelta_apply(source, target, None)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
661 if not callable(handler):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
662 # TODO(augie) Raise a real exception, don't just fail an assertion.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
663 assert False, 'handler not callable, bindings are broken'
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
664 def txdelt_window(window):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
665 try:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
666 if not self._is_path_valid(self.current_file):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
667 return
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
668 handler(window, baton)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
669 # window being None means commit this file
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
670 if not window:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
671 self.current_files[self.current_file] = target.getvalue()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
672 except core.SubversionException, e:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
673 if e.message == 'Delta source ended unexpectedly':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
674 self.missing_plaintexts.add(self.current_file)
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
675 else:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
676 self._exception_info = sys.exc_info()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
677 raise
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
678 except:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
679 print len(base), self.current_file
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
680 self._exception_info = sys.exc_info()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
681 raise
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
682 return txdelt_window
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
683
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
684 class MissingPlainTextError(Exception):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
685 """Exception raised when the repo lacks a source file required for replaying
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
686 a txdelta.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
687 """
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
688
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
689 class ReplayException(Exception):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
690 """Exception raised when you try and commit but the replay encountered an
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
691 exception.
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
692 """