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

📄 log.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 4 页
字号:
                         left_label, right_label, target_label,
                         FALSE, &merge_outcome, loggy->diff3_cmd, 
                         loggy->pool));

  return SVN_NO_ERROR;
}


static svn_error_t *
log_do_file_xfer (struct log_runner *loggy,
                  const char *name,
                  enum svn_wc__xfer_action action,
                  const char **atts)
{
  svn_error_t *err;
  const char *dest = NULL;

  /* We have the name (src), and the destination is absolutely required. */
  dest = svn_xml_get_attr_value (SVN_WC__LOG_ATTR_DEST, atts);
  if (! dest)
    return svn_error_createf (pick_error_code (loggy), NULL,
                              _("Missing 'dest' attribute in '%s'"),
                              svn_wc_adm_access_path (loggy->adm_access));

  err = file_xfer_under_path (loggy->adm_access, name, dest, action,
                              loggy->pool);
  if (err)
    signal_error (loggy, err);

  return SVN_NO_ERROR;
}

/* Make file NAME in log's CWD readonly */
static svn_error_t *
log_do_file_readonly (struct log_runner *loggy,
                      const char *name)
{
  const char *full_path
    = svn_path_join (svn_wc_adm_access_path (loggy->adm_access), name,
                     loggy->pool);

  SVN_ERR (svn_io_set_file_read_only (full_path, FALSE, loggy->pool));

  return SVN_NO_ERROR;
}


/* Set file NAME in log's CWD to timestamp value in ATTS. */
static svn_error_t *
log_do_file_timestamp (struct log_runner *loggy,
                       const char *name,                       
                       const char **atts)
{
  apr_time_t timestamp;
  svn_node_kind_t kind;
  const char *full_path
    = svn_path_join (svn_wc_adm_access_path (loggy->adm_access), name,
                     loggy->pool);

  const char *timestamp_string
    = svn_xml_get_attr_value (SVN_WC__LOG_ATTR_TIMESTAMP, atts);
  svn_boolean_t is_special;
  
  if (! timestamp_string)
    return svn_error_createf (pick_error_code (loggy), NULL,
                              _("Missing 'timestamp' attribute in '%s'"),
                              svn_wc_adm_access_path (loggy->adm_access));

  /* Do not set the timestamp on special files. */
  SVN_ERR (svn_io_check_special_path (full_path, &kind, &is_special,
                                      loggy->pool));
  
  if (! is_special)
    {
      SVN_ERR (svn_time_from_cstring (&timestamp, timestamp_string,
                                      loggy->pool));
      
      SVN_ERR (svn_io_set_file_affected_time (timestamp, full_path,
                                              loggy->pool));
    }

  return SVN_NO_ERROR;
}


/* Remove file NAME in log's CWD. */
static svn_error_t *
log_do_rm (struct log_runner *loggy, const char *name)
{
  const char *full_path
    = svn_path_join (svn_wc_adm_access_path (loggy->adm_access),
                     name, loggy->pool);

  SVN_ERR (svn_io_remove_file (full_path, loggy->pool));

  return SVN_NO_ERROR;
}




static svn_error_t *
log_do_modify_entry (struct log_runner *loggy,
                     const char *name,
                     const char **atts)
{
  svn_error_t *err;
  apr_hash_t *ah = svn_xml_make_att_hash (atts, loggy->pool);
  const char *tfile;
  svn_wc_entry_t *entry;
  apr_uint32_t modify_flags;
  const char *valuestr;

  /* Convert the attributes into an entry structure. */
  SVN_ERR (svn_wc__atts_to_entry (&entry, &modify_flags, ah, loggy->pool));

  /* Make TFILE the path of the thing being modified.  */
  tfile = svn_path_join (svn_wc_adm_access_path (loggy->adm_access),
                         strcmp (name, SVN_WC_ENTRY_THIS_DIR) ? name : "",
                         loggy->pool);
      
  /* Did the log command give us any timestamps?  There are three
     possible scenarios here.  We must check both text_time
     and prop_time for each of the three scenarios.  */

  /* TEXT_TIME: */
  valuestr = apr_hash_get (ah, SVN_WC__ENTRY_ATTR_TEXT_TIME,
                           APR_HASH_KEY_STRING);

  if ((modify_flags & SVN_WC__ENTRY_MODIFY_TEXT_TIME)
      && (! strcmp (valuestr, SVN_WC_TIMESTAMP_WC)))
    {
      svn_node_kind_t tfile_kind;
      apr_time_t text_time;

      err = svn_io_check_path (tfile, &tfile_kind, loggy->pool);
      if (err)
        return svn_error_createf
          (pick_error_code (loggy), err,
           _("Error checking path '%s'"), tfile);
          
      err = svn_io_file_affected_time (&text_time, tfile, loggy->pool);
      if (err)
        return svn_error_createf
          (pick_error_code (loggy), err,
           _("Error getting 'affected time' on '%s'"), tfile);

      entry->text_time = text_time;
    }

  /* PROP_TIME: */
  valuestr = apr_hash_get (ah, SVN_WC__ENTRY_ATTR_PROP_TIME, 
                           APR_HASH_KEY_STRING);

  if ((modify_flags & SVN_WC__ENTRY_MODIFY_PROP_TIME)
      && (! strcmp (valuestr, SVN_WC_TIMESTAMP_WC)))
    {
      const char *pfile;
      svn_node_kind_t pfile_kind;
      apr_time_t prop_time;

      err = svn_wc__prop_path (&pfile, tfile, loggy->adm_access, FALSE,
                               loggy->pool);
      if (err)
        signal_error (loggy, err);
      
      err = svn_io_check_path (pfile, &pfile_kind, loggy->pool);
      if (err)
        return svn_error_createf
          (pick_error_code (loggy), err,
           _("Error checking path '%s'"), pfile);
      
      err = svn_io_file_affected_time (&prop_time, pfile, loggy->pool);
      if (err)
        return svn_error_createf
          (pick_error_code (loggy), NULL,
           _("Error getting 'affected time' on '%s'"), pfile);

      entry->prop_time = prop_time;
    }

  /* Now write the new entry out */
  err = svn_wc__entry_modify (loggy->adm_access, name,
                              entry, modify_flags, FALSE, loggy->pool);
  if (err)
    return svn_error_createf (pick_error_code (loggy), err,
                              _("Error modifying entry for '%s'"), name);
  loggy->entries_modified = TRUE;

  return SVN_NO_ERROR;
}


/* Ben sez:  this log command is (at the moment) only executed by the
   update editor.  It attempts to forcefully remove working data. */
static svn_error_t *
log_do_delete_entry (struct log_runner *loggy, const char *name)
{
  svn_wc_adm_access_t *adm_access;
  const svn_wc_entry_t *entry;
  svn_error_t *err = SVN_NO_ERROR;
  const char *full_path
    = svn_path_join (svn_wc_adm_access_path (loggy->adm_access), name,
                     loggy->pool);

  /* Figure out if 'name' is a dir or a file */
  SVN_ERR (svn_wc_adm_probe_retrieve (&adm_access, loggy->adm_access, full_path,
                                      loggy->pool));
  SVN_ERR (svn_wc_entry (&entry, full_path, adm_access, FALSE, loggy->pool));

  if (! entry)
    /* Hmm....this entry is already absent from the revision control
       system.  Chances are good that this item was removed via a
       commit from this working copy.  */
    return SVN_NO_ERROR;

  /* Remove the object from revision control -- whether it's a
     single file or recursive directory removal.  Attempt
     attempt to destroy all working files & dirs too. 
  
     ### We pass NULL, NULL for cancel_func and cancel_baton below.
     ### If they were available, it would be nice to use them. */
  if (entry->kind == svn_node_dir)
    {
      svn_wc_adm_access_t *ignored;
      
      /* If we get the right kind of error, it means the directory is
         already missing, so all we need to do is delete its entry in
         the parent directory. */
      err = svn_wc_adm_retrieve (&ignored, adm_access, full_path, loggy->pool);
      if (err)
        {
          if (err->apr_err == SVN_ERR_WC_NOT_LOCKED)
            {
              apr_hash_t *entries;

              svn_error_clear (err);
              err = SVN_NO_ERROR;

              if (entry->schedule != svn_wc_schedule_add)
                {
                  SVN_ERR (svn_wc_entries_read (&entries, loggy->adm_access,
                                                TRUE, loggy->pool));
                  svn_wc__entry_remove (entries, name);
                  SVN_ERR (svn_wc__entries_write (entries, loggy->adm_access, 
                                                  loggy->pool));
                }
            }
          else
            {
              return err;
            }
        }
      else 
        {
          err = svn_wc_remove_from_revision_control (adm_access,
                                                     SVN_WC_ENTRY_THIS_DIR,
                                                     TRUE, /* destroy */
                                                     FALSE, /* instant_error */
                                                     NULL, NULL,
                                                     loggy->pool);
        }
    }
  else if (entry->kind == svn_node_file)
    {
      err = svn_wc_remove_from_revision_control (loggy->adm_access, name,
                                                 TRUE, /* destroy */
                                                 FALSE, /* instant_error */
                                                 NULL, NULL,
                                                 loggy->pool);
    }

    if ((err) && (err->apr_err == SVN_ERR_WC_LEFT_LOCAL_MOD))
      {
        svn_error_clear (err);
        return SVN_NO_ERROR;
      }
    else
        return err;
}

/* Note:  assuming that svn_wc__log_commit() is what created all of
   the <committed...> commands, the `name' attribute will either be a
   file or SVN_WC_ENTRY_THIS_DIR. */
static svn_error_t *
log_do_committed (struct log_runner *loggy,
                  const char *name,
                  const char **atts)
{
  svn_error_t *err;
  apr_pool_t *pool = loggy->pool; 
  int is_this_dir = (strcmp (name, SVN_WC_ENTRY_THIS_DIR) == 0);
  const char *rev = svn_xml_get_attr_value (SVN_WC__LOG_ATTR_REVISION, atts);
  svn_boolean_t wc_root, overwrote_working = FALSE, remove_executable = FALSE;
  const char *full_path;
  const char *pdir, *base_name;
  apr_hash_t *entries;
  const svn_wc_entry_t *orig_entry;
  svn_wc_entry_t *entry;
  apr_time_t text_time = 0; /* By default, don't override old stamp. */
  apr_time_t prop_time = 0; /* By default, don't override old stamp. */
  svn_node_kind_t kind;
  svn_wc_adm_access_t *adm_access;

  /* Determine the actual full path of the affected item. */
  if (! is_this_dir)
    full_path = svn_path_join (svn_wc_adm_access_path (loggy->adm_access),
                               name, pool);
  else
    full_path = apr_pstrdup (pool, svn_wc_adm_access_path (loggy->adm_access));

  /*** Perform sanity checking operations ***/

  /* If no new post-commit revision was given us, bail with an error. */
  if (! rev)
    return svn_error_createf (pick_error_code (loggy), NULL,
                              _("Missing 'revision' attribute for '%s'"),
                              name);
      
  /* Read the entry for the affected item.  If we can't find the
     entry, or if the entry states that our item is not either "this
     dir" or a file kind, perhaps this isn't really the entry our log
     creator was expecting.  */
  SVN_ERR (svn_wc_adm_probe_retrieve (&adm_access, loggy->adm_access, full_path,
                                      pool));
  SVN_ERR (svn_wc_entry (&orig_entry, full_path, adm_access, TRUE, pool));
  if ((! orig_entry)
      || ((! is_this_dir) && (orig_entry->kind != svn_node_file)))
    return svn_error_createf
      (pick_error_code (loggy), NULL,
       _("Log command for directory '%s' is mislocated"), name);

  entry = svn_wc_entry_dup (orig_entry, pool);

  /*** Handle the committed deletion case ***/

  /* If the committed item was scheduled for deletion, it needs to
     now be removed from revision control.  Once that is accomplished,
     we are finished handling this item.  */
  if (entry->schedule == svn_wc_schedule_delete)
    {
      svn_revnum_t new_rev = SVN_STR_TO_REV(rev);

      /* If we are suppose to delete "this dir", drop a 'killme' file
         into my own administrative dir as a signal for svn_wc__run_log() 
         to blow away the administrative area after it is finished
         processing this logfile.  */
      if (is_this_dir)
        {
          /* Bump the revision number of this_dir anyway, so that it
             might be higher than its parent's revnum.  If it's
             higher, then the process that sees KILLME and destroys
             the directory can also place a 'deleted' dir entry in the
             parent. */
          svn_wc_entry_t tmpentry;
          tmpentry.revision = new_rev;
          tmpentry.kind = svn_node_dir;

          SVN_ERR (svn_wc__entry_modify
                   (loggy->adm_access, NULL, &tmpentry,
                    SVN_WC__ENTRY_MODIFY_REVISION | SVN_WC__ENTRY_MODIFY_KIND,
                    FALSE, pool));
          loggy->entries_modified = TRUE;

          /* Drop the 'killme' file. */
          return svn_wc__make_adm_thing (loggy->adm_access, SVN_WC__ADM_KILLME,
                                         svn_node_file, APR_OS_DEFAULT,
                                         0, pool);

        }

      /* Else, we're deleting a file, and we can safely remove files
         from revision control without screwing something else up.

         ### We pass NULL, NULL for cancel_func and cancel_baton below.
         ### If they were available, it would be nice to use them. */
      else
        {         

⌨️ 快捷键说明

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