[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

question about the update editor (essentially)

From: Stefan Sperling <stsp_at_elego.de>
Date: 2007-12-12 22:03:52 CET

Dear working copy gods and other svn-hacking fellows,

To create a user-visible tree conflicts report file,
I call a function called "svn_wc__write_tree_conflict_report()".

This function gets a log accumulator and an adm_access.

It fetches the entry out of the adm_access, reads tree-conflict
data from it (if any), transforms that into a human readable description
(the "report") and writes that to a temp file.

Then it uses the log to schedule a move of the temp file to the
user-visible file tree_conflicts.txt, which resides in the tree-conflicted
directory in the working copy. See below for the current implementation of
this function.

When calling this function in libsvn_wc/update_editor.c:close_directory(),
tree-conflict data about files that are deleted by the update
make it into the entry retrieved from the adm_access.

But files that the update merely edits do not appear in that entry
object at the time this function is called. They end up on disk though
when the whole update is done. It seems that changes to files are somehow
processed later than changes to directories, is that correct?

I'm now trying to find the proper place in libsvn_wc/update_editor.c
to call this function so that tree conflict data for files that are
modified by the update is present in the entry retrieved from the
adm_access when this function is run.

Any idea where to put this function call?
Maybe I need to call it multiple times?

Both close_file() and complete_directory() seem likely candidates,
but to be honest, with my limited understanding of how the update
editor, the log and the entries files on disk interact with one
another, it's a bit hard for me to find the correct spot just by RTFS.

I thought before going into trial and error I might get an expert's
opinion on this. Thanks for helpėng me out :)

Oh, and if this whole idea is moot for some reason, tell me! Thanks.

As promised, the code for the function I want to call:

svn_error_t *
svn_wc__write_tree_conflict_report(svn_stringbuf_t *log_accum,
                                   svn_wc_adm_access_t *adm_access,
                                   apr_pool_t *pool)
{
  const char *dir_path, *native_text;
  svn_stringbuf_t *report_path_buf;
  const char *report_tmp_path, *report_path;
  apr_file_t *report_tmp_fp;
  apr_size_t written;
  const svn_wc_entry_t *entry;
  svn_wc_entry_t tmp_entry;
  apr_array_header_t *conflicts;
  svn_wc_conflict_description_t *conflict;
  svn_stringbuf_t *report;
  int i;

  /* Make sure the node is a directory.
   * Otherwise we should not have been called. */
  dir_path = svn_wc_adm_access_path(adm_access);
  SVN_ERR(svn_wc_entry(&entry, dir_path, adm_access, TRUE, pool));
  assert(entry->kind == svn_node_dir);

  conflicts = apr_array_make(pool, 0,
                             sizeof(svn_wc_conflict_description_t *));
  SVN_ERR(svn_wc__read_tree_conflicts_from_entry(conflicts, entry, pool));

  if (apr_is_empty_array(conflicts))
    return SVN_NO_ERROR;

  report = svn_stringbuf_create("", pool);
  /* Should we print dir_path and timestamp in the conflict report? */
  for (i = 0; i < conflicts->nelts; i++)
    {
      conflict = APR_ARRAY_IDX(conflicts, i,
                               svn_wc_conflict_description_t *);
      SVN_ERR(svn_wc__append_tree_conflict_to_report(report, conflict, pool));
      svn_stringbuf_appendcstr(report, "\n");
    }
  native_text = svn_utf_cstring_from_utf8_fuzzy(report->data, pool);

  /* Write the report to a temp file. */
  SVN_ERR(svn_wc_create_tmp_file2(&report_tmp_fp,
                                  &report_tmp_path,
                                  dir_path,
                                  svn_io_file_del_none,
                                  pool));
  SVN_ERR(svn_io_file_write_full(report_tmp_fp,
                                 native_text,
                                 strlen(native_text),
                                 &written,
                                 pool));
  SVN_ERR(svn_io_file_close(report_tmp_fp, pool));

  /* Loggy move the temp file to the user-visible file.
   * Assumes that the move will succeed even if another application
   * has locked the file. Is that a safe assumption?
   */
  report_path_buf = svn_stringbuf_create(SVN_WC__TREE_CONFLICT_REPORT, pool);
  svn_stringbuf_appendcstr(report_path_buf, SVN_WC__TREE_CONFLICT_REPORT_EXT);
  report_path = svn_path_join(dir_path, report_path_buf->data, pool);
  SVN_ERR(svn_wc__loggy_move(&log_accum,
                             NULL,
                             adm_access,
                             report_tmp_path,
                             report_path,
                             FALSE,
                             pool));

  /* Update the entry with the path (relative to DIR_PATH) of the
   * user-visible report file. */
  tmp_entry.tree_conflict_report = svn_path_is_child(dir_path,
                                                     report_path, pool);
  SVN_ERR(svn_wc__loggy_entry_modify(&log_accum,
                                     adm_access,
                                     dir_path,
                                     &tmp_entry,
                                     SVN_WC__ENTRY_MODIFY_TREE_CONFLICT_REPORT,
                                     pool));
  return SVN_NO_ERROR;
}

-- 
Stefan Sperling <stsp@elego.de>                 Software Developer
elego Software Solutions GmbH                            HRB 77719
Gustav-Meyer-Allee 25, Gebaeude 12        Tel:  +49 30 23 45 86 96 
13355 Berlin                              Fax:  +49 30 23 45 86 95
http://www.elego.de                 Geschaeftsfuehrer: Olaf Wagner

  • application/pgp-signature attachment: stored
Received on Wed Dec 12 22:05:32 2007

This is an archived mail posted to the Subversion Dev mailing list.