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

📄 diff.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                    svn_wc_notify_state_t *state,                    const char *path,                    const apr_array_header_t *propchanges,                    apr_hash_t *original_props,                    void *baton){  apr_array_header_t *props;  struct merge_cmd_baton *merge_b = baton;  apr_pool_t *subpool = svn_pool_create(merge_b->pool);  svn_error_t *err;  SVN_ERR(svn_categorize_props(propchanges, NULL, NULL, &props, subpool));  /* We only want to merge "regular" version properties:  by     definition, 'svn merge' shouldn't touch any data within .svn/  */  if (props->nelts)    {      err = svn_wc_merge_props(state, path, adm_access, original_props, props,                               FALSE, merge_b->dry_run, subpool);      if (err && (err->apr_err == SVN_ERR_ENTRY_NOT_FOUND                  || err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE))        {          /* if the entry doesn't exist in the wc, just 'skip' over             this part of the tree-delta. */          if (state)            *state = svn_wc_notify_state_missing;          svn_error_clear(err);          return SVN_NO_ERROR;                }      else if (err)        return err;    }  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}/* A svn_wc_diff_callbacks2_t function. */static svn_error_t *merge_file_changed(svn_wc_adm_access_t *adm_access,                   svn_wc_notify_state_t *content_state,                   svn_wc_notify_state_t *prop_state,                   const char *mine,                   const char *older,                   const char *yours,                   svn_revnum_t older_rev,                   svn_revnum_t yours_rev,                   const char *mimetype1,                   const char *mimetype2,                   const apr_array_header_t *prop_changes,                   apr_hash_t *original_props,                   void *baton){  struct merge_cmd_baton *merge_b = baton;  apr_pool_t *subpool = svn_pool_create(merge_b->pool);  /* xgettext: the '.working', '.merge-left.r%ld' and '.merge-right.r%ld'     strings are used to tag onto a filename in case of a merge conflict */  const char *target_label = _(".working");  const char *left_label = apr_psprintf(subpool,                                        _(".merge-left.r%ld"),                                        older_rev);  const char *right_label = apr_psprintf(subpool,                                         _(".merge-right.r%ld"),                                         yours_rev);  svn_boolean_t has_local_mods;  svn_boolean_t merge_required = TRUE;  enum svn_wc_merge_outcome_t merge_outcome;  /* Easy out:  no access baton means there ain't no merge target */  if (adm_access == NULL)    {      if (content_state)        *content_state = svn_wc_notify_state_missing;      if (prop_state)        *prop_state = svn_wc_notify_state_missing;      return SVN_NO_ERROR;    }    /* Other easy outs:  if the merge target isn't under version     control, or is just missing from disk, fogettaboutit.  There's no     way svn_wc_merge2() can do the merge. */  {    const svn_wc_entry_t *entry;    svn_node_kind_t kind;    SVN_ERR(svn_wc_entry(&entry, mine, adm_access, FALSE, subpool));    SVN_ERR(svn_io_check_path(mine, &kind, subpool));    /* ### a future thought:  if the file is under version control,       but the working file is missing, maybe we can 'restore' the       working file from the text-base, and then allow the merge to run?  */    if ((! entry) || (kind != svn_node_file))      {        if (content_state)          *content_state = svn_wc_notify_state_missing;        if (prop_state)          *prop_state = svn_wc_notify_state_missing;        return SVN_NO_ERROR;      }  }  /* This callback is essentially no more than a wrapper around     svn_wc_merge2().  Thank goodness that all the     diff-editor-mechanisms are doing the hard work of getting the     fulltexts! */  /* Do property merge before text merge so that keyword expansion takes     into account the new property values. */  if (prop_changes->nelts > 0)    SVN_ERR(merge_props_changed(adm_access, prop_state, mine, prop_changes,                                original_props, baton));  else    if (prop_state)      *prop_state = svn_wc_notify_state_unchanged;  if (older)    {      SVN_ERR(svn_wc_text_modified_p(&has_local_mods, mine, FALSE,                                     adm_access, subpool));      /* Special case:  if a binary file isn't locally modified, and is         exactly identical to the 'left' side of the merge, then don't         allow svn_wc_merge to produce a conflict.  Instead, just         overwrite the working file with the 'right' side of the merge.         Alternately, if the 'left' side of the merge doesn't exist in         the repository, and the 'right' side of the merge is         identical to the WC, pretend we did the merge (a no-op). */      if ((! has_local_mods)          && ((mimetype1 && svn_mime_type_is_binary(mimetype1))              || (mimetype2 && svn_mime_type_is_binary(mimetype2))))        {          /* For adds, the 'left' side of the merge doesn't exist. */          svn_boolean_t older_revision_exists =              !merge_b->add_necessitated_merge;          svn_boolean_t same_contents;          SVN_ERR(svn_io_files_contents_same_p(&same_contents,                                               (older_revision_exists ?                                                older : yours),                                               mine, subpool));          if (same_contents)            {              if (older_revision_exists && !merge_b->dry_run)                SVN_ERR(svn_io_file_rename(yours, mine, subpool));              merge_outcome = svn_wc_merge_merged;              merge_required = FALSE;            }        }        if (merge_required)        {          SVN_ERR(svn_wc_merge2(&merge_outcome,                                older, yours, mine, adm_access,                                left_label, right_label, target_label,                                merge_b->dry_run, merge_b->diff3_cmd,                                merge_b->merge_options, subpool));        }      /* Philip asks "Why?"  Why does the notification depend on whether the         file had modifications before the merge?  If the merge didn't change         the file because the local mods already included the change why does         that result it "merged" notification?  That's information available         through the status command, while the fact that the merge didn't         change the file is lost :-( */      if (content_state)        {          if (merge_outcome == svn_wc_merge_conflict)            *content_state = svn_wc_notify_state_conflicted;          else if (has_local_mods)            *content_state = svn_wc_notify_state_merged;          else if (merge_outcome == svn_wc_merge_merged)            *content_state = svn_wc_notify_state_changed;          else if (merge_outcome == svn_wc_merge_no_merge)            *content_state = svn_wc_notify_state_missing;          else /* merge_outcome == svn_wc_merge_unchanged */            *content_state = svn_wc_notify_state_unchanged;        }    }  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}/* A svn_wc_diff_callbacks2_t function. */static svn_error_t *merge_file_added(svn_wc_adm_access_t *adm_access,                 svn_wc_notify_state_t *content_state,                 svn_wc_notify_state_t *prop_state,                 const char *mine,                 const char *older,                 const char *yours,                 svn_revnum_t rev1,                 svn_revnum_t rev2,                 const char *mimetype1,                 const char *mimetype2,                 const apr_array_header_t *prop_changes,                 apr_hash_t *original_props,                 void *baton){  struct merge_cmd_baton *merge_b = baton;  apr_pool_t *subpool = svn_pool_create(merge_b->pool);  svn_node_kind_t kind;  const char *copyfrom_url;  const char *child;  int i;  apr_hash_t *new_props;  /* In most cases, we just leave prop_state as unknown, and let the     content_state what happened, so we set prop_state here to avoid that     below. */  if (prop_state)    *prop_state = svn_wc_notify_state_unknown;  /* Apply the prop changes to a new hash table. */  new_props = apr_hash_copy(subpool, original_props);  for (i = 0; i < prop_changes->nelts; ++i)    {      const svn_prop_t *prop = &APR_ARRAY_IDX(prop_changes, i, svn_prop_t);      apr_hash_set(new_props, prop->name, APR_HASH_KEY_STRING, prop->value);    }  /* Easy out:  if we have no adm_access for the parent directory,     then this portion of the tree-delta "patch" must be inapplicable.     Send a 'missing' state back;  the repos-diff editor should then     send a 'skip' notification. */  if (! adm_access)    {      if (merge_b->dry_run && merge_b->added_path          && svn_path_is_child(merge_b->added_path, mine, subpool))        {          if (content_state)            *content_state = svn_wc_notify_state_changed;          if (prop_state && apr_hash_count(new_props))            *prop_state = svn_wc_notify_state_changed;        }      else        *content_state = svn_wc_notify_state_missing;      return SVN_NO_ERROR;    }  SVN_ERR(svn_io_check_path(mine, &kind, subpool));  switch (kind)    {    case svn_node_none:      {        const svn_wc_entry_t *entry;        SVN_ERR(svn_wc_entry(&entry, mine, adm_access, FALSE, subpool));        if (entry && entry->schedule != svn_wc_schedule_delete)          {            /* It's versioned but missing. */            if (content_state)              *content_state = svn_wc_notify_state_obstructed;            return SVN_NO_ERROR;          }        if (! merge_b->dry_run)          {            child = svn_path_is_child(merge_b->target, mine, subpool);            assert(child != NULL);            copyfrom_url = svn_path_url_add_component(merge_b->url, child,                                                      subpool);            SVN_ERR(check_scheme_match(adm_access, copyfrom_url));            /* Since 'mine' doesn't exist, and this is               'merge_file_added', I hope it's safe to assume that               'older' is empty, and 'yours' is the full file.  Merely               copying 'yours' to 'mine', isn't enough; we need to get               the whole text-base and props installed too, just as if               we had called 'svn cp wc wc'. */            SVN_ERR(svn_wc_add_repos_file2(mine, adm_access,                                           yours, NULL,                                           new_props, NULL,                                           copyfrom_url,                                           rev2,                                           subpool));          }        if (content_state)          *content_state = svn_wc_notify_state_changed;        if (prop_state && apr_hash_count(new_props))          *prop_state = svn_wc_notify_state_changed;      }      break;    case svn_node_dir:      if (content_state)        {          /* directory already exists, is it under version control? */          const svn_wc_entry_t *entry;          SVN_ERR(svn_wc_entry(&entry, mine, adm_access, FALSE, subpool));          if (entry && dry_run_deleted_p(merge_b, mine))            *content_state = svn_wc_notify_state_changed;          else            /* this will make the repos_editor send a 'skipped' message */            *content_state = svn_wc_notify_state_obstructed;        }      break;    case svn_node_file:      {        /* file already exists, is it under version control? */        const svn_wc_entry_t *entry;        SVN_ERR(svn_wc_entry(&entry, mine, adm_access, FALSE, subpool));        /* If it's an unversioned file, don't touch it.  If its scheduled           for deletion, then rm removed it from the working copy and the           user must have recreated it, don't touch it */        if (!entry || entry->schedule == svn_wc_schedule_delete)          {            /* this will make the repos_editor send a 'skipped' message */            if (content_state)              *content_state = svn_wc_notify_state_obstructed;          }        else          {            if (dry_run_deleted_p(merge_b, mine))              {                if (content_state)                  *content_state = svn_wc_notify_state_changed;              }            else              {                /* Indicate that we merge because of an add to handle a                   special case for binary files with no local mods. */                  merge_b->add_necessitated_merge = TRUE;                  SVN_ERR(merge_file_changed(adm_access, content_state,                                             prop_state, mine, older, yours,                                             rev1, rev2,                                             mimetype1, mimetype2,                                             prop_changes, original_props,                                             baton));                /* Reset the state so that the baton can safely be reused                   in subsequent ops occurring during this merge. */                  merge_b->add_necessitated_merge = FALSE;              }          }        break;            }    default:      if (content_state)        *content_state = svn_wc_notify_state_unknown;      break;    }  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}/* A svn_wc_diff_callbacks2_t function. */static svn_error_t *merge_file_deleted(svn_wc_adm_access_t *adm_access,                   svn_wc_notify_state_t *state,                   const char *mine,                   const char *older,                   const char *yours,                   const char *mimetype1,                   const char *mimetype2,                   apr_hash_t *original_props,                   void *baton){  struct merge_cmd_baton *merge_b = baton;  apr_pool_t *subpool = svn_pool_create(merge_b->pool);  svn_node_kind_t kind;  svn_wc_adm_access_t *parent_access;  const char *parent_path;  svn_error_t *err;

⌨️ 快捷键说明

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