monotone

monotone Mtn Source Tree

Root/src/merge_content.hh

1// Copyright (C) 2005 Nathaniel Smith <njs@pobox.com>
2// 2008, 2010, 2012 Stephen Leake <stephen_leake@stephe-leake.org>
3//
4// This program is made available under the GNU GPL version 2.0 or
5// greater. See the accompanying file COPYING for details.
6//
7// This program is distributed WITHOUT ANY WARRANTY; without even the
8// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
9// PURPOSE.
10
11#ifndef __MERGE_HH__
12#define __MERGE_HH__
13
14#include "vocab.hh"
15#include "roster.hh"
16#include "rev_types.hh"
17#include "paths.hh"
18
19class database;
20class lua_hooks;
21struct roster_merge_result;
22struct options;
23
24struct
25content_merge_adaptor
26{
27 virtual void record_merge(file_id const & left_ident,
28 file_id const & right_ident,
29 file_id const & merged_ident,
30 file_data const & left_data,
31 file_data const & right_data,
32 file_data const & merged_data) = 0;
33
34 // dropped_modified conflict resolution of keep or user creates new node
35 virtual void record_file(file_id const & ident,
36 file_data const & data) = 0;
37
38 virtual void record_file(file_id const & parent_ident,
39 file_id const & merged_ident,
40 file_data const & parent_data,
41 file_data const & merged_data) = 0;
42
43 virtual void get_ancestral_roster(node_id nid,
44 revision_id & rid,
45 boost::shared_ptr<roster_t const> & anc) = 0;
46
47 virtual void get_version(file_id const & ident,
48 file_data & dat) const = 0;
49
50 virtual ~content_merge_adaptor() {}
51};
52
53struct
54content_merge_database_adaptor
55 : public content_merge_adaptor
56{
57 database & db;
58 revision_id lca;
59 revision_id left_rid;
60 revision_id right_rid;
61 marking_map const & left_mm;
62 marking_map const & right_mm;
63 std::map<revision_id, boost::shared_ptr<roster_t const> > rosters;
64 content_merge_database_adaptor(database & db,
65 revision_id const & left,
66 revision_id const & right,
67 marking_map const & left_mm,
68 marking_map const & right_mm);
69 void record_merge(file_id const & left_ident,
70 file_id const & right_ident,
71 file_id const & merged_ident,
72 file_data const & left_data,
73 file_data const & right_data,
74 file_data const & merged_data);
75
76 void record_file(file_id const & ident,
77 file_data const & data);
78
79 void record_file(file_id const & parent_ident,
80 file_id const & merged_ident,
81 file_data const & parent_data,
82 file_data const & merged_data);
83
84 void cache_roster(revision_id const & rid,
85 boost::shared_ptr<roster_t const> roster);
86
87 void get_ancestral_roster(node_id nid,
88 revision_id & rid,
89 boost::shared_ptr<roster_t const> & anc);
90
91 // Search parents of rev_id (which must be left_rid or right_rid); return
92 // rev, file_path, and file_id for nid just before it was dropped.
93 void get_dropped_details(revision_id & rev_id,
94 node_id nid,
95 revision_id & dropped_rev_id,
96 file_path & dropped_name,
97 file_id & dropped_file_id);
98
99 void get_version(file_id const & ident,
100 file_data & dat) const;
101};
102
103struct
104content_merge_workspace_adaptor
105 : public content_merge_adaptor
106{
107 std::map<file_id, file_data> temporary_store;
108 database & db;
109 revision_id const lca;
110 boost::shared_ptr<roster_t const> base;
111 marking_map const & left_mm;
112 marking_map const & right_mm;
113 std::map<revision_id, boost::shared_ptr<roster_t const> > rosters;
114 std::map<file_id, file_path> content_paths;
115 content_merge_workspace_adaptor(database & db,
116 revision_id const & lca,
117 boost::shared_ptr<roster_t const> base,
118 marking_map const & left_mm,
119 marking_map const & right_mm,
120 std::map<file_id, file_path> const & paths)
121 : db(db), lca(lca), base(base),
122 left_mm(left_mm), right_mm(right_mm), content_paths(paths)
123 {}
124
125 void cache_roster(revision_id const & rid,
126 boost::shared_ptr<roster_t const> roster);
127
128 void record_merge(file_id const & left_ident,
129 file_id const & right_ident,
130 file_id const & merged_ident,
131 file_data const & left_data,
132 file_data const & right_data,
133 file_data const & merged_data);
134
135 void record_file(file_id const & ident,
136 file_data const & data);
137
138 void record_file(file_id const & parent_ident,
139 file_id const & merged_ident,
140 file_data const & parent_data,
141 file_data const & merged_data);
142
143 void get_ancestral_roster(node_id nid,
144 revision_id & rid,
145 boost::shared_ptr<roster_t const> & anc);
146
147 void get_version(file_id const & ident,
148 file_data & dat) const;
149};
150
151struct
152content_merge_checkout_adaptor
153 : public content_merge_adaptor
154{
155 database & db;
156 content_merge_checkout_adaptor(database & db)
157 : db(db)
158 {}
159
160 void record_merge(file_id const & left_ident,
161 file_id const & right_ident,
162 file_id const & merged_ident,
163 file_data const & left_data,
164 file_data const & right_data,
165 file_data const & merged_data);
166
167 void record_file(file_id const & ident,
168 file_data const & data);
169
170 void record_file(file_id const & parent_ident,
171 file_id const & merged_ident,
172 file_data const & parent_data,
173 file_data const & merged_data);
174
175 void get_ancestral_roster(node_id nid,
176 revision_id & rid,
177 boost::shared_ptr<roster_t const> & anc);
178
179 void get_version(file_id const & ident,
180 file_data & dat) const;
181
182};
183
184
185struct
186content_merge_empty_adaptor
187 : public content_merge_adaptor
188{
189 void record_merge(file_id const & left_ident,
190 file_id const & right_ident,
191 file_id const & merged_ident,
192 file_data const & left_data,
193 file_data const & right_data,
194 file_data const & merged_data);
195
196 void record_file(file_id const & ident,
197 file_data const & data);
198
199 void record_file(file_id const & parent_ident,
200 file_id const & merged_ident,
201 file_data const & parent_data,
202 file_data const & merged_data);
203
204 void get_ancestral_roster(node_id nid,
205 revision_id & rid,
206 boost::shared_ptr<roster_t const> & anc);
207
208 void get_version(file_id const & ident,
209 file_data & dat) const;
210};
211
212struct content_merger
213{
214 lua_hooks & lua;
215 roster_t const & anc_ros;
216 roster_t const & left_ros;
217 roster_t const & right_ros;
218
219 content_merge_adaptor & adaptor;
220
221 content_merger(lua_hooks & lua,
222 roster_t const & anc_ros,
223 roster_t const & left_ros,
224 roster_t const & right_ros,
225 content_merge_adaptor & adaptor)
226 : lua(lua),
227 anc_ros(anc_ros),
228 left_ros(left_ros),
229 right_ros(right_ros),
230 adaptor(adaptor)
231 {}
232
233 // Attempt merge3 on a file (line by line). Return true and valid data if
234 // it would succeed; false and invalid data otherwise.
235 bool attempt_auto_merge(file_path const & anc_path, // inputs
236 file_path const & left_path,
237 file_path const & right_path,
238 file_id const & ancestor_id,
239 file_id const & left_id,
240 file_id const & right_id,
241 file_data & left_data, // outputs
242 file_data & right_data,
243 file_data & merge_data);
244
245 // Attempt merge3 on a file (line by line). If it succeeded, store results
246 // in database and return true and valid merged_id; return false
247 // otherwise.
248 bool try_auto_merge(file_path const & anc_path,
249 file_path const & left_path,
250 file_path const & right_path,
251 file_path const & merged_path,
252 file_id const & ancestor_id,
253 file_id const & left_id,
254 file_id const & right,
255 file_id & merged_id);
256
257 bool try_user_merge(file_path const & anc_path,
258 file_path const & left_path,
259 file_path const & right_path,
260 file_path const & merged_path,
261 file_id const & ancestor_id,
262 file_id const & left_id,
263 file_id const & right,
264 file_id & merged_id);
265
266 std::string get_file_encoding(file_path const & path,
267 roster_t const & ros);
268
269 bool attribute_manual_merge(file_path const & path,
270 roster_t const & ros);
271};
272
273
274// Destructively alter a roster_merge_result to attempt to remove any
275// conflicts in it. Takes a content_merge_adaptor to pass on to the content
276// merger; used from both the merge-to-database code (below) and the
277// merge-to-workspace "update" code in commands.cc.
278
279void
280resolve_merge_conflicts(lua_hooks & lua,
281 options const & opts,
282 roster_t const & left_roster,
283 roster_t const & right_roster,
284 roster_merge_result & result,
285 content_merge_adaptor & adaptor,
286 temp_node_id_source & nis,
287 bool const resolutions_given);
288
289// traditional resolve-all-conflicts-as-you-go style merging with 3-way merge
290// for file texts
291// throws if merge fails
292// writes out resulting revision to the db, along with author and date certs
293// (but _not_ branch or changelog certs)
294// this version can only be used to merge revisions that are in the db, and
295// that are written straight back out to the db; some refactoring would
296// probably be good
297// 'update' requires some slightly different interface, to deal with the gunk
298// around the revision and its files not being in the db, and the resulting
299// revision and its merged files not being written back to the db
300void
301interactive_merge_and_store(lua_hooks & lua,
302 database & db,
303 options const & opts,
304 revision_id const & left,
305 revision_id const & right,
306 revision_id & merged);
307
308void
309store_roster_merge_result(database & db,
310 roster_t const & left_roster,
311 roster_t const & right_roster,
312 roster_merge_result & result,
313 revision_id const & left_rid,
314 revision_id const & right_rid,
315 revision_id & merged_rid);
316
317// Do a three-way merge on file content, expressed as vectors of
318// strings (one per line).
319
320bool merge3(std::vector<std::string> const & ancestor,
321 std::vector<std::string> const & left,
322 std::vector<std::string> const & right,
323 std::vector<std::string> & merged);
324
325
326#endif
327
328// Local Variables:
329// mode: C++
330// fill-column: 76
331// c-file-style: "gnu"
332// indent-tabs-mode: nil
333// End:
334// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:

Archive Download this file

Branches

Tags

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