<commit_before>/*
 * copy.c:  copy/move wrappers around wc 'copy' functionality.
 *
 * ====================================================================
 * Copyright (c) 2000-2007 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */

/* ==================================================================== */




/*** Includes. ***/

#include <string.h>
#include <assert.h>
#include "svn_client.h"
#include "svn_error.h"
#include "svn_error_codes.h"
#include "svn_path.h"
#include "svn_opt.h"
#include "svn_time.h"
#include "svn_props.h"
#include "svn_mergeinfo.h"
#include "svn_pools.h"

#include "client.h"
#include "mergeinfo.h"

#include "svn_private_config.h"
#include "private/svn_wc_private.h"
#include "private/svn_mergeinfo_private.h"



/*** Code. ***/

/*
 * for each source/destination pair
 *   if (not exist src_path)
 *     return ERR_BAD_SRC error
 *
 *   if (exist dst_path)
 *     return ERR_OBSTRUCTION error
 *   else
 *     copy src_path into parent_of_dst_path as basename (dst_path)
 *
 *   if (this is a move)
 *     delete src_path
 */


/* Obtain the implied mergeinfo of repository-relative path PATH in
   *IMPLIED_MERGEINFO (e.g. every revision of the node at PATH since
   it last appeared).  REL_PATH corresponds to PATH, but is relative
   to RA_SESSION. */
static svn_error_t *
get_implied_mergeinfo(svn_ra_session_t *ra_session,
                      apr_hash_t **implied_mergeinfo,
                      const char *rel_path,
                      const char *path,
                      svn_revnum_t rev,
                      apr_pool_t *pool)
{
  svn_revnum_t oldest_rev;
  svn_merge_range_t *range;
  apr_array_header_t *rangelist;

  *implied_mergeinfo = apr_hash_make(pool);

  SVN_ERR(svn_client__oldest_rev_at_path(&oldest_rev, ra_session, rel_path,
                                         rev, pool));
  if (oldest_rev == SVN_INVALID_REVNUM)
    return SVN_NO_ERROR;

  range = apr_palloc(pool, sizeof(*range));
  range->start = oldest_rev - 1;
  range->end = rev;
  range->inheritable = TRUE;
  rangelist = apr_array_make(pool, 1, sizeof(range));
  APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = range;
  apr_hash_set(*implied_mergeinfo, path, APR_HASH_KEY_STRING, rangelist);

  return SVN_NO_ERROR;
}

/* Obtain the implied mergeinfo and the existing mergeinfo of the
   source path, combine them and return the result in
   *TARGET_MERGEINFO.  SRC_REL_PATH corresponds to SRC_PATH_OR_URL,
   but is relative to RA_SESSION. */
static svn_error_t *
calculate_target_mergeinfo(svn_ra_session_t *ra_session,
                           apr_hash_t **target_mergeinfo,
                           svn_wc_adm_access_t *adm_access,
                           const char *src_path_or_url,
                           const char *src_rel_path,
                           svn_revnum_t src_revnum,
                           apr_pool_t *pool)
{
  const char *src_path;
  apr_hash_t *src_mergeinfo = NULL;
  svn_boolean_t locally_added = FALSE;

  /* Find src path relative to the repository root. */
  SVN_ERR(svn_client__path_relative_to_root(&src_path, src_path_or_url,
                                            NULL, ra_session, adm_access,
                                            pool));

  /* If we have a schedule-add path, it doesn't have any repository mergeinfo,
     so don't bother checking. */
  if ( ! svn_path_is_url(src_path_or_url) )
    {
      const svn_wc_entry_t *entry;

      SVN_ERR(svn_wc__entry_versioned(&entry, src_path_or_url, adm_access,
                                      FALSE, pool));
      if (entry->schedule == svn_wc_schedule_add)
        locally_added = TRUE;
    }

  if (! locally_added)
    {
      /* Obtain any implied and/or existing (explicit) mergeinfo. */
      SVN_ERR(get_implied_mergeinfo(ra_session, target_mergeinfo,
                                    src_rel_path, src_path, src_revnum, pool));
      SVN_ERR(svn_client__get_repos_mergeinfo(ra_session, &src_mergeinfo,
                                              src_path, src_revnum,
                                              svn_mergeinfo_inherited, pool));
      /* Combine and return all mergeinfo. */
      if (src_mergeinfo)
        {
          SVN_ERR(svn_mergeinfo_merge(target_mergeinfo, src_mergeinfo,
                                      svn_rangelist_equal_inheritance, pool));<commit_msg>A follow-up to r26289.<commit_after>/*
 * copy.c:  copy/move wrappers around wc 'copy' functionality.
 *
 * ====================================================================
 * Copyright (c) 2000-2007 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */

/* ==================================================================== */




/*** Includes. ***/

#include <string.h>
#include <assert.h>
#include "svn_client.h"
#include "svn_error.h"
#include "svn_error_codes.h"
#include "svn_path.h"
#include "svn_opt.h"
#include "svn_time.h"
#include "svn_props.h"
#include "svn_mergeinfo.h"
#include "svn_pools.h"

#include "client.h"
#include "mergeinfo.h"

#include "svn_private_config.h"
#include "private/svn_wc_private.h"
#include "private/svn_mergeinfo_private.h"



/*** Code. ***/

/*
 * for each source/destination pair
 *   if (not exist src_path)
 *     return ERR_BAD_SRC error
 *
 *   if (exist dst_path)
 *     return ERR_OBSTRUCTION error
 *   else
 *     copy src_path into parent_of_dst_path as basename (dst_path)
 *
 *   if (this is a move)
 *     delete src_path
 */


/* Obtain the implied mergeinfo of repository-relative path PATH in
   *IMPLIED_MERGEINFO (e.g. every revision of the node at PATH since
   it last appeared).  REL_PATH corresponds to PATH, but is relative
   to RA_SESSION. */
static svn_error_t *
get_implied_mergeinfo(svn_ra_session_t *ra_session,
                      apr_hash_t **implied_mergeinfo,
                      const char *rel_path,
                      const char *path,
                      svn_revnum_t rev,
                      apr_pool_t *pool)
{
  svn_revnum_t oldest_rev;
  svn_merge_range_t *range;
  apr_array_header_t *rangelist;

  *implied_mergeinfo = apr_hash_make(pool);

  SVN_ERR(svn_client__oldest_rev_at_path(&oldest_rev, ra_session, rel_path,
                                         rev, pool));
  if (oldest_rev == SVN_INVALID_REVNUM)
    return SVN_NO_ERROR;

  range = apr_palloc(pool, sizeof(*range));
  range->start = oldest_rev - 1;
  range->end = rev;
  range->inheritable = TRUE;
  rangelist = apr_array_make(pool, 1, sizeof(range));
  APR_ARRAY_PUSH(rangelist, svn_merge_range_t *) = range;
  apr_hash_set(*implied_mergeinfo, path, APR_HASH_KEY_STRING, rangelist);

  return SVN_NO_ERROR;
}

/* Obtain the implied mergeinfo and the existing mergeinfo of the
   source path, combine them and return the result in
   *TARGET_MERGEINFO.  ADM_ACCESS may be NULL, if SRC_PATH_OR_URL is an
   URL. */
static svn_error_t *
calculate_target_mergeinfo(svn_ra_session_t *ra_session,
                           apr_hash_t **target_mergeinfo,
                           svn_wc_adm_access_t *adm_access,
                           const char *src_path_or_url,
                           const char *src_rel_path,
                           svn_revnum_t src_revnum,
                           apr_pool_t *pool)
{
  const char *src_path;
  apr_hash_t *src_mergeinfo = NULL;
  svn_boolean_t locally_added = FALSE;

  /* Find src path relative to the repository root. */
  SVN_ERR(svn_client__path_relative_to_root(&src_path, src_path_or_url,
                                            NULL, ra_session, adm_access,
                                            pool));

  /* If we have a schedule-add path, it doesn't have any repository mergeinfo,
     so don't bother checking. */
  if (adm_access)
    {
      const svn_wc_entry_t *entry;

      SVN_ERR(svn_wc__entry_versioned(&entry, src_path_or_url, adm_access,
                                      FALSE, pool));
      if (entry->schedule == svn_wc_schedule_add)
        locally_added = TRUE;
    }

  if (! locally_added)
    {
      /* Obtain any implied and/or existing (explicit) mergeinfo. */
      SVN_ERR(get_implied_mergeinfo(ra_session, target_mergeinfo,
                                    src_rel_path, src_path, src_revnum, pool));
      SVN_ERR(svn_client__get_repos_mergeinfo(ra_session, &src_mergeinfo,
                                              src_path, src_revnum,
                                              svn_mergeinfo_inherited, pool));
      /* Combine and return all mergeinfo. */
      if (src_mergeinfo)
        {
          SVN_ERR(svn_mergeinfo_merge(target_mergeinfo, src_mergeinfo,
                                      svn_rangelist_equal_inheritance, pool));
{'fraction_non_alphanumeric': 0.12292831723436706, 'fraction_numerical': 0.0027452974072191155, 'mean_word_length': 2.5754271174118504, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5373008', 'n_tokens_mistral': 3112, 'n_tokens_neox': 3013, 'n_words': 744}