In the command-line client, forbid
[svn.git] / subversion / libsvn_client / revisions.c
blob8bc4b7a78cdd0248bb970ae88b3e0a5b47b4769c
1 /*
2 * revisions.c: discovering revisions
4 * ====================================================================
5 * Copyright (c) 2000-2007 CollabNet. All rights reserved.
7 * This software is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution. The terms
9 * are also available at http://subversion.tigris.org/license-1.html.
10 * If newer versions of this license are posted there, you may use a
11 * newer version instead, at your option.
13 * This software consists of voluntary contributions made by many
14 * individuals. For exact contribution history, see the revision
15 * history and logs, available at http://subversion.tigris.org/.
16 * ====================================================================
21 #include <apr_pools.h>
23 #include "svn_error.h"
24 #include "svn_ra.h"
25 #include "svn_path.h"
26 #include "client.h"
28 #include "svn_private_config.h"
29 #include "private/svn_wc_private.h"
34 svn_error_t *
35 svn_client__get_revision_number(svn_revnum_t *revnum,
36 svn_revnum_t *youngest_rev,
37 svn_ra_session_t *ra_session,
38 const svn_opt_revision_t *revision,
39 const char *path,
40 apr_pool_t *pool)
42 switch (revision->kind)
44 case svn_opt_revision_unspecified:
45 *revnum = SVN_INVALID_REVNUM;
46 break;
48 case svn_opt_revision_number:
49 *revnum = revision->value.number;
50 break;
52 case svn_opt_revision_head:
53 /* If our caller provided a value for HEAD that he wants us to
54 use, we'll use it. Otherwise, we have to query the
55 repository (and possible return our fetched value in
56 *YOUNGEST_REV, too). */
57 if (youngest_rev && SVN_IS_VALID_REVNUM(*youngest_rev))
59 *revnum = *youngest_rev;
61 else
63 if (! ra_session)
64 return svn_error_create(SVN_ERR_CLIENT_RA_ACCESS_REQUIRED,
65 NULL, NULL);
66 SVN_ERR(svn_ra_get_latest_revnum(ra_session, revnum, pool));
67 if (youngest_rev)
68 *youngest_rev = *revnum;
70 break;
72 case svn_opt_revision_committed:
73 case svn_opt_revision_working:
74 case svn_opt_revision_base:
75 case svn_opt_revision_previous:
77 svn_wc_adm_access_t *adm_access;
78 const svn_wc_entry_t *ent;
80 /* Sanity check. */
81 if (path == NULL)
82 return svn_error_create(SVN_ERR_CLIENT_VERSIONED_PATH_REQUIRED,
83 NULL, NULL);
85 SVN_ERR(svn_wc_adm_probe_open3(&adm_access, NULL, path, FALSE,
86 0, NULL, NULL, pool));
87 SVN_ERR(svn_wc__entry_versioned(&ent, path, adm_access, FALSE, pool));
88 SVN_ERR(svn_wc_adm_close(adm_access));
90 if ((revision->kind == svn_opt_revision_base)
91 || (revision->kind == svn_opt_revision_working))
93 *revnum = ent->revision;
95 else
97 if (! SVN_IS_VALID_REVNUM(ent->cmt_rev))
98 return svn_error_createf(SVN_ERR_CLIENT_BAD_REVISION, NULL,
99 _("Path '%s' has no committed "
100 "revision"), path);
101 *revnum = ent->cmt_rev;
102 if (revision->kind == svn_opt_revision_previous)
103 (*revnum)--;
106 break;
108 case svn_opt_revision_date:
109 /* ### When revision->kind == svn_opt_revision_date, is there an
110 ### optimization such that we can compare
111 ### revision->value->date with the committed-date in the
112 ### entries file (or rather, with some range of which
113 ### committed-date is one endpoint), and sometimes avoid a
114 ### trip over the RA layer? The only optimizations I can
115 ### think of involve examining other entries to build a
116 ### timespan across which committed-revision is known to be
117 ### the head, but it doesn't seem worth it. -kff */
118 if (! ra_session)
119 return svn_error_create(SVN_ERR_CLIENT_RA_ACCESS_REQUIRED, NULL, NULL);
120 SVN_ERR(svn_ra_get_dated_revision(ra_session, revnum,
121 revision->value.date, pool));
122 break;
124 default:
125 return svn_error_createf(SVN_ERR_CLIENT_BAD_REVISION, NULL,
126 _("Unrecognized revision type requested for "
127 "'%s'"),
128 svn_path_local_style(path, pool));
131 /* Final check -- if our caller provided a youngest revision, and
132 the number we wound up with is younger than that revision, we need
133 to stick to our caller's idea of "youngest". */
134 if (youngest_rev
135 && SVN_IS_VALID_REVNUM(*youngest_rev)
136 && SVN_IS_VALID_REVNUM(*revnum)
137 && (*revnum > *youngest_rev))
138 *revnum = *youngest_rev;
140 return SVN_NO_ERROR;
144 svn_boolean_t
145 svn_client__compare_revisions(svn_opt_revision_t *revision1,
146 svn_opt_revision_t *revision2)
148 if ((revision1->kind != revision2->kind)
149 || ((revision1->kind == svn_opt_revision_number)
150 && (revision1->value.number != revision2->value.number))
151 || ((revision1->kind == svn_opt_revision_date)
152 && (revision1->value.date != revision2->value.date)))
153 return FALSE;
155 /* Else. */
156 return TRUE;
160 svn_boolean_t
161 svn_client__revision_is_local(const svn_opt_revision_t *revision)
163 if ((revision->kind == svn_opt_revision_unspecified)
164 || (revision->kind == svn_opt_revision_head)
165 || (revision->kind == svn_opt_revision_number)
166 || (revision->kind == svn_opt_revision_date))
167 return FALSE;
168 else
169 return TRUE;