monotone

monotone Mtn Source Tree

Root/restrictions.cc

1// copyright (C) 2005 derek scherger <derek@echologic.com>
2// all rights reserved.
3// licensed to the public under the terms of the GNU GPL (>= 2)
4// see the file COPYING for details
5
6#include <map>
7#include <string>
8#include <vector>
9
10#include "manifest.hh"
11#include "restrictions.hh"
12#include "revision.hh"
13#include "transforms.hh"
14
15void
16extract_rearranged_paths(change_set::path_rearrangement const & rearrangement, path_set & paths)
17{
18 paths.insert(rearrangement.deleted_files.begin(), rearrangement.deleted_files.end());
19 paths.insert(rearrangement.deleted_dirs.begin(), rearrangement.deleted_dirs.end());
20
21 for (std::map<file_path, file_path>::const_iterator i = rearrangement.renamed_files.begin();
22 i != rearrangement.renamed_files.end(); ++i)
23 {
24 paths.insert(i->first);
25 paths.insert(i->second);
26 }
27
28 for (std::map<file_path, file_path>::const_iterator i = rearrangement.renamed_dirs.begin();
29 i != rearrangement.renamed_dirs.end(); ++i)
30 {
31 paths.insert(i->first);
32 paths.insert(i->second);
33 }
34
35 paths.insert(rearrangement.added_files.begin(), rearrangement.added_files.end());
36}
37
38static void
39extract_delta_paths(change_set::delta_map const & deltas, path_set & paths)
40{
41 for (change_set::delta_map::const_iterator i = deltas.begin(); i != deltas.end(); ++i)
42 {
43 paths.insert(i->first);
44 }
45}
46
47static void
48extract_changed_paths(change_set const & cs, path_set & paths)
49{
50 extract_rearranged_paths(cs.rearrangement, paths);
51 extract_delta_paths(cs.deltas, paths);
52}
53
54void
55add_intermediate_paths(path_set & paths)
56{
57 path_set intermediate_paths;
58
59 for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i)
60 {
61 // we know that file_path's are normalized relative paths. So we can
62 // find intermediate paths simply by searching for /.
63 std::string::size_type j = std::string::npos;
64 while ((j = (*i).as_internal().rfind('/', j)) != std::string::npos)
65 {
66 file_path dir = file_path_internal((*i).as_internal().substr(0, j));
67 if (intermediate_paths.find(dir) != intermediate_paths.end()) break;
68 if (paths.find(dir) != paths.end()) break;
69 intermediate_paths.insert(dir);
70 --j;
71 }
72 }
73
74 paths.insert(intermediate_paths.begin(), intermediate_paths.end());
75}
76
77
78static void
79restrict_path_set(std::string const & type,
80 path_set const & paths,
81 path_set & included,
82 path_set & excluded,
83 app_state & app)
84{
85 for (path_set::const_iterator i = paths.begin(); i != paths.end(); ++i)
86 {
87 if (app.restriction_includes(*i))
88 {
89 L(F("restriction includes %s %s\n") % type % *i);
90 included.insert(*i);
91 }
92 else
93 {
94 L(F("restriction excludes %s %s\n") % type % *i);
95 excluded.insert(*i);
96 }
97 }
98}
99
100static void
101restrict_rename_set(std::string const & type,
102 std::map<file_path, file_path> const & renames,
103 std::map<file_path, file_path> & included,
104 std::map<file_path, file_path> & excluded,
105 app_state & app)
106{
107 for (std::map<file_path, file_path>::const_iterator i = renames.begin();
108 i != renames.end(); ++i)
109 {
110 // include renames if either source or target name is included in the restriction
111 if (app.restriction_includes(i->first) || app.restriction_includes(i->second))
112 {
113 L(F("restriction includes %s '%s' to '%s'\n") % type % i->first % i->second);
114 included.insert(*i);
115 }
116 else
117 {
118 L(F("restriction excludes %s '%s' to '%s'\n") % type % i->first % i->second);
119 excluded.insert(*i);
120 }
121 }
122}
123
124void
125restrict_path_rearrangement(change_set::path_rearrangement const & work,
126 change_set::path_rearrangement & included,
127 change_set::path_rearrangement & excluded,
128 app_state & app)
129{
130 restrict_path_set("delete file", work.deleted_files,
131 included.deleted_files, excluded.deleted_files, app);
132 restrict_path_set("delete dir", work.deleted_dirs,
133 included.deleted_dirs, excluded.deleted_dirs, app);
134
135 restrict_rename_set("rename file", work.renamed_files,
136 included.renamed_files, excluded.renamed_files, app);
137 restrict_rename_set("rename dir", work.renamed_dirs,
138 included.renamed_dirs, excluded.renamed_dirs, app);
139
140 restrict_path_set("add file", work.added_files,
141 included.added_files, excluded.added_files, app);
142}
143
144static void
145restrict_delta_map(change_set::delta_map const & deltas,
146 change_set::delta_map & included,
147 change_set::delta_map & excluded,
148 app_state & app)
149{
150 for (change_set::delta_map::const_iterator i = deltas.begin(); i!= deltas.end(); ++i)
151 {
152 if (app.restriction_includes(i->first))
153 {
154 L(F("restriction includes delta on %s\n") % i->first);
155 included.insert(*i);
156 }
157 else
158 {
159 L(F("restriction excludes delta on %s\n") % i->first);
160 excluded.insert(*i);
161 }
162 }
163}
164
165void
166calculate_restricted_rearrangement(app_state & app,
167 std::vector<utf8> const & args,
168 manifest_id & old_manifest_id,
169 revision_id & old_revision_id,
170 manifest_map & m_old,
171 path_set & old_paths,
172 path_set & new_paths,
173 change_set::path_rearrangement & included,
174 change_set::path_rearrangement & excluded)
175{
176 change_set::path_rearrangement work;
177
178 get_base_revision(app,
179 old_revision_id,
180 old_manifest_id, m_old);
181
182 extract_path_set(m_old, old_paths);
183
184 get_path_rearrangement(work);
185
186 path_set valid_paths(old_paths);
187 extract_rearranged_paths(work, valid_paths);
188 add_intermediate_paths(valid_paths);
189
190 app.set_restriction(valid_paths, args);
191
192 restrict_path_rearrangement(work, included, excluded, app);
193
194 apply_path_rearrangement(old_paths, included, new_paths);
195}
196
197void
198calculate_restricted_revision(app_state & app,
199 std::vector<utf8> const & args,
200 revision_set & rev,
201 manifest_map & m_old,
202 manifest_map & m_new,
203 change_set::path_rearrangement & excluded)
204{
205 manifest_id old_manifest_id;
206 revision_id old_revision_id;
207 boost::shared_ptr<change_set> cs(new change_set());
208 path_set old_paths, new_paths;
209
210 rev.edges.clear();
211 m_old.clear();
212 m_new.clear();
213
214 calculate_restricted_rearrangement(app, args,
215 old_manifest_id, old_revision_id,
216 m_old, old_paths, new_paths,
217 cs->rearrangement, excluded);
218
219 build_restricted_manifest_map(new_paths, m_old, m_new, app);
220 complete_change_set(m_old, m_new, *cs);
221
222 calculate_ident(m_new, rev.new_manifest);
223 L(F("new manifest is %s\n") % rev.new_manifest);
224
225 rev.edges.insert(std::make_pair(old_revision_id,
226 std::make_pair(old_manifest_id, cs)));
227}
228
229void
230calculate_restricted_revision(app_state & app,
231 std::vector<utf8> const & args,
232 revision_set & rev,
233 manifest_map & m_old,
234 manifest_map & m_new)
235{
236 change_set::path_rearrangement work;
237 calculate_restricted_revision(app, args, rev, m_old, m_new, work);
238}
239
240void
241calculate_unrestricted_revision(app_state & app,
242 revision_set & rev,
243 manifest_map & m_old,
244 manifest_map & m_new)
245{
246 std::vector<utf8> empty_args;
247 std::set<utf8> saved_exclude_patterns(app.exclude_patterns);
248 app.exclude_patterns.clear();
249 calculate_restricted_revision(app, empty_args, rev, m_old, m_new);
250 app.exclude_patterns = saved_exclude_patterns;
251}
252
253void
254calculate_restricted_change_set(app_state & app,
255 std::vector<utf8> const & args,
256 change_set const & cs,
257 change_set & included,
258 change_set & excluded)
259{
260 path_set valid_paths;
261
262 extract_changed_paths(cs, valid_paths);
263 add_intermediate_paths(valid_paths);
264
265 app.set_restriction(valid_paths, args);
266
267 restrict_path_rearrangement(cs.rearrangement,
268 included.rearrangement, excluded.rearrangement, app);
269
270 restrict_delta_map(cs.deltas, included.deltas, excluded.deltas, app);
271}
272
273

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status