monotone

monotone Mtn Source Tree

Root/work.hh

1#ifndef __WORK_HH__
2#define __WORK_HH__
3
4// Copyright (C) 2002 Graydon Hoare <graydon@pobox.com>
5//
6// This program is made available under the GNU GPL version 2.0 or
7// greater. See the accompanying file COPYING for details.
8//
9// This program is distributed WITHOUT ANY WARRANTY; without even the
10// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11// PURPOSE.
12
13#include <set>
14#include "paths.hh"
15#include "rev_types.hh"
16
17class path_restriction;
18class node_restriction;
19struct content_merge_adaptor;
20class lua_hooks;
21class i18n_format;
22struct options;
23class app_state;
24
25//
26// this file defines structures to deal with the "workspace" of a tree
27//
28// at present the presence or absence of a workspace is intrinsically global
29// state, because it affects things like file_path construction (over in
30// paths.cc) and the current working directory. also, there are a bunch of
31// operations, mostly during program initialization, that are conditional on
32// whether or not we are inside a workspace. this has two visible
33// consequences to this api: first, you cannot create more than one
34// workspace object, and second, the workspace class has many class methods
35// as well as many instance methods. class methods can be used when you're
36// not sure yet whether or not there is a workspace. instance methods can
37// only be used if there definitely is a workspace; the workspace object
38// constructor will throw an N() if there isn't one. (this can also be
39// triggered by the class method require_workspace, for the sake of a few
40// places that need to do that but not create the workspace object yet.)
41//
42
43//
44// workspace book-keeping files are stored in a directory called _MTN, off
45// the root of the workspace source tree (analogous to the CVS or .svn
46// directories). there is no hierarchy of _MTN directories; only one exists,
47// and it is always at the root. it contains the following files:
48//
49
50// _MTN/revision -- this file can be thought of as an approximation to the
51// revision that would be added to the database if one
52// were to execute 'mtn commit' with the current set of
53// changes. it records the id of the revision that was
54// checked out (the "parent revision") plus a cset
55// describing pathname and attribute modifications
56// relative to that revision. if the workspace is the
57// result of a merge, the revision will have more than
58// one parent and thus more than one cset. files
59// changed solely in content do not appear in
60// _MTN/revision; this is the major difference between
61// the revision in this file and the revision that 'mtn
62// commit' adds to the database.
63// _MTN/options -- the database, branch and key options currently in use
64// _MTN/log -- user edited log file
65// _MTN/inodeprints -- file fingerprint cache, see below
66//
67// as work proceeds, the files in the workspace either change their
68// sha1 fingerprints from those listed in the revision's manifest, or else are
69// added or deleted or renamed (and the paths of those changes recorded in
70// '_MTN/revision').
71//
72// many operations need to work with a revision that accurately describes
73// both pathname and content changes. constructing this revision is the
74// function of update_current_roster_from_filesystem(). this operation
75// intrinsically requires reading every file in the workspace, which can be
76// slow. _MTN/inodeprints, if present, is used to speed up this process; it
77// records information accessible via stat() that is expected to change
78// whenever a file is modified. this expectation is not true under all
79// conditions, but works in practice (it is, for instance, the same
80// expectation used by "make"). nonetheless, this mode is off by default.
81
82bool directory_is_workspace(system_path const & dir);
83
84struct workspace
85{
86 // This is a public flag because it's set from monotone.cc using a
87 // function (find_and_go_to_workspace) which cannot presently be moved
88 // from paths.cc.
89 static bool found;
90
91private:
92 // This is used by get_ws_options and set_ws_options.
93 static bool branch_is_sticky;
94
95 // This is used by a lot of instance methods.
96 lua_hooks & lua;
97
98 // Interfaces.
99public:
100 static void require_workspace();
101 static void require_workspace(i18n_format const & explanation);
102
103 static void create_workspace(options const & opts,
104 lua_hooks & lua,
105 system_path const & new_dir);
106
107 // Constructor. In normal usage, calling this transitions from the state
108 // where there may or may not be a workspace to the state where there
109 // definitely is.
110 explicit workspace(app_state & app, bool writeback_options = true);
111 explicit workspace(app_state & app, i18n_format const & explanation,
112 bool writeback_options = true);
113 explicit workspace(options const & opts, lua_hooks & lua,
114 i18n_format const & explanation, bool writeback_options = true);
115
116 // Methods for manipulating the workspace's content.
117 void find_missing(roster_t const & new_roster_shape,
118 node_restriction const & mask,
119 std::set<file_path> & missing);
120
121 void find_unknown_and_ignored(database & db,
122 path_restriction const & mask,
123 std::vector<file_path> const & roots,
124 std::set<file_path> & unknown,
125 std::set<file_path> & ignored);
126
127 void perform_additions(database & db,
128 std::set<file_path> const & targets,
129 bool recursive = false,
130 bool respect_ignore = true);
131
132 void perform_deletions(database & db,
133 std::set<file_path> const & targets,
134 bool recursive,
135 bool bookkeep_only);
136
137 void perform_rename(database & db,
138 std::set<file_path> const & src_paths,
139 file_path const & dst_dir,
140 bool bookkeep_only);
141
142 void perform_pivot_root(database & db,
143 file_path const & new_root,
144 file_path const & put_old,
145 bool bookkeep_only);
146
147 void perform_content_update(database & db,
148 cset const & cs,
149 content_merge_adaptor const & ca,
150 bool messages = true);
151
152 void update_any_attrs(database & db);
153 void init_attributes(file_path const & path, editable_roster_base & er);
154
155 bool has_changes(database & db);
156
157 // write out a new (partial) revision describing the current workspace;
158 // the important pieces of this are the base revision id and the "shape"
159 // changeset (representing tree rearrangements).
160 void put_work_rev(revision_t const & rev);
161
162 // read the (partial) revision describing the current workspace.
163 void get_work_rev(revision_t & rev);
164
165 // convenience wrappers around the above functions.
166
167 // This returns the current roster, except it does not bother updating the
168 // hashes in that roster -- the "shape" is correct, all files and dirs
169 // exist and under the correct names -- but do not trust file content
170 // hashes. If you need the current roster with correct file content
171 // hashes, call update_current_roster_from_filesystem on the result of
172 // this function. Under almost all conditions, NIS should be a
173 // temp_node_id_source.
174 void get_current_roster_shape(database & db, node_id_source & nis,
175 roster_t & ros);
176
177 // This returns a map whose keys are revision_ids and whose values are
178 // rosters, there being one such pair for each parent of the current
179 // revision.
180 void get_parent_rosters(database & db, parent_map & parents);
181
182 // This updates the file-content hashes in ROSTER, which is assumed to be
183 // the "current" roster returned by one of the above get_*_roster_shape
184 // functions. If a node_restriction is provided, only the files matching
185 // the restriction have their hashes updated.
186 void update_current_roster_from_filesystem(roster_t & ros);
187 void update_current_roster_from_filesystem(roster_t & ros,
188 node_restriction const & mask);
189
190
191 // the "user log" is a file the user can edit as they program to record
192 // changes they make to their source code. Upon commit the file is read
193 // and passed to the edit_comment lua hook. If the commit is a success,
194 // the user log is then blanked. If the commit does not succeed, no
195 // change is made to the user log file.
196
197 void read_user_log(utf8 & dat);
198 void write_user_log(utf8 const & dat);
199 void blank_user_log();
200 bool has_contents_user_log();
201
202 // the "options map" is another administrative file, stored in
203 // _MTN/options. it keeps a list of name/value pairs which are considered
204 // "persistent options", associated with a particular workspace and
205 // implied unless overridden on the command line.
206 static void get_ws_options(options & opts);
207 static void get_database_option(system_path const & workspace_root,
208 system_path & database_option);
209 static void set_ws_options(options const & opts, bool branch_is_sticky);
210 static void print_ws_option(utf8 const & opt, std::ostream & output);
211
212 // the "workspace format version" is a nonnegative integer value, stored
213 // in _MTN/format as an unadorned decimal number. at any given time
214 // monotone supports actual use of only one workspace format.
215 // check_ws_format throws an error if the workspace exists but its format
216 // number is not equal to the currently supported format number. it is
217 // automatically called for all commands defined with CMD() (not
218 // CMD_NO_WORKSPACE()). migrate_ws_format is called only on explicit user
219 // request (mtn ws migrate) and will convert a workspace from any older
220 // format to the new one. finally, write_ws_format is called only when a
221 // workspace is created, and simply writes the current workspace format
222 // number to _MTN/format. unlike most routines in this class, these
223 // functions are defined in their own file, work_migration.cc.
224 static void check_ws_format();
225 static void write_ws_format();
226 void migrate_ws_format();
227
228 // the "local dump file' is a debugging file, stored in _MTN/debug. if we
229 // crash, we save some debugging information here.
230
231 static void get_local_dump_path(bookkeeping_path & d_path);
232
233 // the 'inodeprints file' contains inode fingerprints
234
235 bool in_inodeprints_mode();
236 void read_inodeprints(data & dat);
237 void write_inodeprints(data const & dat);
238
239 void enable_inodeprints();
240 void maybe_update_inodeprints(database &);
241
242 // the 'ignore file', .mtn-ignore in the root of the workspace, contains a
243 // set of regular expressions that match pathnames. any file or directory
244 // that exists, is unknown, and matches one of these regexps is treated as
245 // if it did not exist, instead of being an unknown file.
246 bool ignore_file(file_path const & path);
247};
248
249// Local Variables:
250// mode: C++
251// fill-column: 76
252// c-file-style: "gnu"
253// indent-tabs-mode: nil
254// End:
255// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
256
257#endif // __WORK_HH__
258

Archive Download this file

Branches

Tags

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