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

📄 log.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 4 页
字号:
          const svn_wc_entry_t *parentry;
          svn_wc_entry_t tmp_entry;

          SVN_ERR (svn_wc_remove_from_revision_control (loggy->adm_access,
                                                        name, FALSE, FALSE,
                                                        NULL, NULL,
                                                        pool));
          
          /* If the parent entry's working rev 'lags' behind new_rev... */
          SVN_ERR (svn_wc_entry (&parentry,
                                 svn_wc_adm_access_path (loggy->adm_access),
                                 loggy->adm_access,
                                 TRUE, pool));
          if (new_rev > parentry->revision)
            {
              /* ...then the parent's revision is now officially a
                 lie;  therefore, it must remember the file as being
                 'deleted' for a while.  Create a new, uninteresting
                 ghost entry:  */
              tmp_entry.kind = svn_node_file;
              tmp_entry.deleted = TRUE;
              tmp_entry.revision = new_rev;
              SVN_ERR (svn_wc__entry_modify
                       (loggy->adm_access, name, &tmp_entry,
                        SVN_WC__ENTRY_MODIFY_REVISION
                        | SVN_WC__ENTRY_MODIFY_KIND
                        | SVN_WC__ENTRY_MODIFY_DELETED,
                        FALSE, pool));
              loggy->entries_modified = TRUE;
            }

          return SVN_NO_ERROR;
        }
    }


  /*** Mark the committed item committed-to-date ***/

  
  /* If "this dir" has been replaced (delete + add), all its
     immmediate children *must* be either scheduled for deletion (they
     were children of "this dir" during the "delete" phase of its
     replacement), added (they are new children of the replaced dir),
     or replaced (they are new children of the replace dir that have
     the same names as children that were present during the "delete"
     phase of the replacement).  

     Children which are added or replaced will have been reported as
     individual commit targets, and thus will be re-visited by
     log_do_committed().  Children which were marked for deletion,
     however, need to be outright removed from revision control.  */
  if ((entry->schedule == svn_wc_schedule_replace) && is_this_dir)
    {
      apr_hash_index_t *hi;
              
      /* Loop over all children entries, look for items scheduled for
         deletion. */
      SVN_ERR (svn_wc_entries_read (&entries, loggy->adm_access, TRUE, pool));
      for (hi = apr_hash_first (pool, entries); hi; hi = apr_hash_next (hi))
        {
          const void *key;
          apr_ssize_t klen;
          void *val;
          const svn_wc_entry_t *cur_entry; 
          svn_wc_adm_access_t *entry_access;
                  
          /* Get the next entry */
          apr_hash_this (hi, &key, &klen, &val);
          cur_entry = (svn_wc_entry_t *) val;
                  
          /* Skip each entry that isn't scheduled for deletion. */
          if (cur_entry->schedule != svn_wc_schedule_delete)
            continue;
          
          /* Determine what arguments to hand to our removal function,
             and let BASE_NAME double as an "ok" flag to run that function. */
          base_name = NULL;
          if (cur_entry->kind == svn_node_file)
            {
              pdir = svn_wc_adm_access_path (loggy->adm_access);
              base_name = apr_pstrdup (pool, key);
              entry_access = loggy->adm_access;
            }
          else if (cur_entry->kind == svn_node_dir)
            {
              pdir = svn_path_join (svn_wc_adm_access_path (loggy->adm_access),
                                    key, pool);
              base_name = SVN_WC_ENTRY_THIS_DIR;
              SVN_ERR (svn_wc_adm_retrieve (&entry_access, loggy->adm_access,
                                            pdir, pool));
            }

          /* ### We pass NULL, NULL for cancel_func and cancel_baton below.
             ### If they were available, it would be nice to use them. */
          if (base_name)
            SVN_ERR (svn_wc_remove_from_revision_control 
                     (entry_access, base_name, FALSE, FALSE,
                      NULL, NULL, pool));
        }
    }


  /* For file commit items, we need to "install" the user's working
     file as the new `text-base' in the administrative area.  A copy
     of this file should have been dropped into our `tmp/text-base'
     directory during the commit process.  Part of this process
     involves setting the textual timestamp for this entry.  We'd like
     to just use the timestamp of the working file, but it is possible that
     at some point during the commit, the real working file might have
     changed again.  If that has happened, we'll use the timestamp of
     the copy of this file in `tmp/text-base'. */
  if (! is_this_dir)
    {
      const char *wf = full_path, *tmpf;

      /* Make sure our working file copy is present in the temp area. */
      tmpf = svn_wc__text_base_path (wf, 1, pool);
      if ((err = svn_io_check_path (tmpf, &kind, pool)))
        return svn_error_createf (pick_error_code (loggy), err,
                                  _("Error checking existence of '%s'"), name);
      if (kind == svn_node_file)
        {
          svn_boolean_t modified;
          const char *chosen;

          /* Verify that the working file is the same as the tmpf file. */
          if ((err = svn_wc__versioned_file_modcheck (&modified, wf,
                                                      loggy->adm_access,
                                                      tmpf, pool)))
            return svn_error_createf (pick_error_code (loggy), err,
                                      _("Error comparing '%s' and '%s'"),
                                      wf, tmpf);

          /* If they are the same, use the working file's timestamp,
             else use the tmpf file's timestamp. */
          chosen = modified ? tmpf : wf;

          /* Get the timestamp from our chosen file. */
          if ((err = svn_io_file_affected_time (&text_time, chosen, pool)))
            return svn_error_createf
              (pick_error_code (loggy), err,
               _("Error getting 'affected time' for '%s'"), chosen);
        }
    }
              
  /* Now check for property commits.  If a property commit occurred, a
     copy of the "working" property file should have been dumped in
     the admistrative `tmp' area.  We'll let that tmpfile's existence
     be a signal that we need to do post-commit property processing.
     Also, we have to again decide which timestamp to use (see the
     text-time case above).  */
  {
    const char *wf, *tmpf, *basef;

    /* Get property file pathnames (not from the `tmp' area) depending
       on whether we're examining a file or THIS_DIR */
    
    /* ### Logic check: if is_this_dir, then full_path is the same
       as loggy->adm_access->path, I think.  In which case we don't need the
       inline conditionals below... */
    
    SVN_ERR (svn_wc__prop_path
             (&wf,
              is_this_dir
              ? svn_wc_adm_access_path (loggy->adm_access) : full_path,
              loggy->adm_access, FALSE, pool));
    SVN_ERR (svn_wc__prop_base_path
             (&basef,
              is_this_dir
              ? svn_wc_adm_access_path (loggy->adm_access) : full_path,
              loggy->adm_access, FALSE, pool));
    
    /* If this file was replaced in the commit, then we definitely
       need to begin by removing any old residual prop-base file.  */
    if (entry->schedule == svn_wc_schedule_replace)
      {
        svn_node_kind_t kinder;
        SVN_ERR (svn_io_check_path (basef, &kinder, pool));
        if (kinder == svn_node_file)
          SVN_ERR (svn_io_remove_file (basef, pool));
      }

    SVN_ERR (svn_wc__prop_path
             (&tmpf,
              is_this_dir
              ? svn_wc_adm_access_path (loggy->adm_access) : full_path,
              loggy->adm_access, TRUE, pool));
    if ((err = svn_io_check_path (tmpf, &kind, pool)))
      return svn_error_createf (pick_error_code (loggy), err,
                                _("Error checking existence of '%s'"), name);
    if (kind == svn_node_file)
      {
        svn_boolean_t same;
        const char *chosen;
        
        /* We need to decide which prop-timestamp to use, just like we
           did with text-time above. */
        if ((err = svn_io_files_contents_same_p (&same, wf, tmpf, pool)))
          return svn_error_createf (pick_error_code (loggy), err,
                                    _("Error comparing '%s' and '%s'"),
                                    wf, tmpf);

        /* If they are the same, use the working file's timestamp,
           else use the tmp_base file's timestamp. */
        chosen = same ? wf : tmpf;

        /* Get the timestamp of our chosen file. */
        if ((err = svn_io_file_affected_time (&prop_time, chosen, pool)))
          return svn_error_createf (pick_error_code (loggy), err,
                                    _("Error getting 'affected time' of '%s'"),
                                    chosen);

        /* Examine propchanges here before installing the new
           propbase.  If the executable prop was -deleted-, then set a
           flag that will remind us to run -x after our call to
           install_committed_file(). */
        if (! is_this_dir)
          {
            int i;
            apr_array_header_t *propchanges;
            SVN_ERR (svn_wc_get_prop_diffs (&propchanges, NULL,
                                            full_path, loggy->adm_access,
                                            pool));
            for (i = 0; i < propchanges->nelts; i++)
              {
                svn_prop_t *propchange
                  = &APR_ARRAY_IDX (propchanges, i, svn_prop_t);
                
                if ((! strcmp (propchange->name, SVN_PROP_EXECUTABLE))
                    && (propchange->value == NULL))
                  {
                    remove_executable = TRUE;
                    break;
                  }
              }                
          }

        /* Make the tmp prop file the new pristine one. */
        SVN_ERR (svn_wc__prep_file_for_replacement (basef, TRUE, pool));
        SVN_ERR (svn_io_file_rename (tmpf, basef, pool));
        SVN_ERR (svn_io_set_file_read_only (basef, FALSE, pool));
      }
  }   

  /* Timestamps have been decided on, and prop-base has been installed
     if necessary.  Now we install the new text-base (if present), and
     possibly re-translate the working file. */
  if (! is_this_dir)
    {
      /* Install the new file, which may involve expanding keywords. */
      if ((err = install_committed_file
           (&overwrote_working, loggy->adm_access, name, pool)))
        return svn_error_createf
          (pick_error_code (loggy), err,
           _("Error replacing text-base of '%s'"), name);

      /* The previous call will have run +x if the executable property
         was added or already present.  But if this property was
         -removed-, (detected earlier), then run -x here on the new
         working file.  */
      if (remove_executable)
        {
          SVN_ERR (svn_io_set_file_executable (full_path,
                                               FALSE, /* chmod -x */
                                               FALSE, pool));
          overwrote_working = TRUE; /* entry needs wc-file's timestamp  */
        }
      
      /* If the working file was overwritten (due to re-translation)
         or touched (due to +x / -x), then use *that* textual
         timestamp instead. */
      if (overwrote_working)
        if ((err = svn_io_file_affected_time (&text_time, full_path, pool)))
          return svn_error_createf (pick_error_code (loggy), err,
                                    _("Error getting 'affected time' of '%s'"),
                                    full_path);
    }
    
  /* Files have been moved, and timestamps have been found.  It is now
     fime for The Big Entry Modification. */
  entry->revision = SVN_STR_TO_REV (rev);
  entry->kind = is_this_dir ? svn_node_dir : svn_node_file;
  entry->schedule = svn_wc_schedule_normal;
  entry->copied = FALSE;
  entry->deleted = FALSE;
  entry->text_time = text_time;
  entry->prop_time = prop_time;
  entry->conflict_old = NULL;
  entry->conflict_new = NULL;
  entry->conflict_wrk = NULL;
  entry->prejfile = NULL;
  entry->copyfrom_url = NULL;
  entry->copyfrom_rev = SVN_INVALID_REVNUM;
  if ((err = svn_wc__entry_modify (loggy->adm_access, name, entry,
                                   (SVN_WC__ENTRY_MODIFY_REVISION 
                                    | SVN_WC__ENTRY_MODIFY_SCHEDULE 
                                    | SVN_WC__ENTRY_MODIFY_COPIED
                                    | SVN_WC__ENTRY_MODIFY_DELETED
                                    | SVN_WC__ENTRY_MODIFY_COPYFROM_URL
                                    | SVN_WC__ENTRY_MODIFY_COPYFROM_REV
                                    | SVN_WC__ENTRY_MODIFY_CONFLICT_OLD
                                    | SVN_WC__ENTRY_MODIFY_CONFLICT_NEW
                                    | SVN_WC__ENTRY_MODIFY_CONFLICT_WRK
                                    | SVN_WC__ENTRY_MODIFY_PREJFILE
                                    | (text_time
                                       ? SVN_WC__ENTRY_MODIFY_TEXT_TIME
                                       : 0)
                                    | (prop_time
                                       ? SVN_WC__ENTRY_MODIFY_PROP_TIME
                                       : 0)
                                    | SVN_WC__ENTRY_MODIFY_FORCE),
                                   FALSE, pool)))
    return svn_error_createf
      (pick_error_code (loggy), err,
       _("Error modifying entry of '%s'"), name);
  loggy->entries_modified = TRUE;

  /* If we aren't looking at "this dir" (meaning we are looking at a
     file), we are finished.  From here on out, it's all about a
     directory's entry in its parent.  */
  if (! is_this_dir)
    return SVN_NO_ERROR;

  /* For directories, we also have to reset the state in the parent's
     entry for this directory, unless the current directory is a `WC
     root' (meaning, our parent directory on disk is not our parent in
     Version Control Land), in which case we're all finished here. */
  SVN_ERR (svn_wc_is_wc_root (&wc_root,
                              svn_wc_adm_access_path (loggy->adm_access),
                              loggy->adm_access,
                              pool));
  if (wc_root)
    return SVN_NO_ERROR;

  /* Make sure our entry exists in the parent. */
  {
    svn_wc_adm_access_t *paccess;
    svn_boolean_t unassociated = FALSE;
    
    svn_path_split (svn_wc_adm_access_path (loggy->adm_access), &pdir,
                    &base_name, pool);
    
    err = svn_wc_adm_retrieve (&paccess, loggy->adm_access, pdir, pool);
    if (err && (err->apr_err == SVN_ERR_WC_NOT_LOCKED))
      {
        svn_error_clear (err);
        SVN_ERR (svn_wc_adm_open2 (&paccess, NULL, pdir, TRUE, 0, pool));
        unassociated = TRUE;
      }
    else if (err)
      return err;
    
    SVN_ERR (svn_wc_entries_read (&entries, paccess, FALSE, pool));
    if (apr_hash_get (entries, base_name, APR_HASH_KEY_STRING))
      {
        if ((err = svn_wc__entry_modify (paccess, base_name, entry,
                                         (SVN_WC__ENTRY_MODIFY_SCHEDULE 
                                          | SVN_WC__ENTRY_MODIFY_COPIED
                                          | SVN_WC__ENTRY_MODIFY_DELETED
                                          | SVN_WC__ENTRY_MODIFY_FORCE),
                                         TRUE, pool)))
          return svn_error_createf (pick_error_code (loggy), err,
                                    _("Error modifying entry of '%s'"), name);
      }

    if (unassociated)
      SVN_ERR (svn_wc_adm_close (paccess));
  }

  return SVN_NO_ERROR;
}


/* See documentation for SVN_WC__LOG_MODIFY_WCPROP. */
static svn_error_t *
log_do_modify_wcprop (struct log_runner *loggy,
                      const char *name,
                      const char **atts)

⌨️ 快捷键说明

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