1251881Speter     Oh Most High and Fragrant Emacs, please be in -*- text -*- mode!
2251881Speter
3251881Speter##############################################################################
4251881Speter### The vast majority of this file is completely out-of-date as a result   ###
5251881Speter### of the ongoing work known as WC-NG.  Please consult that documentation ###
6251881Speter### for a more relevant and complete reference.                            ###
7251881Speter### (See the files in notes/wc-ng )                                        ###
8251881Speter##############################################################################
9251881Speter
10251881Speter
11251881SpeterThis is the library described in the section "The working copy
12251881Spetermanagement library" of svn-design.texi.  It performs local operations
13251881Speterin the working copy, tweaking administrative files and versioned data.
14251881SpeterIt does not communicate directly with a repository; instead, other
15251881Speterlibraries that do talk to the repository call into this library to
16251881Spetermake queries and changes in the working copy.
17251881Speter
18251881SpeterNote: This document attempts to describe (insofar as development is still
19251881Spetera moving target) the current working copy layout.  For historic layouts,
20251881Speterconsulting the versioned history of this file (yay version control!)
21251881Speter
22251881Speter
23251881SpeterThe Problem We're Solving
24251881Speter-------------------------
25251881Speter
26251881SpeterThe working copy is arranged as a directory tree, which, at checkout,
27251881Spetermirrors a tree rooted at some node in the repository.  Over time, the
28251881Speterworking copy accumulates uncommitted changes, some of which may affect
29251881Speterits tree layout.  By commit time, the working copy's layout could be
30251881Speterarbitrarily different from the repository tree on which it was based.
31251881Speter
32251881SpeterFurthermore, updates/commits do not always involve the entire tree, so
33251881Speterit is possible for the working copy to go a very long time without
34251881Speterbeing a perfect mirror of some tree in the repository.
35251881Speter
36251881Speter
37251881SpeterOne Way We're Not Solving It
38251881Speter----------------------------
39251881Speter
40251881SpeterUpdates and commits are about merging two trees that share a common
41251881Speterancestor, but have diverged since that ancestor.  In real life, one of
42251881Speterthe trees comes from the working copy, the other from the repository.
43251881SpeterBut when thinking about how to merge two such trees, we can ignore the
44251881Speterquestion of which is the working copy and which is the repository,
45251881Speterbecause the principles involved are symmetrical.
46251881Speter
47251881SpeterWhy do we say symmetrical?
48251881Speter
49251881SpeterIt's tempting to think of a change as being either "from" the working
50251881Spetercopy or "in" the repository.  But the true source of a change is some
51251881Spetercommitter -- each change represents some developer's intention toward
52251881Spetera file or a tree, and a conflict is what happens when two intentions
53251881Speterare incompatible (or their compatibility cannot be automatically
54251881Speterdetermined).
55251881Speter
56251881SpeterIt doesn't matter in what order the intentions were discovered --
57251881Speterwhich has already made it into the repository versus which exists only
58251881Speterin someone's working copy.  Incompatibility is incompatibility,
59251881Speterindependent of timing.
60251881Speter
61251881SpeterIn fact, a working copy can be viewed as a "branch" off the
62251881Speterrepository, and the changes committed in the repository *since* then
63251881Speterrepresent another, divergent branch.  Thus, every update or commit is
64251881Spetera general branch-merge problem:
65251881Speter
66251881Speter   - An update is an attempt to merge the repository's branch into the
67251881Speter     working copy's branch, and the attempt may fail wholly or
68251881Speter     partially depending on the number of conflicts.
69251881Speter
70251881Speter   - A commit is an attempt to merge the working copy's branch into
71251881Speter     the repository.  The exact same algorithm is used as with
72251881Speter     updates, the only difference being that a commit must succeed
73251881Speter     completely or not at all.  That last condition is merely a
74251881Speter     usability decision: the repository tree is shared by many
75251881Speter     people, so folding both sides of a conflict into it to aid
76251881Speter     resolution would actually make it less usable, not more.  On the
77251881Speter     other hand, representing both sides of a conflict in a working
78251881Speter     copy is often helpful to the person who owns that copy.
79251881Speter
80251881SpeterSo below we consider the general problem of how to merge two trees
81251881Speterthat have a common ancestor.  The concrete tree layout discussed will
82251881Speterbe that of the working copy, because this library needs to know
83251881Speterexactly how to massage a working copy from one state to another.
84251881Speter
85251881Speter
86251881SpeterStructure of the Working Copy
87251881Speter-----------------------------
88251881Speter
89251881SpeterWorking copy meta-information is stored in a single .svn/ subdirectory, in
90251881Speterthe root of a given working copy.  For the purposes of storage, directories
91251881Speterpull in through the use of svn:externals are considered separate working
92251881Spetercopies.
93251881Speter
94251881Speter  .svn/wc.db                    /* SQLite database containing node metadata. */
95251881Speter       pristine/                /* Sharded directory containing base files. */
96251881Speter       tmp/                     /* Local tmp area. */
97362181Sdim       experimental/            /* Data for experimental features. */
98362181Sdim       shelves/                 /* Used by 1.10.x shelves implementation */
99362181Sdim       entries                  /* Stub file. */
100362181Sdim       format                   /* Stub file. */
101251881Speter
102251881Speter`wc.db':
103251881Speter   A self-contained SQLite database containing all the metadata Subversion
104251881Speter   needs to track for this working copy.  The schema is described by
105251881Speter   libsvn_wc/wc-metadata.sql.
106251881Speter
107251881Speter`pristine':
108251881Speter   Each file in the working copy has a corresponding unmodified version in
109251881Speter   the .svn/pristine subdirectory.  This files are stored by the SHA-1
110251881Speter   hash of their contents, sharded into 256 subdirectories based upon the
111251881Speter   first two characters of the hex expansion of the hash.  In this way,
112251881Speter   multiple identical files can share the same pristine representation.
113251881Speter
114251881Speter   Pristines are used for sending diffs back to the server, etc.
115251881Speter
116362181Sdim`experimental':
117362181Sdim   Experimental (unstable) features store their data here.
118251881Speter
119362181Sdim`shelves':
120362181Sdim   Subversion 1.10's "svn shelve" command stores shelved changes here.
121362181Sdim   This directory is not used by any other minor release line.
122362181Sdim
123362181Sdim`entries', `format':
124362181Sdim   These stub files exist only to enable a pre-1.7 client to yield a clearer
125362181Sdim   error message.
126362181Sdim
127362181Sdim
128251881SpeterHow the client applies an update delta
129251881Speter--------------------------------------
130251881Speter
131251881SpeterUpdating is more than just bringing changes down from the repository;
132251881Speterit's also folding those changes into the working copy.  Getting the
133251881Speterright changes is the easy part -- folding them in is hard.
134251881Speter
135251881SpeterBefore we examine how Subversion handles this, let's look at what CVS
136251881Speterdoes:
137251881Speter
138251881Speter   1. Unmodified portions of the working copy are simply brought
139251881Speter      up-to-date.  The server sends a forward diff, the client applies
140251881Speter      it.
141251881Speter
142251881Speter   2. Locally modified portions are "merged", where possible.  That
143251881Speter      is, the changes from the repository are incorporated into the
144251881Speter      local changes in an intelligent way (if the diff application
145251881Speter      succeeds, then no conflict, else go to 3...)
146251881Speter
147251881Speter   3. Where merging is not possible, a conflict is flagged, and *both*
148251881Speter      sides of the conflict are folded into the local file in such a
149251881Speter      way that it's easy for the developer to figure out what
150251881Speter      happened.  (And the old locally-modified file is saved under a
151251881Speter      temp name, just in case.)
152251881Speter
153251881SpeterIt would be nice for Subversion to do things this way too;
154251881Speterunfortunately, that's not possible in every case.
155251881Speter
156251881SpeterCVS has a wonderfully simplifying limitation: it doesn't version
157251881Speterdirectories, so never has tree-structure conflicts.  Given that only
158251881Spetertextual conflicts are possible, there is usually a natural way to
159251881Speterexpress both sides of a conflict -- just include the opposing texts
160251881Speterinside the file, delimited with conflict markers.  (Or for binary
161251881Speterfiles, make both revisions available under temporary names.)
162251881Speter
163251881SpeterWhile Subversion can behave the same way for textual conflicts, the
164251881Spetersituation is more complex for trees.  There is sometimes no way for a
165251881Speterworking copy to reflect both sides of a tree conflict without being
166251881Spetermore confusing than helpful.  How does one put "conflict markers" into
167251881Spetera directory, especially when what was a directory might now be a file,
168251881Speteror vice-versa?
169251881Speter
170251881SpeterTherefore, while Subversion does everything it can to fold conflicts
171251881Speterintelligently (doing at least as well as CVS does), in extreme cases
172251881Speterit is acceptable for the Subversion client to punt, saying in effect
173251881Speter"Your working copy is too out of whack; please move it aside, check
174251881Speterout a fresh one, redo your changes in the fresh copy, and commit from
175251881Speterthat."  (This response may also apply to subtrees of the working copy,
176251881Speterof course).
177251881Speter
178251881SpeterUsually it offers more detail than that, too.  In addition to the
179251881Speteroverall out-of-whackness message, it can say "Directory foo was
180251881Speterrenamed to bar, conflicting with your new file bar; file blah was
181251881Speterdeleted, conflicting with your local change to file blah, ..." and so
182251881Speteron.  The important thing is that these are informational only -- they
183251881Spetertell the user what's wrong, but they don't try to fix it
184251881Speterautomatically.
185251881Speter
186251881SpeterAll this is purely a matter of *client-side* intelligence.  Nothing in
187251881Speterthe repository logic or protocol affects the client's ability to fold
188251881Speterconflicts.  So as we get smarter, and/or as there is demand for more
189251881Speterinformative conflicting updates, the client's behavior can improve and
190251881Speterpunting can become a rare event.  We should start out with a _simple_
191251881Speterconflict-folding algorithm initially, though.
192251881Speter
193251881Speter
194251881SpeterText and Property Components
195251881Speter----------------------------
196251881Speter
197251881SpeterA Subversion working copy keeps track of *two* forks per file, much
198251881Speterlike the way MacOS files have "data" forks and "resource" forks.  Each
199251881Speterfile under revision control has its "text" and "properties" tracked
200251881Speterwith different timestamps and different conflict (reject) files.  In
201251881Speterthis vein, each file's status-line has two columns which describe the
202251881Speterfile's state.
203251881Speter
204251881SpeterExamples:
205251881Speter
206251881Speter  --  glub.c      --> glub.c is completely up-to-date.
207251881Speter  U-  foo.c       --> foo.c's textual component was updated.
208251881Speter  -M  bar.c       --> bar.c's properties have been locally modified
209251881Speter  UC  baz.c       --> baz.c has had both components patched, but a
210251881Speter                      local property change is creating a conflict.
211