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

📄 externals.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 2 页
字号:
        (*ib->ctx->notify_func) (ib->ctx->notify_baton,
                                 path,
                                 svn_wc_notify_update_external,
                                 svn_node_unknown,
                                 NULL,
                                 svn_wc_notify_state_unknown,
                                 svn_wc_notify_state_unknown,
                                 SVN_INVALID_REVNUM);

      /* Next, verify that the external working copy matches
         (URL-wise) what is supposed to be on disk. */
      SVN_ERR (svn_io_check_path (path, &kind, ib->pool));
      if (kind == svn_node_dir)
        {
          SVN_ERR (svn_wc_adm_open2 (&adm_access, NULL, path, TRUE, -1,
                                     ib->pool));
          SVN_ERR (svn_wc_entry (&ext_entry, path, adm_access, 
                                 FALSE, ib->pool));
          SVN_ERR (svn_wc_adm_close (adm_access));

          /* If we have what appears to be a version controlled
             subdir, and its top-level URL matches that of our
             externals definition, perform an update. */
          if (ext_entry && (strcmp (ext_entry->url, new_item->url) == 0))
            {
              SVN_ERR (svn_client__update_internal (NULL, path,
                                                    &(new_item->revision),
                                                    TRUE, /* recurse */
                                                    ib->timestamp_sleep,
                                                    ib->ctx, ib->pool));
            }
          /* If, however, the URLs don't match, we need to relegate
             the one subdir, and then checkout a new one. */
          else
            {
              /* Buh-bye, old and busted ... */
              SVN_ERR (relegate_external (path,
                                          ib->ctx->cancel_func,
                                          ib->ctx->cancel_baton,
                                          ib->pool));
              /* ... Hello, new hotness. */
              SVN_ERR (svn_client__checkout_internal (NULL, new_item->url,
                                                      path,
                                                      &(new_item->revision),
                                                      TRUE, /* recurse */
                                                      ib->timestamp_sleep,
                                                      ib->ctx, ib->pool));
            }
        }
      else /* Not a directory at all -- just try the checkout. */
        {
          /* The target dir might have multiple components.  Guarantee
             the path leading down to the last component. */
          svn_path_split (path, &parent, NULL, ib->pool);
          SVN_ERR (svn_io_make_dir_recursively (parent, ib->pool));

          /* Checking out... */
          SVN_ERR (svn_client__checkout_internal (NULL, new_item->url, path,
                                                  &(new_item->revision),
                                                  TRUE, /* recurse */
                                                  ib->timestamp_sleep,
                                                  ib->ctx, ib->pool));
        }
    }

  /* Clear IB->pool -- we only use it for scratchwork (and this will
     close any RA sessions still open in this pool). */
  svn_pool_clear (ib->pool);

  return SVN_NO_ERROR;
}


/* Closure for handle_externals_change. */
struct handle_externals_desc_change_baton
{
  /* As returned by svn_wc_edited_externals(). */
  apr_hash_t *externals_new;
  apr_hash_t *externals_old;

  /* Passed through to handle_external_item_change_baton. */
  svn_client_ctx_t *ctx;
  svn_boolean_t update_unchanged;
  svn_boolean_t *timestamp_sleep;
  svn_boolean_t is_export;

  apr_pool_t *pool;
};


/* This implements the 'svn_hash_diff_func_t' interface.
   BATON is of type 'struct handle_externals_desc_change_baton *'.  
*/
static svn_error_t *
handle_externals_desc_change (const void *key, apr_ssize_t klen,
                              enum svn_hash_diff_key_status status,
                              void *baton)
{
  struct handle_externals_desc_change_baton *cb = baton;
  struct handle_external_item_change_baton ib;
  const char *old_desc_text, *new_desc_text;
  apr_array_header_t *old_desc, *new_desc;
  apr_hash_t *old_desc_hash, *new_desc_hash;
  int i;
  svn_wc_external_item_t *item;

  if ((old_desc_text = apr_hash_get (cb->externals_old, key, klen)))
    SVN_ERR (svn_wc_parse_externals_description2 (&old_desc, (const char *) key,
                                                  old_desc_text, cb->pool));
  else
    old_desc = NULL;

  if ((new_desc_text = apr_hash_get (cb->externals_new, key, klen)))
    SVN_ERR (svn_wc_parse_externals_description2 (&new_desc, (const char *) key,
                                                  new_desc_text, cb->pool));
  else
    new_desc = NULL;

  old_desc_hash = apr_hash_make (cb->pool);
  new_desc_hash = apr_hash_make (cb->pool);

  /* Create hashes of our two externals arrays so that we can
     efficiently generate a diff for them. */
  for (i = 0; old_desc && (i < old_desc->nelts); i++)
    {
      item = APR_ARRAY_IDX (old_desc, i, svn_wc_external_item_t *);

      apr_hash_set (old_desc_hash, item->target_dir,
                    APR_HASH_KEY_STRING, item);
    }
  
  for (i = 0; new_desc && (i < new_desc->nelts); i++)
    {
      item = APR_ARRAY_IDX (new_desc, i, svn_wc_external_item_t *);

      apr_hash_set (new_desc_hash, item->target_dir,
                    APR_HASH_KEY_STRING, item);
    }

  ib.old_desc          = old_desc_hash;
  ib.new_desc          = new_desc_hash;
  ib.parent_dir        = (const char *) key;
  ib.ctx               = cb->ctx;
  ib.update_unchanged  = cb->update_unchanged;
  ib.is_export         = cb->is_export;
  ib.timestamp_sleep   = cb->timestamp_sleep;
  ib.pool              = svn_pool_create (cb->pool);

  /* We must use a custom version of svn_hash_diff so that the diff
     entries are processed in the order they were originally specified
     in the svn:external properties. */

  for (i = 0; old_desc && (i < old_desc->nelts); i++)
    {
      item = APR_ARRAY_IDX (old_desc, i, svn_wc_external_item_t *);

      if (apr_hash_get (new_desc_hash, item->target_dir, APR_HASH_KEY_STRING))
        SVN_ERR (handle_external_item_change (item->target_dir,
                                              APR_HASH_KEY_STRING,
                                              svn_hash_diff_key_both, &ib));
      else
        SVN_ERR (handle_external_item_change (item->target_dir,
                                              APR_HASH_KEY_STRING,
                                              svn_hash_diff_key_a, &ib));
    }
  for (i = 0; new_desc && (i < new_desc->nelts); i++)
    {
      item = APR_ARRAY_IDX (new_desc, i, svn_wc_external_item_t *);
      if (! apr_hash_get (old_desc_hash, item->target_dir, APR_HASH_KEY_STRING))
        SVN_ERR (handle_external_item_change (item->target_dir,
                                              APR_HASH_KEY_STRING,
                                              svn_hash_diff_key_b, &ib));
    }
  
  /* Now destroy the subpool we pass to the hash differ.  This will
     close any remaining RA sessions used by the hash diff callback. */
  svn_pool_destroy (ib.pool);

  return SVN_NO_ERROR;
}


svn_error_t *
svn_client__handle_externals (svn_wc_traversal_info_t *traversal_info,
                              svn_boolean_t update_unchanged,
                              svn_boolean_t *timestamp_sleep,
                              svn_client_ctx_t *ctx,
                              apr_pool_t *pool)
{
  apr_hash_t *externals_old, *externals_new;
  struct handle_externals_desc_change_baton cb;

  svn_wc_edited_externals (&externals_old, &externals_new, traversal_info);

  cb.externals_new     = externals_new;
  cb.externals_old     = externals_old;
  cb.ctx               = ctx;
  cb.update_unchanged  = update_unchanged;
  cb.timestamp_sleep   = timestamp_sleep;
  cb.is_export         = FALSE;
  cb.pool              = pool;

  SVN_ERR (svn_hash_diff (cb.externals_old, cb.externals_new,
                          handle_externals_desc_change, &cb, pool));

  return SVN_NO_ERROR;
}


svn_error_t *
svn_client__fetch_externals (apr_hash_t *externals,
                             svn_boolean_t is_export,
                             svn_boolean_t *timestamp_sleep,
                             svn_client_ctx_t *ctx,
                             apr_pool_t *pool)
{
  struct handle_externals_desc_change_baton cb;

  cb.externals_new     = externals;
  cb.externals_old     = apr_hash_make (pool);
  cb.ctx               = ctx;
  cb.update_unchanged  = TRUE;
  cb.timestamp_sleep   = timestamp_sleep;
  cb.is_export         = is_export;
  cb.pool              = pool;

  SVN_ERR (svn_hash_diff (cb.externals_old, cb.externals_new,
                          handle_externals_desc_change, &cb, pool));

  return SVN_NO_ERROR;
}


svn_error_t *
svn_client__do_external_status (svn_wc_traversal_info_t *traversal_info,
                                svn_wc_status_func_t status_func,
                                void *status_baton,
                                svn_boolean_t get_all,
                                svn_boolean_t update,
                                svn_boolean_t no_ignore,
                                svn_client_ctx_t *ctx,
                                apr_pool_t *pool)
{
  apr_hash_t *externals_old, *externals_new;
  apr_hash_index_t *hi;
  apr_pool_t *subpool = svn_pool_create (pool);

  /* Get the values of the svn:externals properties. */
  svn_wc_edited_externals (&externals_old, &externals_new, traversal_info);

  /* Loop over the hash of new values (we don't care about the old
     ones).  This is a mapping of versioned directories to property
     values. */
  for (hi = apr_hash_first (pool, externals_new); 
       hi; 
       hi = apr_hash_next (hi))
    {
      apr_array_header_t *exts;
      const void *key;
      void *val;
      const char *path;
      const char *propval;
      apr_pool_t *iterpool;
      int i;

      /* Clear the subpool. */
      svn_pool_clear (subpool);

      apr_hash_this (hi, &key, NULL, &val);
      path = key;
      propval = val;

      /* Parse the svn:externals property value.  This results in a
         hash mapping subdirectories to externals structures. */
      SVN_ERR (svn_wc_parse_externals_description2 (&exts, path, 
                                                    propval, subpool));

      /* Make a sub-pool of SUBPOOL. */
      iterpool = svn_pool_create (subpool);

      /* Loop over the subdir array. */
      for (i = 0; exts && (i < exts->nelts); i++)
        {
          const char *fullpath;
          svn_wc_external_item_t *external;
          svn_node_kind_t kind;

          svn_pool_clear (iterpool);

          external = APR_ARRAY_IDX (exts, i, svn_wc_external_item_t *);
          fullpath = svn_path_join (path, external->target_dir, iterpool);

          /* If the external target directory doesn't exist on disk,
             just skip it. */
          SVN_ERR (svn_io_check_path (fullpath, &kind, iterpool));
          if (kind != svn_node_dir)
            continue;

          /* Tell the client we're staring an external status set. */
          if (ctx->notify_func)
            (ctx->notify_func) (ctx->notify_baton,
                                fullpath,
                                svn_wc_notify_status_external,
                                svn_node_unknown,
                                NULL,
                                svn_wc_notify_state_unknown,
                                svn_wc_notify_state_unknown,
                                SVN_INVALID_REVNUM);

          /* And then do the status. */
          SVN_ERR (svn_client_status (NULL, fullpath, 
                                      &(external->revision),
                                      status_func, status_baton, 
                                      TRUE, get_all, update, no_ignore, 
                                      ctx, iterpool));
        }
    } 
  
  /* Destroy SUBPOOL and (implicitly) ITERPOOL. */
  apr_pool_destroy (subpool);

  return SVN_NO_ERROR;
}

⌨️ 快捷键说明

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