Allright, here is the complete patch for updates. The three changes in
mod_dav_svn, are there as a hack to temporarily solve the anchor/target
problems we have been having with ra_dav.
The rest are genuine problems with the way updates work.
Note: svn up --nonrecursive is still not implemented. I may get to it in a
little while
Index: ./libsvn_wc/adm_crawler.c
===================================================================
--- ./libsvn_wc/SVN/text-base/adm_crawler.c Tue Sep 11 16:00:45 2001
+++ ./libsvn_wc/adm_crawler.c Wed Sep 12 13:21:00 2001
@@ -1764,12 +1764,21 @@
svn_wc_entry_t *entry;
svn_revnum_t base_rev = SVN_INVALID_REVNUM;
svn_pool_feedback_t *fbtable = svn_pool_get_feedback_vtable (pool);
+ svn_boolean_t missing = FALSE;
/* The first thing we do is get the base_rev from the working copy's
ROOT_DIRECTORY. This is the first revnum that entries will be
compared to. */
SVN_ERR (svn_wc_entry (&entry, path, pool));
base_rev = entry->revision;
+ if (base_rev == SVN_INVALID_REVNUM)
+ {
+ svn_stringbuf_t *parent_name = svn_stringbuf_dup (path, pool);
+ svn_wc_entry_t *parent_entry;
+ svn_path_remove_component (parent_name, svn_path_local_style);
+ SVN_ERR (svn_wc_entry (&parent_entry, parent_name, pool));
+ base_rev = parent_entry->revision;
+ }
/* The first call to the reporter merely informs it that the
top-level directory being updated is at BASE_REV. Its PATH
@@ -1778,7 +1787,30 @@
svn_stringbuf_create ("", pool),
base_rev));
- if (entry->kind == svn_node_dir)
+ if (entry->existence != svn_wc_existence_deleted
+ && entry->schedule != svn_wc_schedule_delete)
+ {
+ apr_finfo_t info;
+ apr_status_t apr_err;
+ apr_err = apr_stat (&info, path->data, APR_FINFO_MIN, pool);
+ if (APR_STATUS_IS_ENOENT(apr_err))
+ {
+ missing = TRUE;
+ err = reporter->delete_path (report_baton,
+ svn_stringbuf_create ("", pool));
+ if (err)
+ {
+ /* Clean up the fs transaction. */
+ svn_error_t *fserr;
+ fserr = reporter->abort_report (report_baton);
+ if (fserr)
+ return svn_error_quick_wrap (fserr, "Error aborting report.");
+ else
+ return err;
+ }
+ }
+ }
+ if (!missing && entry->kind == svn_node_dir)
{
/* Recursively crawl ROOT_DIRECTORY and report differing
revisions. */
@@ -1797,7 +1829,7 @@
return err;
}
}
- else if ((entry->kind == svn_node_file)
+ else if (!missing && (entry->kind == svn_node_file)
&& (entry->revision != base_rev))
{
/* If this entry is a file node, we just want to report that
Index: ./libsvn_wc/get_editor.c
===================================================================
--- ./libsvn_wc/SVN/text-base/get_editor.c Tue Sep 11 16:00:43 2001
+++ ./libsvn_wc/get_editor.c Wed Sep 12 13:08:50 2001
@@ -1853,6 +1853,15 @@
*entry = NULL;
}
}
+ else if (!my_entry->ancestor)
+ {
+ /* Case V: If my_entry->ancestor is NULL, that probably means that
+ my_entry is a directory which has been deleted, leaving an entry
+ in parent_dir's entries file, but not the thisdir info that would
+ be in path's entries file. */
+ *parent_dir = dirname;
+ *entry = basename;
+ }
}
return SVN_NO_ERROR;
Index: ./libsvn_client/update.c
===================================================================
--- ./libsvn_client/SVN/text-base/update.c Tue Sep 11 16:00:35 2001
+++ ./libsvn_client/update.c Wed Sep 12 13:14:07 2001
@@ -71,6 +71,7 @@
void *report_baton;
svn_wc_entry_t *entry;
svn_stringbuf_t *URL;
+ svn_stringbuf_t *base_dir = path;
/* Sanity check. Without this, the update is meaningless. */
assert (path != NULL);
@@ -88,13 +89,35 @@
(SVN_ERR_WC_ENTRY_NOT_FOUND, 0, NULL, pool,
"entry '%s' has already been deleted", path->data);
- URL = svn_stringbuf_create (entry->ancestor->data, pool);
+ if (entry->ancestor)
+ URL = svn_stringbuf_create (entry->ancestor->data, pool);
+
+ if (!entry->ancestor)
+ {
+ svn_wc_entry_t *par_entry;
+ svn_stringbuf_t *basename;
+ svn_path_split(path, &base_dir, &basename, svn_path_local_style, pool);
+ if (svn_stringbuf_isempty(base_dir))
+ svn_stringbuf_set(base_dir, ".");
+ SVN_ERR(svn_wc_entry(&par_entry, base_dir, pool));
+ if (! par_entry)
+ return svn_error_createf
+ (SVN_ERR_WC_OBSTRUCTED_UPDATE, 0, NULL, pool,
+ "svn_client_update: %s is not under revision control",
+ base_dir->data);
+ if (entry->existence == svn_wc_existence_deleted)
+ return svn_error_createf
+ (SVN_ERR_WC_ENTRY_NOT_FOUND, 0, NULL, pool,
+ "entry '%s' has already been deleted", base_dir->data);
+ URL = svn_stringbuf_dup(par_entry->ancestor, pool);
+ svn_path_add_component(URL, basename, svn_path_url_style);
+ }
/* The following is an ugly kludge. In order to let the RA layer
know the difference between updating entry 'Z' in dir 'X/Y' and
updating entry '.' in 'X/Y/Z', we'll append a '.' to the URL. */
if (svn_path_is_thisdir (path, svn_path_repos_style))
- svn_path_add_component (URL, path, svn_path_repos_style);
+ svn_path_add_component (URL, path, svn_path_url_style);
/* Fetch the update editor. If REVISION is invalid, that's okay;
either the RA or XML driver will call editor->set_target_revision
@@ -116,7 +139,6 @@
{
void *ra_baton, *session;
svn_ra_plugin_t *ra_lib;
- svn_stringbuf_t *base_dir = path;
/* Get the RA vtable that matches URL. */
SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));
Index: ./mod_dav_svn/update.c
===================================================================
--- ./mod_dav_svn/SVN/text-base/update.c Tue Sep 11 16:00:22 2001
+++ ./mod_dav_svn/update.c Wed Sep 12 12:51:19 2001
@@ -338,7 +338,8 @@
dav_error * dav_svn__update_report(const dav_resource *resource,
const apr_xml_doc *doc,
- apr_text_header *report)
+ apr_text_header *report,
+ int is_thisdir)
{
svn_delta_edit_fns_t *editor;
apr_xml_elem *child;
@@ -349,6 +350,8 @@
int ns;
svn_error_t *serr;
svn_stringbuf_t *pathstr;
+ svn_stringbuf_t *anchor;
+ svn_stringbuf_t *target;
const dav_svn_repos *repos = resource->info->repos;
if (resource->type != DAV_RESOURCE_TYPE_REGULAR)
@@ -413,22 +416,15 @@
}
fs_base = svn_stringbuf_create(resource->info->repos_path, resource->pool);
+ if (fs_base->len == 1 && fs_base->data[0] == '/')
+ svn_stringbuf_setempty(fs_base);
- /* ### temp hack until begin_report gets separate anchor/target params */
- if (resource->collection)
- {
- uc.anchor = resource->info->repos_path;
- svn_stringbuf_appendcstr(fs_base, "/.");
- }
- else
- {
- svn_stringbuf_t *anchor;
- svn_stringbuf_t *target;
+ if (is_thisdir)
+ svn_stringbuf_appendcstr(fs_base, "/.");
- svn_path_split(fs_base, &anchor, &target, svn_path_repos_style,
- resource->pool);
- uc.anchor = anchor->data;
- }
+ svn_path_split(fs_base, &anchor, &target, svn_path_repos_style,
+ resource->pool);
+ uc.anchor = anchor->data;
serr = svn_repos_begin_report(&rbaton, revnum, repos->username, repos->fs,
fs_base, editor, &uc, resource->pool);
Index: ./mod_dav_svn/version.c
===================================================================
--- ./mod_dav_svn/SVN/text-base/version.c Tue Sep 11 16:00:21 2001
+++ ./mod_dav_svn/version.c Wed Sep 12 12:51:19 2001
@@ -367,6 +367,8 @@
ap_text_header *report)
{
int ns = dav_svn_find_ns(doc->namespaces, SVN_XML_NAMESPACE);
+ int is_thisdir = 0;
+ apr_size_t len;
if (doc->root->ns != ns
|| strcmp(doc->root->name, "update-report") != 0)
@@ -376,7 +378,11 @@
"The requested report is unknown.");
}
- return dav_svn__update_report(resource, doc, report);
+ len = strlen(r->the_request);
+ if (r->the_request[len - 10] == '.')
+ is_thisdir = 1;
+
+ return dav_svn__update_report(resource, doc, report, is_thisdir);
}
static int dav_svn_can_be_activity(const dav_resource *resource)
Index: ./mod_dav_svn/dav_svn.h
===================================================================
--- ./mod_dav_svn/SVN/text-base/dav_svn.h Tue Sep 11 16:00:21 2001
+++ ./mod_dav_svn/dav_svn.h Wed Sep 12 12:51:19 2001
@@ -307,7 +307,8 @@
dav_error * dav_svn__update_report(const dav_resource *resource,
const apr_xml_doc *doc,
- apr_text_header *report);
+ apr_text_header *report,
+ int is_thisdir);
int dav_svn_find_ns(apr_array_header_t *namespaces, const char *uri);
Index: ./libsvn_repos/delta.c
===================================================================
--- ./libsvn_repos/SVN/text-base/delta.c Tue Sep 11 15:59:35 2001
+++ ./libsvn_repos/delta.c Wed Sep 12 12:51:19 2001
@@ -176,6 +176,7 @@
svn_stringbuf_t *tgt_parent_dir, *tgt_entry;
svn_stringbuf_t *src_fullpath, *tgt_fullpath;
svn_fs_id_t *src_id, *tgt_id;
+ svn_error_t *err;
int distance;
/* SRC_PARENT_DIR must be valid. */
@@ -248,10 +249,21 @@
svn_path_add_component (src_fullpath, src_entry, svn_path_repos_style);
/* Get the node ids for the source and target paths. */
- SVN_ERR (svn_fs_node_id (&src_id, src_root, src_fullpath->data, pool));
+
+ err = svn_fs_node_id (&src_id, src_root, src_fullpath->data, pool);
SVN_ERR (svn_fs_node_id (&tgt_id, tgt_root, tgt_fullpath->data, pool));
-
- if (src_entry && src_entry->len > 0)
+ if (err && err->apr_err == SVN_ERR_FS_NOT_FOUND)
+ {
+ /* The target has been deleted from our working copy. Add back a new
+ one. */
+ SVN_ERR (add_file_or_dir (&c, root_baton,
+ 0,
+ 0,
+ tgt_parent_dir,
+ tgt_entry,
+ pool));
+ }
+ else if (src_entry && src_entry->len > 0)
{
/* Use the distance between the node ids to determine the best
way to update the requested entry. */
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Kevin Pilch-Bisson http://www.pilch-bisson.net
"Historically speaking, the presences of wheels in Unix
has never precluded their reinvention." - Larry Wall
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- application/pgp-signature attachment: stored
Received on Sat Oct 21 14:36:40 2006