Exemplo n.º 1
0
/* Callback for log messages: implements svn_log_entry_receiver_t and
   accumulates revision metadata into a chronologically ordered list stored in
   the baton. */
static svn_error_t *
fr_log_message_receiver(void *baton,
                        svn_log_entry_t *log_entry,
                        apr_pool_t *pool)
{
  struct fr_log_message_baton *lmb = baton;
  struct rev *rev;
  apr_hash_index_t *hi;

  rev = apr_palloc(lmb->pool, sizeof(*rev));
  rev->revision = log_entry->revision;
  rev->path = lmb->path;
  rev->next = lmb->eldest;
  lmb->eldest = rev;

  /* Duplicate log_entry revprops into rev->props */
  rev->props = apr_hash_make(lmb->pool);
  for (hi = apr_hash_first(pool, log_entry->revprops); hi;
       hi = apr_hash_next(hi))
    {
      void *val;
      const void *key;

      apr_hash_this(hi, &key, NULL, &val);
      apr_hash_set(rev->props, apr_pstrdup(lmb->pool, key), APR_HASH_KEY_STRING,
                   svn_string_dup(val, lmb->pool));
    }

  return prev_log_path(&lmb->path, &lmb->action,
                       &lmb->copyrev, log_entry->changed_paths2,
                       lmb->path, svn_node_file, log_entry->revision,
                       lmb->pool);
}
Exemplo n.º 2
0
static svn_error_t *
gls_log_receiver(void *baton,
                 svn_log_entry_t *log_entry,
                 apr_pool_t *pool)
{
  struct gls_log_receiver_baton *lrb = baton;
  const char *current_path = lrb->last_path;
  const char *prev_path;
  svn_revnum_t copyfrom_rev;

  /* If we're done, ignore this invocation. */
  if (lrb->done)
    return SVN_NO_ERROR;

  /* Figure out at which repository path our object of interest lived
     in the previous revision, and if its current location is the
     result of copy since then. */
  SVN_ERR(prev_log_path(&prev_path, NULL, &copyfrom_rev,
                        log_entry->changed_paths2, current_path,
                        lrb->kind, log_entry->revision, pool));

  /* If we've run off the end of the path's history, we need to report
     our final segment (and then, we're done). */
  if (! prev_path)
    {
      lrb->done = TRUE;
      return maybe_crop_and_send_segment(current_path, lrb->start_rev,
                                         log_entry->revision, lrb->range_end,
                                         lrb->receiver, lrb->receiver_baton,
                                         pool);
    }

  /* If there was a copy operation of interest... */
  if (SVN_IS_VALID_REVNUM(copyfrom_rev))
    {
      /* ...then report the segment between this revision and the
         last-reported revision. */
      SVN_ERR(maybe_crop_and_send_segment(current_path, lrb->start_rev,
                                          log_entry->revision, lrb->range_end,
                                          lrb->receiver, lrb->receiver_baton,
                                          pool));
      lrb->range_end = log_entry->revision - 1;

      /* And if there was a revision gap, we need to report that, too. */
      if (log_entry->revision - copyfrom_rev > 1)
        {
          SVN_ERR(maybe_crop_and_send_segment(NULL, lrb->start_rev,
                                              copyfrom_rev + 1, lrb->range_end,
                                              lrb->receiver,
                                              lrb->receiver_baton, pool));
          lrb->range_end = copyfrom_rev;
        }

      /* Update our state variables. */
      lrb->last_path = apr_pstrdup(lrb->pool, prev_path);
    }

  return SVN_NO_ERROR;
}
Exemplo n.º 3
0
/* Callback for log messages: implements svn_log_entry_receiver_t and
   accumulates revision metadata into a chronologically ordered list stored in
   the baton. */
static svn_error_t *
fr_log_message_receiver(void *baton,
                        svn_log_entry_t *log_entry,
                        apr_pool_t *pool)
{
  struct fr_log_message_baton *lmb = baton;
  struct rev *rev;

  rev = apr_palloc(lmb->pool, sizeof(*rev));
  rev->revision = log_entry->revision;
  rev->path = lmb->path;
  rev->next = lmb->eldest;
  lmb->eldest = rev;

  /* Duplicate log_entry revprops into rev->props */
  rev->props = svn_prop_hash_dup(log_entry->revprops, lmb->pool);

  return prev_log_path(&lmb->path, &lmb->action,
                       &lmb->copyrev, log_entry->changed_paths2,
                       lmb->path, svn_node_file, log_entry->revision,
                       lmb->pool);
}
Exemplo n.º 4
0
/* Implements svn_log_entry_receiver_t; helper for slow_get_locations.
   As input, takes log_receiver_baton (defined above) and attempts to
   "fill in" locations in the baton over the course of many
   iterations. */
static svn_error_t *
log_receiver(void *baton,
             svn_log_entry_t *log_entry,
             apr_pool_t *pool)
{
  struct log_receiver_baton *lrb = baton;
  apr_pool_t *hash_pool = apr_hash_pool_get(lrb->locations);
  const char *current_path = lrb->last_path;
  const char *prev_path;

  /* No paths were changed in this revision.  Nothing to do. */
  if (! log_entry->changed_paths2)
    return SVN_NO_ERROR;

  /* If we've run off the end of the path's history, there's nothing
     to do.  (This should never happen with a properly functioning
     server, since we'd get no more log messages after the one where
     path was created.  But a malfunctioning server shouldn't cause us
     to trigger an assertion failure.) */
  if (! current_path)
    return SVN_NO_ERROR;

  /* If we haven't found our peg path yet, and we are now looking at a
     revision equal to or older than the peg revision, then our
     "current" path is our peg path. */
  if ((! lrb->peg_path) && (log_entry->revision <= lrb->peg_revision))
    lrb->peg_path = apr_pstrdup(lrb->pool, current_path);

  /* Determine the paths for any of the revisions for which we haven't
     gotten paths already. */
  while (lrb->location_revisions->nelts)
    {
      svn_revnum_t next = APR_ARRAY_IDX(lrb->location_revisions,
                                        lrb->location_revisions->nelts - 1,
                                        svn_revnum_t);
      if (log_entry->revision <= next)
        {
          apr_hash_set(lrb->locations,
                       apr_pmemdup(hash_pool, &next, sizeof(next)),
                       sizeof(next),
                       apr_pstrdup(hash_pool, current_path));
          apr_array_pop(lrb->location_revisions);
        }
      else
        break;
    }

  /* Figure out at which repository path our object of interest lived
     in the previous revision. */
  SVN_ERR(prev_log_path(&prev_path, NULL, NULL, log_entry->changed_paths2,
                        current_path, lrb->kind, log_entry->revision, pool));

  /* Squirrel away our "next place to look" path (suffer the strcmp
     hit to save on allocations). */
  if (! prev_path)
    lrb->last_path = NULL;
  else if (strcmp(prev_path, current_path) != 0)
    lrb->last_path = apr_pstrdup(lrb->pool, prev_path);

  return SVN_NO_ERROR;
}