Edmund <edm...@belfordhk.com> writes: > +* High-level semantics we are trying to achieve: > + > + - Whenever Subversion puts or modifies a file (or directory) in > + the WC, it shall set the node's mtime in the WC to the mtime > + recorded for that node as given by the server. It also saves > + the mtime to a different 'read-only' property, say 'svn:origmtime'. > + Furthermore, to allow users to keep track of file/directory > + information, a few other -mtime properties can be included: > + > + * 'svn:addmtime' for Add > + * 'svn:commtime' for Commit > + * 'svn:impmtime' for Import
Those names are horrible; if we were to adopt this we should use names like svn:commit-time. > + > + - Whenever Subversion modifies a file (or directory) in the WC, and > + there are local changes to that node, such as when updating a file > + that the user has been editing, it shall leave the 'read-only' > + property 'svn:origmtime' as is and update the mtime property and > + depending on the function used, the additional -mtime properties > + are also set. Attempting to make properties read-only on the client is going to be tricky, because you can't control all the clients. If some other client changes svn:origmtime are you really going to ignore that change? If you use a client that does this it means that checking out rN and updating to rN+1 might not be the same as checking out rN+1. A read-only property is likely to need server-side support. > + > + - In order to lessen property hash corruptions, it would be > + preferential if aside for the 'svn:mtime' property, all other > + proposed properties cannot be set by 'pset' but can be retrieved > + by 'pget'. > + > + - The user can control the modification of the mtime property > + by the use of pset; but, cannot change 'svn:origmtime' or the > + other additional proposed properties. Again, that's only going to work for the clients you control. > + > + - Backward compatibility issues: > + > + o If the mtime/origmtime property hasn't been set for a node > + (most probably because it was stored in the repository > + prior to this feature being implemented), the mtime/origtime > + can be set to the current date of modification. > + > + > +* Specification of the behaviour in all the cases: > + > +Data Storage: > + > + Mtime shall be stored in a versioned property named 'svn:mtime'. > + The original mtime shall be stored in a read-only property > + named 'svn:origmtime'. Any file or directory may have this > + property. The format of the property value is 'YYYY-MM-DD HH:MM:SS' > + of which the time is UTC. So filesystems that support sub-second timestamps are not supported? A standard Ubuntu 9.10 installation uses ext4 with sub-second timestamps. > + > +Behaviour of Each Action: > + > + The behaviour of each svn action that may affect a node in the > + WC, is for x where x is a member of {file, dir}: > + > + CT = current time > + M(x) = mtime of x > + A(x) = initial mtime of Add 'svn:addmtime' > + I(x) = initial mtime of Import 'svn:impmtime' > + C(x) = recorded mtime of Commit 'svn:commtime' > + R(x) = recorded current mtime 'svn:mtime' > + S(x) = recorded original mtime 'svn:origmtime' > + G(x) = recorded mtime of merge 'svn:mrgmtime' > + > + All initial values prior to the actions are set to NULL and it is > + assumed that all the following functions are done with all the > + necessary checking, such that as an example, after doing a > + 'svn add', svn will complain if the user repeats the command. > + > + - add > + Let f_add(x) be the following process: > + 1) if x is already versioned, exit. > + 2) Get M(x) > + 3) Set A(x) = M(x) > + 4) Set S(x) = M(x) > + 5) Set R(x) = M(x) > + 6) Save A(x), S(x), and R(x) to property hash. > + > + o if x = file, then f_add(x) > + o if x = dir, then recursively f_add(x) > + > + > + - import > + Let f_import(x) be the following process: > + 1) if x is already versioned, exit. > + 2) Get M(x) > + 3) Set I(x) = M(x) > + 4) Set R(x) = M(x) > + 5) Set S(x) = M(x) > + 6) Save I(x), R(x), and S(x) to property hash. > + > + o if x = file, then f_import(x). > + o if x = dir, then recurisvely f_import(x) > + > + - commit > + Let f_commit(x) be the following process: > + 1) Get M(x) > + 2) Set C(x) = M(x) > + 3) R(x) = M(x) > + 4) Is S(x) == NULL? > + Yes: Previous committed action did not > + save S(x). Set it now. S(x) = M(x) > + No: Ignore S(x) value. > + 5) Save all other 'svn:*mtime' properties. > + > + o if x = file, then f_commit(x). > + o if x = dir, then recurisvely f_commit(x) > + > + - export > + Let f_export(x) be the following process: > + 1) Get S(x) > + 2) Is S(x) == NULL? > + Yes: Set the current M(x) as the file's > + mod time. > + No: Set M(x) = S(x) > + > + > + o if x = file, then f_export(x). > + o if x = dir, then recurisvely f_export(x) > + > + > + - checkout > + Let f_checkout(x) be the following process: > + 1) Get current time, CT > + 2) Is S(x) == NULL, > + Yes: 'svn:*mtime' properties were not set > + for x; therefore, > + 1.1) set S(x) = CT You plan to store property modifications during checkout? Do those modifications show up in 'svn st'? Can they be committed? > + 1.2) set M(x) = CT > + No: set M(x) = S(x) > + > + o if x = file, then f_checkout(x). > + o if x = dir, then recurisvely f_checkout(x) If you do support ext4 sub-second timestamps what happens when I checkout on my ext3 machine which cannot represent those timestamps? > + > + - update/switch that brings in a change > + Let f_update_switch(x) be the following process: > + 1) Get current time, CT > + 2) Is S(x) == NULL, > + Yes: 'svn:*mtime' properties were not set > + for x; therefore, > + 1.1) set S(x) = CT > + 1.2) set M(x) = CT > + No: set M(x) = C(x) > + > + o if x = file, then f_update_switch(x). > + o if x = dir, then recurisvely f_update_switch(x) > + > + - update/switch that brings in NO change > + Since nothing was changed, the mtime theoretically should > + remain the same, even with local changes. It is the mtime > + of these local changes that should remain the same. > + > + - merge > + This action is a bit more involved as there are a few > + situations that arise from the merge. Let x be a member > + of {file, dir}. Assume the following conditions are checked > + _after_ the merge. > + > + 1) If x was locally changed with no conflicts, then set > + G(x) = R(x). Then when the local changes are saved, > + the M(x) is once again changed which then requires a > + f_commit(x). > + > + 2) If x was locally changed with conflicts, then another > + set of conditions are checked: > + > + If to resolve conflicts, > + 2a) 'theirs-full' is used then M(x) = G(x). > + 2b) 'mine-full' is used, then G(x) = M(x). > + 2c) manual conflict resolution is needed, then > + to simplify the process, R(x) = M(x). > + > + 3) If x was not locally changed, then G(x) = R(x). Does the user have to resolve svn:*time property conflicts manually? Does this happen automatically? Does this mean that a user with a non-svn:*mtime aware client cannot easily run merge? > + > + - revert > + 1) if no local changes, then ignore command. > + 2) if R(x) == NULL, then set R(x) = M(x). So there are property modifications *after* revert? Do those modifications show up in 'svn st'? Can they be committed? > + 3) if R(x) != NULL, then set M(x) = R(x). > + > + - rename > + i.e. svn rename x y > + > + 1) if R(x) != NULL and S(x) != NULL, then delete > + both R(x) and S(x). > + 2) Set A(y) = M(y), R(y) = M(y), S(y) = M(y). > + > + If there was just the 'svn:mtime' property to keep track of > + modification times, then allowing the user to change the > + 'svn:mtime' property would be discouraged. A definitive caveat. > + However, with the different svn:*mtime properties, allowing > + the user to change the 'svn:mtime' would not be problematic; > + it would just give the user the ability to enter into a property > + conflict state to which property conflict resolution procedures are > + applied. > + > + If none of the 'svn:*mtime' properties exist for a file or > + directory, it means either it (file or directory) is not > + versioned, or it existed in the repository and WC before > + this feature was created. Since the original information > + pertaining to the file/directory is lost, the options are > + either to store the current mtime as the original mtime > + or completely ignore the 'svn:*mtime' properties for this > + file. This functional specification takes the tact of > + setting the 'svn:*mtime' to the current mtime as it will > + give the user at least a starting point to which to make > + their statistical/informational mtime references. > + > + With the different mtime representations due to the different > + platforms and locales Subversion runs on, it gets tricky in having > + a unified mtime representation. An example of such difficulty > + is in which the same mtime value may be represented by different > + formats could indeed make an unmodified file/directory be mis- > + construed as being modified. In order to avoid this issue, > + perhaps some conditional platform-specific functions can change > + the local value to the unified value with which Subversion can > + store it in the 'svn:*mtime' properties. > + > + > +* Controlling the behaviour: > + > + To control the behaviour there are two options that can be used. > + > + 1) Use a client-side configuration file. > + > + 2) A set of client-side configuration options. > + > + > + Since we are dealing with properties, then any command that > + deals with properties also apply to the 'svn:*mtime' properties > + with the additional ones that control the read/write of these > + new properties. > + > + For instance, the user wanting to set the 'svn:mtime' for an > + already versioned file which has none of the 'svn:*mtime' properties > + set. > + > + svn pset svn:mtime '11-11-2009 12:22:00' foo.txt > + > + Whereas: > + > + svn pset svn:addmtime '11-11-2009 12:22:00' foo.txt > + > + will return an error: "svn:addmtime is a read-only property" > + > + "How does it interact with the "use-commit-times" option?" > + > + With this option, use-commit-times will override all > + Subversion conditions as mentioned above. > + > + > +* Concerns > + > +The original issue called for just a single property to > +keep track of the mtime. However, with a single mtime > +reference, it would be overwritten anytime the repository > +copy is updated in any way. This will most likely lead > +to complaints of not being able to track the mtime > +properly. This specification highlights seven different > +mtime values that possibly could be the same value (at > +least, in the beginning when first added or imported). > +The benefit of having the additional six mtime properties > +is to clarify the file's or directory's historical changes, > +from the first time it was introduced into the repository > +to the current moment. > + > +With the added properties come the possibility of > +concerns to crop up. > + > +1) Whether having so many different mtime properties > + is helpful, even from a user's standpoint. While > + it gives the user the flexibility of maintaining > + their files in their proper time-order, it also > + gives users another way of ruining their repository > + and/or properties. > + > +2) Whether it is feasible to maintain so many > + *mtime properties and keep the majority read-only. > + The multiple *mtime properties clarifies the initial > + Add, and Import mtimes as well as the last Commit > + and Merge commands; but, is it possible to make a > + property 'read only' (from the POV of the user, > + not the system)? Making the specified *mtime > + properties read-only will imply a change in > + the pset command functionality. > + > + ### Or can it just simply be > + ### if property=svn:addmtime > + ### ignore command > + > +3) Will the *mtime properties cause confusion, especially > + R(x) and S(x) which is the mtime and the 'original mtime' > + of file/directory x respectively? What's the difference? > + > + Clarification: > + The difference between R(x) and S(x) is that of > + viewpoint. R(x) is the mtime of the file which > + changes as the file is updated. S(x) is the > + original mtime on the time it was updated, added > + or imported. > + > + This further begs the question, why so many? > + > + To clarify, > + > + A(x) is the time the file/directory was added. > + C(x) is the time the file/directory was committed. > + I(x) is the time the file/directory was imported. > + G(x) is the time the file was last merged. > + R(x) is the mtime of the file. > + S(x) is the original mtime of the file upon committed > + to the repository. > + > + What is the purpose of having a separate A(x) and > + a C(x)? A user might have added a file to the repository > + via 'svn add <file>' but did not commit it until later. > + > + What about the difference between S(x) and A(x) or I(x)? > + Since if S(x) is the original mtime upon being committed > + to the repository, would this not be the same as A(x) or > + I(x)? The rationale for having these different mtime > + values is to allow the user to indicate when x was > + Added (A(x)) or imported (I(x)). Since these two values > + are one-off (after all, you cannot add the same x to > + the same repository more than once), A(x) and I(x) > + should be 'written in stone'. That is, the properties > + should be written once to the property hashes and should > + not be over-written. S(x), on the other hand, can be > + over-written. > + ### What about the case with 'svn rm x'? > + ### Might this help with 'svn rename x y' and keeping > + ### history? $ svn co http://... wc $ touch wc/foo $ svn st wc $ svn ci wc Does wc/foo show up as modifed? Can the mtime modification be committed? What happens when the wc filesystem cannot support the timestamp resolution in the svn:*mtime properties? Do all the files show up as modified? -- Philip