Index: build.conf
===================================================================
--- build.conf	(revision 9246)
+++ build.conf	(working copy)
@@ -629,6 +629,15 @@
 # disabled for now, BROKEN.
 testing = skip
 
+[ra-get-past-location]
+type = exe
+path = subversion/tests/libsvn_ra_local
+sources = get-past-location.c
+install = fs-test
+libs = libsvn_ra libsvn_fs libsvn_delta libsvn_subr
+	aprutil apriconv apr neon
+# disabled for now, BROKEN.
+testing = skip
 
 ### Tests that don't use the C framework (rewrite?) ----------
 
Index: h
===================================================================
--- h	(revision 0)
+++ h	(revision 0)
@@ -0,0 +1 @@
+hello
Index: subversion/include/svn_fs.h
===================================================================
--- subversion/include/svn_fs.h	(revision 9246)
+++ subversion/include/svn_fs.h	(working copy)
@@ -742,8 +742,18 @@
                                       svn_revnum_t *revision,
                                       svn_fs_history_t *history,
                                       apr_pool_t *pool);
-                                      
 
+/** Set @a *past_fs_path to the location at the repository @a past_revision
+ * of the file @a fs_path present at the repository in revision @a 
+ * peg_revision.
+ */
+svn_error_t *svn_fs_trace_old_file_location (svn_fs_t *fs,
+                                             const char *fs_path,
+                                             svn_revnum_t peg_revision, 
+                                             svn_revnum_t past_revision,
+                                             const char **past_fs_path,
+                                             apr_pool_t *pool);
+
 /** Set @a *is_dir to @c TRUE iff @a path in @a root is a directory.
  * Do any necessary temporary allocation in @a pool.
  */
Index: subversion/include/svn_ra.h
===================================================================
--- subversion/include/svn_ra.h	(revision 9246)
+++ subversion/include/svn_ra.h	(working copy)
@@ -715,6 +715,18 @@
                                   const char **url,
                                   apr_pool_t *pool);
 
+  /** Set @a *past_url to the location at the repository @a past_revision
+   * of the file @a url present at the repository in revision @a peg_revision.
+   * 
+   * Use @a pool for temporary allocations.
+   */  
+  svn_error_t *(*trace_old_file_location) (void *session_baton,
+                                           const char *url,
+                                           svn_revnum_t peg_revision,
+                                           svn_revnum_t past_revision,
+                                           const char **past_url,
+                                           apr_pool_t *pool);
+
 } svn_ra_plugin_t;
 
 
Index: subversion/libsvn_fs/tree.c
===================================================================
--- subversion/libsvn_fs/tree.c	(revision 9246)
+++ subversion/libsvn_fs/tree.c	(working copy)
@@ -4293,3 +4293,45 @@
   *revision = history->revision;
   return SVN_NO_ERROR;
 }
+
+/** Set @a *past_fs_path to the location at the repository @a past_revision
+ * of the file @a fs_path present at the repository in revision @a 
+ * peg_revision.
+ */
+svn_error_t *svn_fs_trace_old_file_location (svn_fs_t *fs,
+                                             const char *fs_path,
+                                             svn_revnum_t peg_revision, 
+                                             svn_revnum_t past_revision,
+                                             const char **past_fs_path,
+                                             apr_pool_t *pool)
+{
+  svn_fs_root_t *root;
+  svn_node_kind_t kind;
+  svn_fs_history_t *history, *new_history;
+  const char *path;
+  svn_revnum_t revision;
+  
+  SVN_ERR (svn_fs_revision_root (&root, fs, peg_revision, pool));
+  SVN_ERR (svn_fs_check_path (&kind, root, fs_path, pool));
+  SVN_ERR (svn_fs_node_history (&history, root, fs_path, pool));
+  SVN_ERR (svn_fs_history_location (&path, &revision, history, pool));
+  while (history && (revision > past_revision))
+    {
+      SVN_ERR (svn_fs_history_prev (&new_history, history, TRUE, pool));
+      history = new_history;
+      if (history)
+        {
+          SVN_ERR (svn_fs_history_location (&path, &revision, history, pool));
+        }
+    }
+  if (! history)
+    {
+      return svn_error_createf (SVN_ERR_FS_NO_SUCH_REVISION, NULL,
+                                "File '%s' did not exist in revision %i",
+                                fs_path, past_revision);
+    }
+  *past_fs_path = path;
+
+  return SVN_NO_ERROR;      
+}
+
Index: subversion/libsvn_ra_local/ra_plugin.c
===================================================================
--- subversion/libsvn_ra_local/ra_plugin.c	(revision 9246)
+++ subversion/libsvn_ra_local/ra_plugin.c	(working copy)
@@ -840,8 +840,43 @@
   return SVN_NO_ERROR;
 }
 
+svn_error_t * svn_ra_local__trace_old_file_location (void *session_baton,
+                                                     const char *url,
+                                                     svn_revnum_t peg_revision,
+                                                     svn_revnum_t past_revision,
+                                                     const char **past_url,
+                                                     apr_pool_t *pool)
+{
+  svn_ra_local__session_baton_t *sbaton = session_baton;
+  int repos_url_len;
+  const char *repos_url;
+  const char *fs_path;
+  const char *past_fs_path;
 
+  /* Check that the URL is contained within the repository */
+  url = svn_path_uri_decode(url, pool);
+  repos_url = sbaton->repos_url;
+  repos_url_len = strlen(repos_url);
+  if (strncmp(url, repos_url, repos_url_len) != 0)
+    return svn_error_createf (SVN_ERR_RA_ILLEGAL_URL, NULL,
+                              "'%s'\n"
+                              "is not the same repository as\n"
+                              "'%s'", url, repos_url);
+  fs_path = url + repos_url_len;
 
+  SVN_ERR (svn_fs_trace_old_file_location (sbaton->fs, 
+                                           fs_path,
+                                           peg_revision, 
+                                           past_revision,
+                                           &past_fs_path,
+                                           pool));
+
+  *past_url = apr_psprintf(pool, "%s%s", repos_url, past_fs_path);
+
+  return SVN_NO_ERROR;
+}
+
+
 /*----------------------------------------------------------------*/
 
 /** The ra_plugin **/
@@ -866,7 +901,8 @@
   svn_ra_local__get_log,
   svn_ra_local__do_check_path,
   svn_ra_local__get_uuid,
-  svn_ra_local__get_repos_root
+  svn_ra_local__get_repos_root,
+  svn_ra_local__trace_old_file_location
 };
 
 
Index: subversion/tests/libsvn_ra_local/get-past-location.c
===================================================================
--- subversion/tests/libsvn_ra_local/get-past-location.c	(revision 0)
+++ subversion/tests/libsvn_ra_local/get-past-location.c	(revision 0)
@@ -0,0 +1,88 @@
+#include <stdlib.h>
+
+#include "svn_ra.h"
+#include "svn_pools.h"
+
+static svn_error_t * svn_main(apr_pool_t *pool, int argc, char *argv[])
+{
+  void *ra_baton;
+  svn_ra_plugin_t *plugin;
+  const char *repos_url, *file_url, *past_file_url;
+  svn_revnum_t peg_rev, past_rev;
+  void *session_baton;
+  svn_ra_callbacks_t my_ra_callbacks = { NULL, NULL, NULL, NULL, NULL, NULL };
+  void *callback_baton;
+  svn_error_t *error;
+
+  /* TODO: check that I do not get past argc. Not very critical, because
+   * this is a test helper. 
+   * */
+  repos_url = argv[1];
+  file_url = argv[2];
+  peg_rev = atoi(argv[3]);
+  past_rev = atoi(argv[4]);
+
+  callback_baton = NULL;
+  
+  /* Load all available RA implementations. */
+  SVN_ERR (svn_ra_init_ra_libs (&ra_baton, pool));
+
+  /* Get the plugin which handles "file:" URLs */
+  SVN_ERR (svn_ra_get_ra_library (&plugin, ra_baton, repos_url, pool));
+
+  SVN_ERR (plugin->open (&session_baton,
+                        repos_url,
+                        &my_ra_callbacks,
+                        callback_baton,
+                        NULL,
+                        pool));
+
+  error = plugin->trace_old_file_location (session_baton,
+                                          file_url,
+                                          peg_rev,
+                                          past_rev,
+                                          &past_file_url,
+                                          pool);
+
+  if (error == SVN_NO_ERROR)
+    {
+      printf("%s\n", past_file_url);
+    }
+  else
+    {
+      if (error->apr_err == SVN_ERR_FS_NO_SUCH_REVISION)
+        {
+          printf("%s", "notexist:\n");
+        }
+      else
+        {
+          return error;
+        }
+    }
+  
+  return SVN_NO_ERROR;
+}
+
+int main(int argc, char *argv[])
+{
+  apr_pool_t *pool;
+  svn_error_t *error;
+
+  /* Initialize the app.  Send all error messages to 'stderr'.  */
+  if (svn_cmdline_init ("get_past_revision", stderr) != EXIT_SUCCESS)
+    return EXIT_FAILURE;
+  
+
+  pool = svn_pool_create(NULL);
+
+  error = svn_main(pool, argc, argv);
+
+  if (error)
+    {
+      svn_handle_error(error, stderr, 0);
+      return EXIT_FAILURE;
+    }
+
+  return EXIT_SUCCESS;
+}
+
Index: subversion/tests/clients/cmdline/past_loc_tests.py
===================================================================
--- subversion/tests/clients/cmdline/past_loc_tests.py	(revision 0)
+++ subversion/tests/clients/cmdline/past_loc_tests.py	(revision 0)
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+#
+#  past_loc_tests.py:  testing the past location tracing function
+#
+#  Subversion is a tool for revision control. 
+#  See http://subversion.tigris.org for more information.
+#    
+# ====================================================================
+# Copyright (c) 2000-2004 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.
+#
+######################################################################
+
+# General modules
+import stat, string, sys, os, shutil, re
+
+# Our testing module
+import svntest
+from svntest import SVNAnyOutput
+
+# (abbreviation)
+Skip = svntest.testcase.Skip
+XFail = svntest.testcase.XFail
+Item = svntest.wc.StateItem
+
+
+######################################################################
+# Utilities
+#
+
+
+def get_repos_rev(sbox):
+  wc_dir = sbox.wc_dir;
+  
+  out, err = svntest.actions.run_and_verify_svn("Getting Repository Revision", 
+                                                None, [], "up", wc_dir)
+
+  mo=re.match("At revision (\\d+)\\.", out[-1])
+  if mo: 
+    return int(mo.group(1))
+  else:
+    raise svntest.Failure
+
+def get_past_url(sbox, new_url, peg_revision, past_revision):
+  get_past_location_path = os.path.join("..", "..", "libsvn_ra_local",
+                                        "ra-get-past-location")
+
+  repos_url = svntest.main.current_repo_url
+
+  out, err = svntest.main.run_command(get_past_location_path, 0, 0, 
+                                      repos_url, new_url, 
+                                      peg_revision, past_revision)
+
+  url = out[0]
+
+  if (url[-1] == "\n"):
+    url = url[:-1]
+
+  return url
+
+
+######################################################################
+# Tests
+#
+#   Each test must return on success or raise on failure.
+
+
+def get_past_loc_for_move(sbox):
+  "get the past url for a file that has been moved"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir;
+  
+  starting_revision = get_repos_rev(sbox)
+
+  mu_path = os.path.join(wc_dir, 'A', 'mu')
+  new_mu_path = os.path.join(wc_dir, "mu.new")
+
+  svntest.actions.run_and_verify_svn(None, None, [], "mv", 
+                                     mu_path, new_mu_path)
+
+  svntest.actions.run_and_verify_svn(None, None, [], 'ci',
+                                     "-m", "Commiting Move",
+                                     wc_dir)
+
+  current_revision = starting_revision + 1
+
+  old_mu_url = svntest.main.current_repo_url + "/A/mu"
+  new_mu_url = svntest.main.current_repo_url + "/mu.new"
+
+  returned_old_mu_url = get_past_url(sbox, new_mu_url, current_revision,
+                                     starting_revision)
+
+  if (returned_old_mu_url != old_mu_url):
+    print "old_mu_url (\"" + old_mu_url + "\") is not " + \
+          "returned_old_mu_url (\"" + returned_old_mu_url + "\")"
+    raise svntest.Failure
+
+
+########################################################################
+# Run the tests
+
+
+# list all tests here, starting with None:
+test_list = [ None,
+              get_past_loc_for_move,
+             ]
+
+if __name__ == '__main__':
+  svntest.main.run_tests(test_list)
+  # NOTREACHED
+
+
+### End of file.

Property changes on: subversion/tests/clients/cmdline/past_loc_tests.py
___________________________________________________________________
Name: svn:executable
   + *



