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

📄 adm_crawler.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * adm_crawler.c:  report local WC mods to an Editor. * * ==================================================================== * Copyright (c) 2000-2006 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/. * ==================================================================== *//* ==================================================================== */#include <string.h>#include <apr_pools.h>#include <apr_file_io.h>#include <apr_hash.h>#include <apr_md5.h>#include <assert.h>#include "svn_types.h"#include "svn_pools.h"#include "svn_wc.h"#include "svn_io.h"#include "svn_md5.h"#include "svn_base64.h"#include "svn_delta.h"#include "svn_path.h"#include "wc.h"#include "adm_files.h"#include "props.h"#include "translate.h"#include "entries.h"#include "lock.h"#include "svn_private_config.h"/* Helper for report_revisions().      Perform an atomic restoration of the file FILE_PATH; that is, copy   the file's text-base to the administrative tmp area, and then move   that file to FILE_PATH with possible translations/expansions.  If   USE_COMMIT_TIMES is set, then set working file's timestamp to   last-commit-time.  Either way, set entry-timestamp to match that of   the working file when all is finished. */static svn_error_t *restore_file(const char *file_path,             svn_wc_adm_access_t *adm_access,             svn_boolean_t use_commit_times,             apr_pool_t *pool){  const char *tmp_file, *text_base_path;  svn_wc_entry_t newentry;  const char *bname;  svn_boolean_t special;  text_base_path = svn_wc__text_base_path(file_path, FALSE, pool);  bname = svn_path_basename(file_path, pool);  /* Copy / translate into a temporary file, which afterwards can     be atomically moved over the original working copy file. */  SVN_ERR(svn_wc_translated_file2(&tmp_file,                                  text_base_path, file_path, adm_access,                                  SVN_WC_TRANSLATE_FROM_NF                                  | SVN_WC_TRANSLATE_FORCE_COPY, pool));  SVN_ERR(svn_io_file_rename(tmp_file, file_path, pool));  SVN_ERR(svn_wc__maybe_set_read_only(NULL, file_path, adm_access, pool));  /* If necessary, tweak the new working file's executable bit. */  SVN_ERR(svn_wc__maybe_set_executable(NULL, file_path, adm_access, pool));  /* Remove any text conflict */  SVN_ERR(svn_wc_resolved_conflict2(file_path, adm_access, TRUE, FALSE,                                    FALSE, NULL, NULL, NULL, NULL, pool));  if (use_commit_times)    {      SVN_ERR(svn_wc__get_special(&special, file_path, adm_access, pool));     }  /* Possibly set timestamp to last-commit-time. */  if (use_commit_times && (! special))    {      const svn_wc_entry_t *entry;      SVN_ERR(svn_wc_entry(&entry, file_path, adm_access, FALSE, pool));      assert(entry != NULL);      SVN_ERR(svn_io_set_file_affected_time(entry->cmt_date,                                            file_path, pool));      newentry.text_time = entry->cmt_date;    }  else    {      SVN_ERR(svn_io_file_affected_time(&newentry.text_time,                                        file_path, pool));    }  /* Modify our entry's text-timestamp to match the working file. */  SVN_ERR(svn_wc__entry_modify(adm_access, bname,                               &newentry, SVN_WC__ENTRY_MODIFY_TEXT_TIME,                               TRUE /* do_sync now */, pool));  return SVN_NO_ERROR;}/* The recursive crawler that describes a mixed-revision working   copy to an RA layer.  Used to initiate updates.   This is a depth-first recursive walk of DIR_PATH under ADM_ACCESS.   Look at each entry and check if its revision is different than   DIR_REV.  If so, report this fact to REPORTER.  If an entry is   missing from disk, report its absence to REPORTER.  If an entry has   a different URL than expected, report that to REPORTER.  Finally,   if REPORT_EVERYTHING is set, then report all children unconditionally.   If TRAVERSAL_INFO is non-null, record this directory's   value of svn:externals in both TRAVERSAL_INFO->externals_old and   TRAVERSAL_INFO->externals_new, using wc_path + dir_path as the key,   and the raw (unparsed) value of the property as the value.  NOTE:   We set the value in both places, because its absence in just one or   the other place signals that the property was added or deleted;   thus, storing it in both places signals that it is present and, by   default, unchanged.   If RESTORE_FILES is set, then unexpectedly missing working files   will be restored from text-base and NOTIFY_FUNC/NOTIFY_BATON   will be called to report the restoration.  USE_COMMIT_TIMES is   passed to restore_file() helper. */static svn_error_t *report_revisions(svn_wc_adm_access_t *adm_access,                 const char *dir_path,                 svn_revnum_t dir_rev,                 const svn_ra_reporter2_t *reporter,                 void *report_baton,                 svn_wc_notify_func2_t notify_func,                 void *notify_baton,                 svn_boolean_t restore_files,                 svn_boolean_t recurse,                 svn_boolean_t report_everything,                 svn_boolean_t use_commit_times,                 svn_wc_traversal_info_t *traversal_info,                 apr_pool_t *pool){  apr_hash_t *entries, *dirents;  apr_hash_index_t *hi;  apr_pool_t *subpool = svn_pool_create(pool), *iterpool;  const svn_wc_entry_t *dot_entry;  const char *this_url, *this_path, *full_path, *this_full_path;  svn_wc_adm_access_t *dir_access;  svn_wc_notify_t *notify;  /* Get both the SVN Entries and the actual on-disk entries.   Also     notice that we're picking up hidden entries too. */  full_path = svn_path_join(svn_wc_adm_access_path(adm_access),                             dir_path, subpool);  SVN_ERR(svn_wc_adm_retrieve(&dir_access, adm_access, full_path, subpool));  SVN_ERR(svn_wc_entries_read(&entries, dir_access, TRUE, subpool));  SVN_ERR(svn_io_get_dir_filenames(&dirents, full_path, subpool));    /*** Do the real reporting and recursing. ***/    /* First, look at "this dir" to see what its URL is. */  dot_entry = apr_hash_get(entries, SVN_WC_ENTRY_THIS_DIR,                            APR_HASH_KEY_STRING);  /* If "this dir" has "svn:externals" property set on it, store its name     in traversal_info. */  if (traversal_info)    {      const svn_string_t *val;      SVN_ERR(svn_wc_prop_get(&val, SVN_PROP_EXTERNALS, full_path, adm_access,                              subpool));      if (val)        {          apr_pool_t *dup_pool = traversal_info->pool;          const char *dup_path = apr_pstrdup(dup_pool, full_path);          const char *dup_val = apr_pstrmemdup(dup_pool, val->data, val->len);          apr_hash_set(traversal_info->externals_old,                       dup_path, APR_HASH_KEY_STRING, dup_val);          apr_hash_set(traversal_info->externals_new,                       dup_path, APR_HASH_KEY_STRING, dup_val);        }    }  /* Looping over current directory's SVN entries: */  iterpool = svn_pool_create(subpool);  for (hi = apr_hash_first(subpool, entries); hi; hi = apr_hash_next(hi))    {      const void *key;      apr_ssize_t klen;      void *val;      const svn_wc_entry_t *current_entry;       svn_io_dirent_t *dirent;      svn_node_kind_t dirent_kind;      svn_boolean_t missing = FALSE;      /* Clear the iteration subpool here because the loop has a bunch         of 'continue' jump statements. */      svn_pool_clear(iterpool);      /* Get the next entry */      apr_hash_this(hi, &key, &klen, &val);      current_entry = val;      /* Compute the name of the entry.  Skip THIS_DIR altogether. */      if (! strcmp(key, SVN_WC_ENTRY_THIS_DIR))        continue;      /* Compute the paths and URLs we need. */      this_url = svn_path_join(dot_entry->url,                                svn_path_uri_encode(key, iterpool), iterpool);      this_path = svn_path_join(dir_path, key, iterpool);      this_full_path = svn_path_join(full_path, key, iterpool);      /*** The Big Tests: ***/      /* If the entry is 'deleted' or 'absent', make sure the server         knows it's gone... */      if (current_entry->deleted || current_entry->absent)        {          /* ...unless we're reporting everything, in which case it's already             missing on the server.  */          if (! report_everything)            SVN_ERR(reporter->delete_path(report_baton, this_path, iterpool));          continue;        }            /* Is the entry on disk?  Set a flag if not. */      dirent = apr_hash_get(dirents, key, klen);      if (! dirent)        {          /* It is possible on a case insensitive system that the             entry is not really missing, so we call our trusty but             expensive friend svn_io_check_path to be sure. */          SVN_ERR(svn_io_check_path(this_full_path, &dirent_kind,                                    iterpool));          if (dirent_kind == svn_node_none)            missing = TRUE;        }            /* From here on out, ignore any entry scheduled for addition */      if (current_entry->schedule == svn_wc_schedule_add)        continue;            /*** Files ***/      if (current_entry->kind == svn_node_file)         {          /* If the item is missing from disk, and we're supposed to             restore missing things, and it isn't missing as a result             of a scheduling operation, then ... */          if (missing               && restore_files               && (current_entry->schedule != svn_wc_schedule_delete)              && (current_entry->schedule != svn_wc_schedule_replace))            {              /* ... recreate file from text-base, and ... */              SVN_ERR(restore_file(this_full_path, dir_access,                                   use_commit_times, iterpool));                            /* ... report the restoration to the caller.  */              if (notify_func != NULL)                {                  notify = svn_wc_create_notify(this_full_path,                                                svn_wc_notify_restore,                                                iterpool);                  notify->kind = svn_node_file;                  (*notify_func)(notify_baton, notify, iterpool);                }            }          if (report_everything)            {              /* Report the file unconditionally, one way or another. */              if (strcmp(current_entry->url, this_url) != 0)                SVN_ERR(reporter->link_path(report_baton, this_path,                                            current_entry->url,                                            current_entry->revision,                                            FALSE, current_entry->lock_token,                                            iterpool));              else                SVN_ERR(reporter->set_path(report_baton, this_path,                                           current_entry->revision,                                           FALSE, current_entry->lock_token,                                           iterpool));                          }          /* Possibly report a disjoint URL ... */          else if ((current_entry->schedule != svn_wc_schedule_add)                   && (current_entry->schedule != svn_wc_schedule_replace)                   && (strcmp(current_entry->url, this_url) != 0))            SVN_ERR(reporter->link_path(report_baton,                                        this_path,                                        current_entry->url,                                        current_entry->revision,                                        FALSE,                                        current_entry->lock_token,                                        iterpool));          /* ... or perhaps just a differing revision or lock token. */          else if (current_entry->revision !=  dir_rev                   || current_entry->lock_token)            SVN_ERR(reporter->set_path(report_baton,                                       this_path,                                       current_entry->revision,                                       FALSE,                                       current_entry->lock_token,

⌨️ 快捷键说明

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