如果你浏览svn源码,你会发现svn commit是由http://svn.apache.org/repos/asf/subversion/branches/1.5.x/subversion/svn/commit-cmd.c中的svn_cl__commit函数处理的。负责将路径拆分为“basename”和“dirname”的实际函数是svn_wc_get_actual_target。此函数在http://svn.apache.org/repos/asf/subversion/branches/1.5.x/subversion/include/svn_wc.h 中声明,并有以下注释:
/** Conditionally split @a path into an @a anchor and @a target for the
* purpose of updating and committing.
*
* @a anchor is the directory at which the update or commit editor
* should be rooted.
*
* @a target is the actual subject (relative to the @a anchor) of the
* update/commit, or "" if the @a anchor itself is the subject.
*
* Allocate @a anchor and @a target in @a pool.
*/
最后在http://svn.apache.org/repos/asf/subversion/branches/1.5.x/subversion/libsvn_wc/update_editor.c 文件中,我们可以看到以下评论:
Updates are accomplished by driving an editor, and an editor is
"rooted" on a directory. So, in order to update a file, we need to
break off the basename of the file, rooting the editor in that
file's parent directory, and then updating only that file, not the
other stuff in its parent directory.
Secondly, we look at the case where we wish to update a directory.
This is typically trivial. However, one problematic case, exists
when we wish to update a directory that has been removed from the
repository and replaced with a file of the same name. If we root
our edit at the initial directory, there is no editor mechanism for
deleting that directory and replacing it with a file (this would be
like having an editor now anchored on a file, which is disallowed).
All that remains is to have a function with the knowledge required
to properly decide where to root our editor, and what to act upon
with that now-rooted editor. Given a path to be updated, this
function should conditionally split that path into an "anchor" and
a "target", where the "anchor" is the directory at which the update
editor is rooted (meaning, editor->open_root() is called with
this directory in mind), and the "target" is the actual intended
subject of the update.
svn_wc_get_actual_target() is that function.
...
As it turns out, commits need to have a similar check in place,
too, specifically for the case where a single directory is being
committed (we have to anchor at that directory's parent in case the
directory itself needs to be modified)