File: revision.hh

package info (click to toggle)
monotone 0.48-3
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 20,096 kB
  • ctags: 8,077
  • sloc: cpp: 81,000; sh: 6,402; perl: 1,241; lisp: 1,045; makefile: 655; python: 566; sql: 112; ansic: 52
file content (255 lines) | stat: -rw-r--r-- 7,510 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
// Copyright (C) 2004 Graydon Hoare <graydon@pobox.com>
//
// This program is made available under the GNU GPL version 2.0 or
// greater. See the accompanying file COPYING for details.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE.

#ifndef __REVISION_HH__
#define __REVISION_HH__

#include <set>
#include "vector.hh"
#include "rev_types.hh"

class key_store;
class node_restriction;
class path_restriction;

// a revision is a text object. It has a precise, normalizable serial form
// as UTF-8 text. it also has some sub-components. not all of these
// sub-components are separately serialized (they could be but there is no
// call for it). a grammar (aside from the parsing code) for the serialized
// form will show up here eventually. until then, here is an example.
//
// new_manifest [16afa28e8783987223993d67f54700f0ecfedfaa]
//
// old_revision [d023242b16cbdfd46686a5d217af14e3c339f2b4]
//
// delete "deleted-file.cc"
//
// rename "old-file.cc"
//     to "new-file.cc"
//
// add_file "added-file.cc"
//  content [da39a3ee5e6b4b0d3255bfef95601890afd80709]
//
// patch "changed-file.cc"
//  from [588fd8a7bcde43a46f0bde1dd1d13e9e77cf25a1]
//    to [559133b166c3154c864f912e9f9452bfc452dfdd]
//
// patch "new-file.cc"
//  from [95b50ede90037557fd0fbbfad6a9fdd67b0bf413]
//    to [bd39086b9da776fc22abd45734836e8afb59c8c0]

enum made_for { made_for_nobody, made_for_workspace, made_for_database };

struct
revision_t : public origin_aware
{
  void check_sane() const;
  bool is_merge_node() const;
  // trivial revisions are ones that have no effect -- e.g., commit should
  // refuse to commit them, saying that there are no changes to commit.
  bool is_nontrivial() const;
  revision_t() : made_for(made_for_nobody) {}
  revision_t(revision_t const & other);
  revision_t const & operator=(revision_t const & other);
  manifest_id new_manifest;
  edge_map edges;
  // workspace::put_work_rev refuses to apply a rev that doesn't have this
  // set to "workspace", and database::put_revision refuses to apply a rev
  // that doesn't have it set to "database".  the default constructor sets
  // it to "nobody".
  enum made_for made_for;
};

class graph_loader
{
 public:
  graph_loader(database & db) : db(db) {}

  void load_parents(revision_id const rid, std::set<revision_id> & parents);
  void load_children(revision_id const rid, std::set<revision_id> & children);
  void load_ancestors(std::set<revision_id> & revs);
  void load_descendants(std::set<revision_id> & revs);

 private:
  database & db;
  enum load_direction { ancestors, descendants };

  void load_revs(load_direction const direction,
                 std::set<revision_id> & revs);
};

inline revision_id const &
edge_old_revision(edge_entry const & e)
{
  return e.first;
}

inline revision_id const &
edge_old_revision(edge_map::const_iterator i)
{
  return i->first;
}

inline cset const &
edge_changes(edge_entry const & e)
{
  return *(e.second);
}

inline cset const &
edge_changes(edge_map::const_iterator i)
{
  return *(i->second);
}

template <> void
dump(revision_t const & rev, std::string & out);

void
read_revision(data const & dat,
              revision_t & rev);

void
read_revision(revision_data const & dat,
              revision_t & rev);

void
write_revision(revision_t const & rev,
               data & dat);

void
write_revision(revision_t const & rev,
               revision_data & dat);

void calculate_ident(revision_t const & cs,
                     revision_id & ident);

// sanity checking

void
find_common_ancestor_for_merge(database & db,
                               revision_id const & left,
                               revision_id const & right,
                               revision_id & anc);

bool
is_ancestor(database & db, revision_id const & ancestor,
            revision_id const & descendent);

void
toposort(database & db,
         std::set<revision_id> const & revisions,
         std::vector<revision_id> & sorted);

void
erase_ancestors(database & db, std::set<revision_id> & revisions);

struct is_failure
{
  virtual bool operator()(revision_id const & rid) = 0;
  virtual ~is_failure() {};
};
void
erase_ancestors_and_failures(database & db,
                             std::set<revision_id> & revisions,
                             is_failure & p,
                             std::multimap<revision_id, revision_id> *inverse_graph_cache_ptr = NULL);

void
ancestry_difference(database & db, revision_id const & a,
                    std::set<revision_id> const & bs,
                    std::set<revision_id> & new_stuff);


// FIXME: can probably optimize this passing a lookaside cache of the active
// frontier set of shared_ptr<roster_t>s, while traversing history.
void
select_nodes_modified_by_rev(database & db,
                             revision_t const & rev,
                             roster_t const roster,
                             std::set<node_id> & nodes_modified);

void
make_revision(revision_id const & old_rev_id,
              roster_t const & old_roster,
              roster_t const & new_roster,
              revision_t & rev);

void
make_revision(parent_map const & old_rosters,
              roster_t const & new_roster,
              revision_t & rev);

// This overload takes a base roster and a changeset instead.
void
make_revision(revision_id const & old_rev_id,
              roster_t const & old_roster,
              cset const & changes,
              revision_t & rev);

// These functions produce a faked "new_manifest" id and discard all
// content-only changes from the cset.  They are only to be used to
// construct a revision that will be written to the workspace.  Don't use
// them for revisions written to the database or presented to the user.
void
make_revision_for_workspace(revision_id const & old_rev_id,
                            cset const & changes,
                            revision_t & rev);

void
make_revision_for_workspace(revision_id const & old_rev_id,
                            roster_t const & old_roster,
                            roster_t const & new_roster,
                            revision_t & rev);

void
make_revision_for_workspace(parent_map const & old_rosters,
                            roster_t const & new_roster,
                            revision_t & rev);

void
make_restricted_revision(parent_map const & old_rosters,
                         roster_t const & new_roster,
                         node_restriction const & mask,
                         revision_t & rev);

void
make_restricted_revision(parent_map const & old_rosters,
                         roster_t const & new_roster,
                         node_restriction const & mask,
                         revision_t & rev,
                         cset & excluded,
                         utf8 const & cmd_name);

// basic_io access to printers and parsers
void
print_revision(basic_io::printer & printer,
               revision_t const & rev);

void
parse_revision(basic_io::parser & parser,
               revision_t & rev);

void
print_edge(basic_io::printer & printer,
           edge_entry const & e);

void
parse_edge(basic_io::parser & parser,
           edge_map & es);

#endif // __REVISION_HH__

// Local Variables:
// mode: C++
// fill-column: 76
// c-file-style: "gnu"
// indent-tabs-mode: nil
// End:
// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: