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

📄 commit.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * commit.c:  wrappers around wc commit functionality. * * ==================================================================== * 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/. * ==================================================================== *//* ==================================================================== *//*** Includes. ***/#include <string.h>#include <assert.h>#include <apr_strings.h>#include <apr_hash.h>#include <apr_md5.h>#include "svn_wc.h"#include "svn_ra.h"#include "svn_delta.h"#include "svn_subst.h"#include "svn_client.h"#include "svn_string.h"#include "svn_pools.h"#include "svn_error.h"#include "svn_path.h"#include "svn_io.h"#include "svn_md5.h"#include "svn_time.h"#include "svn_sorts.h"#include "svn_props.h"#include "client.h"#include "svn_private_config.h"/* Import context baton.   ### TODO:  Add the following items to this baton:      /` import editor/baton. `/      const svn_delta_editor_t *editor;      void *edit_baton;      /` Client context baton `/      svn_client_ctx_t `ctx;      /` Paths (keys) excluded from the import (values ignored) `/      apr_hash_t *excludes;*/typedef struct import_ctx_t{  /* Whether any changes were made to the repository */  svn_boolean_t repos_changed; } import_ctx_t;/* Apply PATH's contents (as a delta against the empty string) to   FILE_BATON in EDITOR.  Use POOL for any temporary allocation.   PROPERTIES is the set of node properties set on this file.   Fill DIGEST with the md5 checksum of the sent file; DIGEST must be   at least APR_MD5_DIGESTSIZE bytes long. */static svn_error_t *send_file_contents(const char *path,                   void *file_baton,                   const svn_delta_editor_t *editor,                   apr_hash_t *properties,                   unsigned char *digest,                   apr_pool_t *pool){  const char *tmpfile_path = NULL;  svn_stream_t *contents;  svn_txdelta_window_handler_t handler;  void *handler_baton;  apr_file_t *f;  const svn_string_t *eol_style_val = NULL, *keywords_val = NULL;  svn_boolean_t special = FALSE;  svn_subst_eol_style_t eol_style;  const char *eol;  apr_hash_t *keywords;  /* If there are properties, look for EOL-style and keywords ones. */  if (properties)    {      eol_style_val = apr_hash_get(properties, SVN_PROP_EOL_STYLE,                                   sizeof(SVN_PROP_EOL_STYLE) - 1);      keywords_val = apr_hash_get(properties, SVN_PROP_KEYWORDS,                                  sizeof(SVN_PROP_KEYWORDS) - 1);      if (apr_hash_get(properties, SVN_PROP_SPECIAL, APR_HASH_KEY_STRING))        special = TRUE;    }  /* Get an editor func that wants to consume the delta stream. */  SVN_ERR(editor->apply_textdelta(file_baton, NULL, pool,                                  &handler, &handler_baton));  if (eol_style_val)    svn_subst_eol_style_from_value(&eol_style, &eol, eol_style_val->data);  else    {      eol = NULL;      eol_style = svn_subst_eol_style_none;    }  if (keywords_val)    SVN_ERR(svn_subst_build_keywords2(&keywords, keywords_val->data,                                      APR_STRINGIFY(SVN_INVALID_REVNUM),                                      "", 0, "", pool));  else    keywords = NULL;  /* If we have EOL styles or keywords to de-translate, do it.  */  if (svn_subst_translation_required(eol_style, eol, keywords, special, TRUE))    {      const char *temp_dir;      /* Now create a new tempfile, and open a stream to it. */      SVN_ERR(svn_io_temp_dir(&temp_dir, pool));      SVN_ERR(svn_io_open_unique_file2              (NULL, &tmpfile_path,               svn_path_join(temp_dir, "svn-import", pool),               ".tmp", svn_io_file_del_on_pool_cleanup, pool));      SVN_ERR(svn_subst_translate_to_normal_form              (path, tmpfile_path, eol_style, eol, FALSE,               keywords, special, pool));    }  /* Open our contents file, either the original path or the temporary     copy we might have made above. */  SVN_ERR(svn_io_file_open(&f, tmpfile_path ? tmpfile_path : path,                           APR_READ, APR_OS_DEFAULT, pool));  contents = svn_stream_from_aprfile(f, pool);  /* Send the file's contents to the delta-window handler. */  SVN_ERR(svn_txdelta_send_stream(contents, handler, handler_baton,                                  digest, pool));  /* Close our contents file. */  SVN_ERR(svn_io_file_close(f, pool));  /* The temp file is removed by the pool cleanup run by the caller */  return SVN_NO_ERROR;}/* Import file PATH as EDIT_PATH in the repository directory indicated * by DIR_BATON in EDITOR.   * * Accumulate file paths and their batons in FILES, which must be * non-null.  (These are used to send postfix textdeltas later). * * If CTX->NOTIFY_FUNC is non-null, invoke it with CTX->NOTIFY_BATON * for each file. * * Use POOL for any temporary allocation. */static svn_error_t *import_file(const svn_delta_editor_t *editor,            void *dir_baton,            const char *path,            const char *edit_path,            import_ctx_t *import_ctx,            svn_client_ctx_t *ctx,            apr_pool_t *pool){  void *file_baton;  const char *mimetype = NULL;  unsigned char digest[APR_MD5_DIGESTSIZE];  const char *text_checksum;  apr_hash_t* properties;  apr_hash_index_t *hi;  svn_node_kind_t kind;  svn_boolean_t is_special;  SVN_ERR(svn_path_check_valid(path, pool));  SVN_ERR(svn_io_check_special_path(path, &kind, &is_special, pool));  if (kind == svn_node_unknown)    {      return svn_error_createf        (SVN_ERR_NODE_UNKNOWN_KIND, NULL,         _("Unknown or unversionable type for '%s'"),         svn_path_local_style(path, pool));    }  /* Add the file, using the pool from the FILES hash. */  SVN_ERR(editor->add_file(edit_path, dir_baton, NULL, SVN_INVALID_REVNUM,                            pool, &file_baton));  /* Remember that the repository was modified */  import_ctx->repos_changed = TRUE;  if (! is_special)    {      /* add automatic properties */      SVN_ERR(svn_client__get_auto_props(&properties, &mimetype, path, ctx,                                         pool));    }  else    properties = apr_hash_make(pool);        if (properties)    {      for (hi = apr_hash_first(pool, properties); hi; hi = apr_hash_next(hi))        {          const void *pname;          void *pval;          apr_hash_this(hi, &pname, NULL, &pval);          SVN_ERR(editor->change_file_prop(file_baton, pname, pval, pool));        }    }  if (ctx->notify_func2)    {      svn_wc_notify_t *notify        = svn_wc_create_notify(path, svn_wc_notify_commit_added, pool);      notify->kind = svn_node_file;      notify->mime_type = mimetype;      notify->content_state = notify->prop_state        = svn_wc_notify_state_inapplicable;      notify->lock_state = svn_wc_notify_lock_state_inapplicable;      (*ctx->notify_func2)(ctx->notify_baton2, notify, pool);    }  /* If this is a special file, we need to set the svn:special     property and create a temporary detranslated version in order to     send to the server. */  if (is_special)    {      apr_hash_set(properties, SVN_PROP_SPECIAL, APR_HASH_KEY_STRING,                   svn_string_create(SVN_PROP_SPECIAL_VALUE, pool));      SVN_ERR(editor->change_file_prop(file_baton, SVN_PROP_SPECIAL,                                       apr_hash_get(properties,                                                    SVN_PROP_SPECIAL,                                                    APR_HASH_KEY_STRING),                                       pool));    }  /* Now, transmit the file contents. */  SVN_ERR(send_file_contents(path, file_baton, editor,                              properties, digest, pool));  /* Finally, close the file. */  text_checksum = svn_md5_digest_to_cstring(digest, pool);  SVN_ERR(editor->close_file(file_baton, text_checksum, pool));  return SVN_NO_ERROR;}             /* Import directory PATH into the repository directory indicated by * DIR_BATON in EDITOR.  EDIT_PATH is the path imported as the root * directory, so all edits are relative to that. * * Accumulate file paths and their batons in FILES, which must be * non-null.  (These are used to send postfix textdeltas later). * * EXCLUDES is a hash whose keys are absolute paths to exclude from * the import (values are unused). *  * If NO_IGNORE is FALSE, don't import files or directories that match * ignore patterns. * * If CTX->NOTIFY_FUNC is non-null, invoke it with CTX->NOTIFY_BATON for each * directory. * * Use POOL for any temporary allocation.  */static svn_error_t *import_dir(const svn_delta_editor_t *editor,            void *dir_baton,           const char *path,           const char *edit_path,           svn_boolean_t nonrecursive,           apr_hash_t *excludes,           svn_boolean_t no_ignore,           import_ctx_t *import_ctx,           svn_client_ctx_t *ctx,           apr_pool_t *pool){  apr_pool_t *subpool = svn_pool_create(pool);  /* iteration pool */  apr_hash_t *dirents;  apr_hash_index_t *hi;  apr_array_header_t *ignores;  SVN_ERR(svn_path_check_valid(path, pool));  if (!no_ignore)    SVN_ERR(svn_wc_get_default_ignores(&ignores, ctx->config, pool));  SVN_ERR(svn_io_get_dirents2(&dirents, path, pool));  for (hi = apr_hash_first(pool, dirents); hi; hi = apr_hash_next(hi))    {      const char *this_path, *this_edit_path, *abs_path;      const svn_io_dirent_t *dirent;      const char *filename;      const void *key;      void *val;            svn_pool_clear(subpool);      apr_hash_this(hi, &key, NULL, &val);      filename = key;      dirent = val;      if (ctx->cancel_func)        SVN_ERR(ctx->cancel_func(ctx->cancel_baton));      if (svn_wc_is_adm_dir(filename, subpool))        {          /* If someone's trying to import a directory named the same             as our administrative directories, that's probably not             what they wanted to do.  If they are importing a file             with that name, something is bound to blow up when they             checkout what they've imported.  So, just skip items with             that name.  */          if (ctx->notify_func2)            {              svn_wc_notify_t *notify                = svn_wc_create_notify(svn_path_join(path, filename,                                                     subpool),                                       svn_wc_notify_skip, subpool);              notify->kind = svn_node_dir;              notify->content_state = notify->prop_state                = svn_wc_notify_state_inapplicable;              notify->lock_state = svn_wc_notify_lock_state_inapplicable;              (*ctx->notify_func2)(ctx->notify_baton2, notify, subpool);            }          continue;        }      /* Typically, we started importing from ".", in which case         edit_path is "".  So below, this_path might become "./blah",         and this_edit_path might become "blah", for example. */      this_path = svn_path_join(path, filename, subpool);      this_edit_path = svn_path_join(edit_path, filename, subpool);      /* If this is an excluded path, exclude it. */      SVN_ERR(svn_path_get_absolute(&abs_path, this_path, subpool));      if (apr_hash_get(excludes, abs_path, APR_HASH_KEY_STRING))        continue;      if ((!no_ignore) && svn_cstring_match_glob_list(filename, ignores))        continue;      /* We only import subdirectories when we're doing a regular         recursive import. */      if ((dirent->kind == svn_node_dir) && (! nonrecursive))        {          void *this_dir_baton;          /* Add the new subdirectory, getting a descent baton from             the editor. */          SVN_ERR(editor->add_directory(this_edit_path, dir_baton,                                         NULL, SVN_INVALID_REVNUM, subpool,                                        &this_dir_baton));          /* Remember that the repository was modified */          import_ctx->repos_changed = TRUE;          /* By notifying before the recursive call below, we display             a directory add before displaying adds underneath the             directory.  To do it the other way around, just move this             after the recursive call. */          if (ctx->notify_func2)            {              svn_wc_notify_t *notify                = svn_wc_create_notify(this_path, svn_wc_notify_commit_added,                                       subpool);              notify->kind = svn_node_dir;              notify->content_state = notify->prop_state                = svn_wc_notify_state_inapplicable;              notify->lock_state = svn_wc_notify_lock_state_inapplicable;              (*ctx->notify_func2)(ctx->notify_baton2, notify, subpool);            }          /* Recurse. */          SVN_ERR(import_dir(editor, this_dir_baton, this_path,                              this_edit_path, FALSE, excludes,                              no_ignore, import_ctx, ctx,                              subpool));          /* Finally, close the sub-directory. */          SVN_ERR(editor->close_directory(this_dir_baton, subpool));        }      else if (dirent->kind == svn_node_file)        {          /* Import a file. */          SVN_ERR(import_file(editor, dir_baton, this_path,                               this_edit_path, import_ctx, ctx, subpool));        }      /* We're silently ignoring things that aren't files or         directories.  If we stop doing that, here is the place to         change your world.  */    }  svn_pool_destroy(subpool);  return SVN_NO_ERROR;}

⌨️ 快捷键说明

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