]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/subversion/subversion/libsvn_wc/README
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / subversion / subversion / libsvn_wc / README
1      Oh Most High and Fragrant Emacs, please be in -*- text -*- mode!
2
3 ##############################################################################
4 ### The vast majority of this file is completely out-of-date as a result   ###
5 ### of the ongoing work known as WC-NG.  Please consult that documentation ###
6 ### for a more relevant and complete reference.                            ###
7 ### (See the files in notes/wc-ng )                                        ###
8 ##############################################################################
9
10
11 This is the library described in the section "The working copy
12 management library" of svn-design.texi.  It performs local operations
13 in the working copy, tweaking administrative files and versioned data.
14 It does not communicate directly with a repository; instead, other
15 libraries that do talk to the repository call into this library to
16 make queries and changes in the working copy.
17
18 Note: This document attempts to describe (insofar as development is still
19 a moving target) the current working copy layout.  For historic layouts,
20 consulting the versioned history of this file (yay version control!)
21
22
23 The Problem We're Solving
24 -------------------------
25
26 The working copy is arranged as a directory tree, which, at checkout,
27 mirrors a tree rooted at some node in the repository.  Over time, the
28 working copy accumulates uncommitted changes, some of which may affect
29 its tree layout.  By commit time, the working copy's layout could be
30 arbitrarily different from the repository tree on which it was based.
31
32 Furthermore, updates/commits do not always involve the entire tree, so
33 it is possible for the working copy to go a very long time without
34 being a perfect mirror of some tree in the repository.
35
36
37 One Way We're Not Solving It
38 ----------------------------
39
40 Updates and commits are about merging two trees that share a common
41 ancestor, but have diverged since that ancestor.  In real life, one of
42 the trees comes from the working copy, the other from the repository.
43 But when thinking about how to merge two such trees, we can ignore the
44 question of which is the working copy and which is the repository,
45 because the principles involved are symmetrical.
46
47 Why do we say symmetrical?
48
49 It's tempting to think of a change as being either "from" the working
50 copy or "in" the repository.  But the true source of a change is some
51 committer -- each change represents some developer's intention toward
52 a file or a tree, and a conflict is what happens when two intentions
53 are incompatible (or their compatibility cannot be automatically
54 determined).
55
56 It doesn't matter in what order the intentions were discovered --
57 which has already made it into the repository versus which exists only
58 in someone's working copy.  Incompatibility is incompatibility,
59 independent of timing.
60
61 In fact, a working copy can be viewed as a "branch" off the
62 repository, and the changes committed in the repository *since* then
63 represent another, divergent branch.  Thus, every update or commit is
64 a general branch-merge problem:
65
66    - An update is an attempt to merge the repository's branch into the
67      working copy's branch, and the attempt may fail wholly or
68      partially depending on the number of conflicts.
69
70    - A commit is an attempt to merge the working copy's branch into
71      the repository.  The exact same algorithm is used as with
72      updates, the only difference being that a commit must succeed
73      completely or not at all.  That last condition is merely a
74      usability decision: the repository tree is shared by many
75      people, so folding both sides of a conflict into it to aid
76      resolution would actually make it less usable, not more.  On the
77      other hand, representing both sides of a conflict in a working
78      copy is often helpful to the person who owns that copy.
79
80 So below we consider the general problem of how to merge two trees
81 that have a common ancestor.  The concrete tree layout discussed will
82 be that of the working copy, because this library needs to know
83 exactly how to massage a working copy from one state to another.
84
85
86 Structure of the Working Copy
87 -----------------------------
88
89 Working copy meta-information is stored in a single .svn/ subdirectory, in
90 the root of a given working copy.  For the purposes of storage, directories
91 pull in through the use of svn:externals are considered separate working
92 copies.
93
94   .svn/wc.db                    /* SQLite database containing node metadata. */
95        pristine/                /* Sharded directory containing base files. */
96        tmp/                     /* Local tmp area. */
97
98 `wc.db':
99    A self-contained SQLite database containing all the metadata Subversion
100    needs to track for this working copy.  The schema is described by
101    libsvn_wc/wc-metadata.sql.
102
103 `pristine':
104    Each file in the working copy has a corresponding unmodified version in
105    the .svn/pristine subdirectory.  This files are stored by the SHA-1
106    hash of their contents, sharded into 256 subdirectories based upon the
107    first two characters of the hex expansion of the hash.  In this way,
108    multiple identical files can share the same pristine representation.
109
110    Pristines are used for sending diffs back to the server, etc.
111
112
113 How the client applies an update delta
114 --------------------------------------
115
116 Updating is more than just bringing changes down from the repository;
117 it's also folding those changes into the working copy.  Getting the
118 right changes is the easy part -- folding them in is hard.
119
120 Before we examine how Subversion handles this, let's look at what CVS
121 does:
122
123    1. Unmodified portions of the working copy are simply brought
124       up-to-date.  The server sends a forward diff, the client applies
125       it.
126
127    2. Locally modified portions are "merged", where possible.  That
128       is, the changes from the repository are incorporated into the
129       local changes in an intelligent way (if the diff application
130       succeeds, then no conflict, else go to 3...)
131
132    3. Where merging is not possible, a conflict is flagged, and *both*
133       sides of the conflict are folded into the local file in such a
134       way that it's easy for the developer to figure out what
135       happened.  (And the old locally-modified file is saved under a
136       temp name, just in case.)
137
138 It would be nice for Subversion to do things this way too;
139 unfortunately, that's not possible in every case.
140
141 CVS has a wonderfully simplifying limitation: it doesn't version
142 directories, so never has tree-structure conflicts.  Given that only
143 textual conflicts are possible, there is usually a natural way to
144 express both sides of a conflict -- just include the opposing texts
145 inside the file, delimited with conflict markers.  (Or for binary
146 files, make both revisions available under temporary names.)
147
148 While Subversion can behave the same way for textual conflicts, the
149 situation is more complex for trees.  There is sometimes no way for a
150 working copy to reflect both sides of a tree conflict without being
151 more confusing than helpful.  How does one put "conflict markers" into
152 a directory, especially when what was a directory might now be a file,
153 or vice-versa?
154
155 Therefore, while Subversion does everything it can to fold conflicts
156 intelligently (doing at least as well as CVS does), in extreme cases
157 it is acceptable for the Subversion client to punt, saying in effect
158 "Your working copy is too out of whack; please move it aside, check
159 out a fresh one, redo your changes in the fresh copy, and commit from
160 that."  (This response may also apply to subtrees of the working copy,
161 of course).
162
163 Usually it offers more detail than that, too.  In addition to the
164 overall out-of-whackness message, it can say "Directory foo was
165 renamed to bar, conflicting with your new file bar; file blah was
166 deleted, conflicting with your local change to file blah, ..." and so
167 on.  The important thing is that these are informational only -- they
168 tell the user what's wrong, but they don't try to fix it
169 automatically.
170
171 All this is purely a matter of *client-side* intelligence.  Nothing in
172 the repository logic or protocol affects the client's ability to fold
173 conflicts.  So as we get smarter, and/or as there is demand for more
174 informative conflicting updates, the client's behavior can improve and
175 punting can become a rare event.  We should start out with a _simple_
176 conflict-folding algorithm initially, though.
177
178
179 Text and Property Components
180 ----------------------------
181
182 A Subversion working copy keeps track of *two* forks per file, much
183 like the way MacOS files have "data" forks and "resource" forks.  Each
184 file under revision control has its "text" and "properties" tracked
185 with different timestamps and different conflict (reject) files.  In
186 this vein, each file's status-line has two columns which describe the
187 file's state.
188
189 Examples:
190
191   --  glub.c      --> glub.c is completely up-to-date.
192   U-  foo.c       --> foo.c's textual component was updated.
193   -M  bar.c       --> bar.c's properties have been locally modified
194   UC  baz.c       --> baz.c has had both components patched, but a
195                       local property change is creating a conflict.