⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 repos_diff.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 3 页
字号:

  return SVN_NO_ERROR;
}

/* An editor function.  Do the work of applying the text delta.  */
static svn_error_t *
window_handler (svn_txdelta_window_t *window,
                void *window_baton)
{
  struct file_baton *b = window_baton;

  SVN_ERR (b->apply_handler (window, b->apply_baton));

  if (!window)
    {
      SVN_ERR (svn_io_file_close (b->file_start_revision, b->pool));
      SVN_ERR (svn_io_file_close (b->file_end_revision, b->pool));
    }

  return SVN_NO_ERROR;
}

/* An editor function.  */
static svn_error_t *
apply_textdelta (void *file_baton,
                 const char *base_checksum,
                 apr_pool_t *pool,
                 svn_txdelta_window_handler_t *handler,
                 void **handler_baton)
{
  struct file_baton *b = file_baton;
  svn_boolean_t have_lock;

  /* Open the file to be used as the base for second revision */
  SVN_ERR (svn_io_file_open (&(b->file_start_revision),
                             b->path_start_revision,
                             APR_READ, APR_OS_DEFAULT, b->pool));

  /* Open the file that will become the second revision after applying the
     text delta, it starts empty */
  have_lock = (b->edit_baton->adm_access 
               && svn_wc_adm_locked (b->edit_baton->adm_access));
  SVN_ERR (create_empty_file (&(b->path_end_revision), have_lock, b->pool));
  SVN_ERR (temp_file_cleanup_register (b->path_end_revision, b->pool));
  SVN_ERR (svn_io_file_open (&(b->file_end_revision), b->path_end_revision,
                             APR_WRITE, APR_OS_DEFAULT, b->pool));

  svn_txdelta_apply (svn_stream_from_aprfile (b->file_start_revision, b->pool),
                     svn_stream_from_aprfile (b->file_end_revision, b->pool),
                     NULL,
                     b->path,
                     b->pool,
                     &(b->apply_handler), &(b->apply_baton));

  *handler = window_handler;
  *handler_baton = file_baton;

  return SVN_NO_ERROR;
}

/* An editor function.  When the file is closed we have a temporary
 * file containing a pristine version of the repository file. This can
 * be compared against the working copy.
 *
 * ### Ignore TEXT_CHECKSUM for now.  Someday we can use it to verify
 * ### the integrity of the file being diffed.  Done efficiently, this
 * ### would probably involve calculating the checksum as the data is
 * ### received, storing the final checksum in the file_baton, and
 * ### comparing against it here.
 */
static svn_error_t *
close_file (void *file_baton,
            const char *text_checksum,
            apr_pool_t *pool)
{
  struct file_baton *b = file_baton;
  struct edit_baton *eb = b->edit_baton;
  svn_wc_adm_access_t *adm_access;
  svn_error_t *err;
  svn_wc_notify_action_t action;
  svn_wc_notify_state_t
    content_state = svn_wc_notify_state_unknown,
    prop_state = svn_wc_notify_state_unknown;

  err = get_parent_access (&adm_access, eb->adm_access, 
                           b->wcpath, eb->dry_run, b->pool);

  if (err && err->apr_err == SVN_ERR_WC_NOT_LOCKED)
    {
      /* ### maybe try to stat the local b->wcpath? */      
      /* If the file path doesn't exist, then send a 'skipped' notification. */
      if (eb->notify_func)
        (*eb->notify_func) (eb->notify_baton, b->wcpath,
                            svn_wc_notify_skip, svn_node_file, NULL,
                            svn_wc_notify_state_missing, prop_state,
                            SVN_INVALID_REVNUM);
      
      svn_error_clear (err);
      return SVN_NO_ERROR;
    }
  else if (err)
    return err;

  if (b->path_end_revision)
    {
      const char *mimetype1, *mimetype2;
      get_file_mime_types (&mimetype1, &mimetype2, b);

      if (b->added)
        SVN_ERR (eb->diff_callbacks->file_added
                 (adm_access, &content_state,
                  b->wcpath,
                  b->path_start_revision,
                  b->path_end_revision,
                  0,
                  b->edit_baton->target_revision,
                  mimetype1, mimetype2,
                  b->edit_baton->diff_cmd_baton));
      else
        SVN_ERR (eb->diff_callbacks->file_changed
                 (adm_access, &content_state,
                  b->wcpath,
                  b->path_start_revision,
                  b->path_end_revision,
                  b->edit_baton->revision,
                  b->edit_baton->target_revision,
                  mimetype1, mimetype2,
                  b->edit_baton->diff_cmd_baton));
    }

  /* Don't do the props_changed stuff if this is a dry_run and we don't
     have an access baton, since in that case the file will already have
     been recognised as added, in which case they cannot conflict. A
     similar argument applies to directories in close_directory. */
  if (b->propchanges->nelts > 0 && (! (eb->dry_run && b->added)))
    {
      SVN_ERR (eb->diff_callbacks->props_changed
               (adm_access, &prop_state,
                b->wcpath,
                b->propchanges, b->pristine_props,
                b->edit_baton->diff_cmd_baton));
    }


  /* ### Is b->path the repos path?  Probably.  This doesn't really
     matter while issue #748 (svn merge only happens in ".") is
     outstanding.  But when we take a wc_path as an argument to
     merge, then we'll need to pass around a wc path somehow. */

  if ((content_state == svn_wc_notify_state_missing)
      || (content_state == svn_wc_notify_state_obstructed))
    action = svn_wc_notify_skip;
  else if (b->added)
    action = svn_wc_notify_update_add;
  else
    action = svn_wc_notify_update_update;

  if (eb->notify_func)
    (*eb->notify_func)
      (eb->notify_baton,
       b->wcpath,
       action,
       svn_node_file,
       NULL,
       content_state,
       prop_state,
       SVN_INVALID_REVNUM);

  return SVN_NO_ERROR;
}

/* An editor function.  */
static svn_error_t *
close_directory (void *dir_baton,
                 apr_pool_t *pool)
{
  struct dir_baton *b = dir_baton;
  struct edit_baton *eb = b->edit_baton;
  svn_wc_notify_state_t prop_state = svn_wc_notify_state_unknown;
  svn_error_t *err;

  if (b->propchanges->nelts > 0)
    {
      svn_wc_adm_access_t *adm_access;
      err = get_path_access (&adm_access, eb->adm_access, b->wcpath,
                             eb->dry_run, b->pool);

      if (err && err->apr_err == SVN_ERR_WC_NOT_LOCKED)
        {
          /* ### maybe try to stat the local b->wcpath? */          
          /* If the path doesn't exist, then send a 'skipped' notification. */
          if (eb->notify_func)
            (*eb->notify_func) (eb->notify_baton, b->wcpath,
                                svn_wc_notify_skip, svn_node_dir, NULL,
                                svn_wc_notify_state_missing,
                                svn_wc_notify_state_missing,
                                SVN_INVALID_REVNUM);

          svn_error_clear (err);      
          return SVN_NO_ERROR;
        }
      else if (err)
        return err;

      /* As for close_file, whether we do this depends on whether it's a
         dry-run */
      if (! eb->dry_run || adm_access)
        SVN_ERR (eb->diff_callbacks->props_changed
                 (adm_access, &prop_state,
                  b->wcpath,
                  b->propchanges, b->pristine_props,
                  b->edit_baton->diff_cmd_baton));
    }

  if (eb->notify_func)
    (*eb->notify_func) (eb->notify_baton,
                        b->wcpath,
                        svn_wc_notify_update_update,
                        svn_node_dir,
                        NULL,
                        svn_wc_notify_state_inapplicable,
                        prop_state,
                        SVN_INVALID_REVNUM);

  return SVN_NO_ERROR;
}


/* An editor function.  */
static svn_error_t *
change_file_prop (void *file_baton,
                  const char *name,
                  const svn_string_t *value,
                  apr_pool_t *pool)
{
  struct file_baton *b = file_baton;
  svn_prop_t *propchange;

  propchange = apr_array_push (b->propchanges);
  propchange->name = apr_pstrdup (b->pool, name);
  propchange->value = value ? svn_string_dup (value, b->pool) : NULL;
  
  return SVN_NO_ERROR;
}

/* An editor function.  */
static svn_error_t *
change_dir_prop (void *dir_baton,
                 const char *name,
                 const svn_string_t *value,
                 apr_pool_t *pool)
{
  struct dir_baton *db = dir_baton;
  svn_prop_t *propchange;

  propchange = apr_array_push (db->propchanges);
  propchange->name = apr_pstrdup (db->pool, name);
  propchange->value = value ? svn_string_dup (value, db->pool) : NULL;

  return SVN_NO_ERROR;
}


/* An editor function.  */
static svn_error_t *
close_edit (void *edit_baton,
            apr_pool_t *pool)
{
  struct edit_baton *eb = edit_baton;

  svn_pool_destroy (eb->pool);

  return SVN_NO_ERROR;
}

/* Create a repository diff editor and baton.  */
svn_error_t *
svn_client__get_diff_editor (const char *target,
                             svn_wc_adm_access_t *adm_access,
                             const svn_wc_diff_callbacks_t *diff_callbacks,
                             void *diff_cmd_baton,
                             svn_boolean_t recurse,
                             svn_boolean_t dry_run,
                             svn_ra_plugin_t *ra_lib,
                             void *ra_session,
                             svn_revnum_t revision,
                             svn_wc_notify_func_t notify_func,
                             void *notify_baton,
                             svn_cancel_func_t cancel_func,
                             void *cancel_baton,
                             const svn_delta_editor_t **editor,
                             void **edit_baton,
                             apr_pool_t *pool)
{
  apr_pool_t *subpool = svn_pool_create (pool);
  svn_delta_editor_t *tree_editor = svn_delta_default_editor (subpool);
  struct edit_baton *eb = apr_palloc (subpool, sizeof (*eb));

  eb->target = target;
  eb->adm_access = adm_access;
  eb->diff_callbacks = diff_callbacks;
  eb->diff_cmd_baton = diff_cmd_baton;
  eb->recurse = recurse;
  eb->dry_run = dry_run;
  eb->ra_lib = ra_lib;
  eb->ra_session = ra_session;
  eb->revision = revision;
  eb->empty_file = NULL;
  eb->pool = subpool;
  eb->notify_func = notify_func;
  eb->notify_baton = notify_baton;

  tree_editor->set_target_revision = set_target_revision;
  tree_editor->open_root = open_root;
  tree_editor->delete_entry = delete_entry;
  tree_editor->add_directory = add_directory;
  tree_editor->open_directory = open_directory;
  tree_editor->add_file = add_file;
  tree_editor->open_file = open_file;
  tree_editor->apply_textdelta = apply_textdelta;
  tree_editor->close_file = close_file;
  tree_editor->close_directory = close_directory;
  tree_editor->change_file_prop = change_file_prop;
  tree_editor->change_dir_prop = change_dir_prop;
  tree_editor->close_edit = close_edit;

  SVN_ERR (svn_delta_get_cancellation_editor (cancel_func,
                                              cancel_baton,
                                              tree_editor,
                                              eb,
                                              editor,
                                              edit_baton,
                                              pool));

  return SVN_NO_ERROR;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -