diff.c

来自「subversion-1.4.3-1.tar.gz 配置svn的源码」· C语言 代码 · 共 1,827 行 · 第 1/4 页

C
1,827
字号
        default:          break;        }    }  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}/* An editor function. */static svn_error_t *set_target_revision(void *edit_baton,                     svn_revnum_t target_revision,                    apr_pool_t *pool){  struct edit_baton *eb = edit_baton;  eb->revnum = target_revision;  return SVN_NO_ERROR;}/* An editor function. The root of the comparison hierarchy */static svn_error_t *open_root(void *edit_baton,          svn_revnum_t base_revision,          apr_pool_t *dir_pool,          void **root_baton){  struct edit_baton *eb = edit_baton;  struct dir_baton *b;  eb->root_opened = TRUE;  b = make_dir_baton(eb->anchor_path, NULL, eb, FALSE, dir_pool);  *root_baton = b;  return SVN_NO_ERROR;}/* An editor function. */static svn_error_t *delete_entry(const char *path,             svn_revnum_t base_revision,             void *parent_baton,             apr_pool_t *pool){  struct dir_baton *pb = parent_baton;  struct edit_baton *eb = pb->edit_baton;  const svn_wc_entry_t *entry;  struct dir_baton *b;  const char *empty_file;  const char *full_path = svn_path_join(pb->edit_baton->anchor_path, path,                                        pb->pool);  svn_wc_adm_access_t *adm_access;  SVN_ERR(svn_wc_adm_probe_retrieve(&adm_access, pb->edit_baton->anchor,                                    full_path, pool));  SVN_ERR(svn_wc_entry(&entry, full_path, adm_access, FALSE, pool));  /* So, it turns out that this can be NULL in at least one actual case,     if you do a nonrecursive checkout and the diff involves the addition     of one of the directories that is not present due to the fact that     your checkout is nonrecursive.  There isn't really a good way to be     sure though, since nonrecursive checkouts suck, and don't leave any     indication in .svn/entries that the directories in question are just     missing. */  if (! entry)    return SVN_NO_ERROR;  /* Mark this entry as compared in the parent directory's baton. */  apr_hash_set(pb->compared, full_path, APR_HASH_KEY_STRING, "");  /* If comparing against WORKING, skip entries that are schedule-deleted     - they don't really exist. */  if (!eb->use_text_base && entry->schedule == svn_wc_schedule_delete)    return SVN_NO_ERROR;  SVN_ERR(get_empty_file(pb->edit_baton, &empty_file));  switch (entry->kind)    {    case svn_node_file:      /* A delete is required to change working-copy into requested         revision, so diff should show this as an add. Thus compare         the empty file against the current working copy.  If         'reverse_order' is set, then show a deletion. */      if (eb->reverse_order)        {          /* Whenever showing a deletion, we show the text-base vanishing. */          /* ### This is wrong if we're diffing WORKING->repos. */          const char *textbase = svn_wc__text_base_path(full_path,                                                        FALSE, pool);          apr_hash_t *baseprops = NULL;          const char *base_mimetype;          SVN_ERR(get_base_mimetype(&base_mimetype, &baseprops,                                    adm_access, full_path, pool));          SVN_ERR(pb->edit_baton->callbacks->file_deleted                  (NULL, NULL, full_path,                   textbase,                   empty_file,                   base_mimetype,                   NULL,                   baseprops,                   pb->edit_baton->callback_baton));        }      else        {          /* Or normally, show the working file being added. */          SVN_ERR(report_wc_file_as_added(pb, adm_access, full_path, entry,                                          pool));        }      break;    case svn_node_dir:      b = make_dir_baton(full_path, pb, pb->edit_baton, FALSE, pool);      /* A delete is required to change working-copy into requested         revision, so diff should show this as an add. */      SVN_ERR(report_wc_directory_as_added(b, pool));      break;    default:      break;    }  return SVN_NO_ERROR;}/* An editor function. */static svn_error_t *add_directory(const char *path,              void *parent_baton,              const char *copyfrom_path,              svn_revnum_t copyfrom_revision,              apr_pool_t *dir_pool,              void **child_baton){  struct dir_baton *pb = parent_baton;  struct dir_baton *b;  const char *full_path;  /* ### TODO: support copyfrom? */  full_path = svn_path_join(pb->edit_baton->anchor_path, path, dir_pool);  b = make_dir_baton(full_path, pb, pb->edit_baton, TRUE, dir_pool);  *child_baton = b;  return SVN_NO_ERROR;}/* An editor function. */static svn_error_t *open_directory(const char *path,               void *parent_baton,               svn_revnum_t base_revision,               apr_pool_t *dir_pool,               void **child_baton){  struct dir_baton *pb = parent_baton;  struct dir_baton *b;  const char *full_path;  /* Allocate path from the parent pool since the memory is used in the     parent's compared hash */  full_path = svn_path_join(pb->edit_baton->anchor_path, path, pb->pool);  b = make_dir_baton(full_path, pb, pb->edit_baton, FALSE, dir_pool);  *child_baton = b;  return SVN_NO_ERROR;}/* An editor function.  When a directory is closed, all the directory * elements that have been added or replaced will already have been * diff'd. However there may be other elements in the working copy * that have not yet been considered.  */static svn_error_t *close_directory(void *dir_baton,                apr_pool_t *pool){  struct dir_baton *b = dir_baton;  struct dir_baton *pb = b->dir_baton;  /* Report the property changes on the directory itself, if necessary. */  if (b->propchanges->nelts > 0)    {      /* The working copy properties at the base of the wc->repos comparison:         either BASE or WORKING. */      apr_hash_t *originalprops;      if (b->added)        {          originalprops = apr_hash_make(b->pool);        }      else        {          svn_wc_adm_access_t *adm_access;          SVN_ERR(svn_wc_adm_retrieve(&adm_access,                                      b->edit_baton->anchor, b->path,                                      b->pool));          if (b->edit_baton->use_text_base)            {              SVN_ERR(svn_wc_get_prop_diffs(NULL, &originalprops,                                            b->path, adm_access, pool));            }          else            {              apr_hash_t *base_props, *repos_props;              int i;              SVN_ERR(svn_wc_prop_list(&originalprops, b->path,                                       b->edit_baton->anchor, pool));              /* Load the BASE and repository directory properties. */              SVN_ERR(svn_wc_get_prop_diffs(NULL, &base_props,                                            b->path, adm_access, pool));              repos_props = apr_hash_copy(pool, base_props);              for (i = 0; i < b->propchanges->nelts; ++i)                {                  const svn_prop_t *prop = &APR_ARRAY_IDX(b->propchanges, i,                                                          svn_prop_t);                  apr_hash_set(repos_props, prop->name, APR_HASH_KEY_STRING,                               prop->value);                }              /* Recalculate b->propchanges as the change between WORKING                 and repos. */              SVN_ERR(svn_prop_diffs(&b->propchanges,                                     repos_props, originalprops, b->pool));            }        }      if (! b->edit_baton->reverse_order)        reverse_propchanges(originalprops, b->propchanges, b->pool);      SVN_ERR(b->edit_baton->callbacks->dir_props_changed              (NULL, NULL,               b->path,               b->propchanges,               originalprops,               b->edit_baton->callback_baton));      /* Mark the properties of this directory as having already been         compared so that we know not to show any local modifications         later on. */      apr_hash_set(b->compared, "", 0, "");    }  /* Report local modifications for this directory.  Skip added     directories since they can only contain added elements, all of     which have already been diff'd. */  if (!b->added)    SVN_ERR(directory_elements_diff(dir_baton));  /* Mark this directory as compared in the parent directory's baton,     unless this is the root of the comparison. */  if (pb)    apr_hash_set(pb->compared, b->path, APR_HASH_KEY_STRING, "");  return SVN_NO_ERROR;}/* An editor function. */static svn_error_t *add_file(const char *path,         void *parent_baton,         const char *copyfrom_path,         svn_revnum_t copyfrom_revision,         apr_pool_t *file_pool,         void **file_baton){  struct dir_baton *pb = parent_baton;  struct file_baton *b;  const char *full_path;  /* ### TODO: support copyfrom? */  full_path = svn_path_join(pb->edit_baton->anchor_path, path, file_pool);  b = make_file_baton(full_path, TRUE, pb, file_pool);  *file_baton = b;  /* Add this filename to the parent directory's list of elements that     have been compared. */  apr_hash_set(pb->compared, apr_pstrdup(pb->pool, full_path),               APR_HASH_KEY_STRING, "");  return SVN_NO_ERROR;}/* An editor function. */static svn_error_t *open_file(const char *path,          void *parent_baton,          svn_revnum_t base_revision,          apr_pool_t *file_pool,          void **file_baton){  struct dir_baton *pb = parent_baton;  struct file_baton *b;  const char *full_path;  full_path = svn_path_join(pb->edit_baton->anchor_path, path, file_pool);  b = make_file_baton(full_path, FALSE, pb, file_pool);  *file_baton = b;  /* Add this filename to the parent directory's list of elements that     have been compared. */  apr_hash_set(pb->compared, apr_pstrdup(pb->pool, full_path),               APR_HASH_KEY_STRING, "");  return SVN_NO_ERROR;}/* 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->temp_file, b->pool));      if (b->added)        SVN_ERR(svn_io_file_close(b->original_file, b->pool));      else        {          SVN_ERR(svn_wc__close_text_base(b->original_file, b->path, 0,                                          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;  struct edit_baton *eb = b->edit_baton;  const svn_wc_entry_t *entry;  const char *parent, *base_name;  SVN_ERR(svn_wc_entry(&entry, b->wc_path, eb->anchor, FALSE, b->pool));  svn_path_split(b->wc_path, &parent, &base_name, b->pool);  /* Check to see if there is a schedule-add with history entry in     the current working copy.  If so, then this is not actually     an add, but instead a modification.*/  if (entry && entry->copyfrom_url)    b->added = FALSE;  if (b->added)    {      /* An empty file is the starting point if the file is being added */      const char *empty_file;      SVN_ERR(get_empty_file(eb, &empty_file));      SVN_ERR(svn_io_file_open(&b->original_file, empty_file,                               APR_READ, APR_OS_DEFAULT, pool));    }  else    {      /* The current text-base is the starting point if replacing */      SVN_ERR(svn_wc__open_text_base(&b->original_file, b->path,                                     APR_READ, b->pool));    }  /* This is the file that will contain the pristine repository version. It     is created in the admin temporary area. This file continues to exists     until after the diff callback is run, at which point it is deleted. */  SVN_ERR(svn_wc_create_tmp_file2(&b->temp_file, &b->temp_file_path,                                  parent, svn_io_file_del_on_pool_cleanup,                                  b->pool));  svn_txdelta_apply(svn_stream_from_aprfile(b->original_file, b->pool),                    svn_stream_from_aprfile(b->temp_file, b->pool),                    NULL,                    b->temp_file_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. */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;  const svn_wc_entry_t *entry;  const char *repos_mimetype;  const char *empty_file;  /* The BASE and repository properties of the file. */  apr_hash_t *base_props;  apr_hash_t *repos_props;  int i;  /* The path to the wc file: either BASE or WORKING. */  const char *localfile;  /* The path to the temporary copy of the pristine repository version. */  const char *temp_file_path;  svn_boolean_t modified;  /* The working copy properties at the base of the wc->repos     comparison: either BASE or WORKING. */  apr_hash_t *originalprops;  SVN_ERR(svn_wc_adm_probe_retrieve(&adm_access, b->edit_baton->anchor,                                    b->wc_path, b->pool));  SVN_ERR(svn_wc_entry(&entry, b->wc_path, adm_access, FALSE, b->pool));  SVN_ERR(get_empty_file(b->edit_baton, &empty_file));  /* Load the BASE and repository file properties. */  if (b->added)    base_props = apr_hash_make(pool);  else    SVN_ERR(svn_wc_get_prop_diffs(NULL, &base_props,                                  b->path, adm_access, pool));  repos_props = apr_hash_copy(pool, base_props);  for (i = 0; i < b->propchanges->nelts; ++i)    {      const svn_prop_t *prop = &APR_ARRAY_IDX(b->propchanges, i,                                              svn_prop_t);      apr_hash_set(repos_props, prop->name, APR_HASH_KEY_STRING,                   prop->value);    }

⌨️ 快捷键说明

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