summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@cvs.openbsd.org>2008-02-09 11:17:03 +0000
committerTobias Stoeckmann <tobias@cvs.openbsd.org>2008-02-09 11:17:03 +0000
commit319a8108a74ced030f57257e72b02186828ce97e (patch)
tree159a230e6e498880407984b209ceef6aa0dfcacd
parente5735e95479e8a02896bc562df8d76909711b07c (diff)
Get in initial support for checkout -D. Works fine with -r support right
now. OK joris@
-rw-r--r--usr.bin/cvs/checkout.c7
-rw-r--r--usr.bin/cvs/cvs.h3
-rw-r--r--usr.bin/cvs/file.c28
-rw-r--r--usr.bin/cvs/rcs.c81
4 files changed, 98 insertions, 21 deletions
diff --git a/usr.bin/cvs/checkout.c b/usr.bin/cvs/checkout.c
index c8a3f98043a..bd1ee99a426 100644
--- a/usr.bin/cvs/checkout.c
+++ b/usr.bin/cvs/checkout.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: checkout.c,v 1.130 2008/02/07 07:50:00 xsa Exp $ */
+/* $OpenBSD: checkout.c,v 1.131 2008/02/09 11:17:02 tobias Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
*
@@ -45,6 +45,8 @@ static char *koptstr = NULL;
static int nflag = 0;
+time_t cvs_specified_date;
+
struct cvs_cmd cvs_cmd_checkout = {
CVS_OP_CHECKOUT, CVS_USE_WDIR, "checkout",
{ "co", "get" },
@@ -79,6 +81,9 @@ cvs_checkout(int argc, char **argv)
case 'c':
cvs_modules_list();
exit(0);
+ case 'D':
+ cvs_specified_date = cvs_date_parse(optarg);
+ break;
case 'd':
if (dflag != NULL)
fatal("-d specified two or more times");
diff --git a/usr.bin/cvs/cvs.h b/usr.bin/cvs/cvs.h
index bb2a5a89e3b..7eb4ed90a4a 100644
--- a/usr.bin/cvs/cvs.h
+++ b/usr.bin/cvs/cvs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cvs.h,v 1.154 2008/02/04 18:23:58 tobias Exp $ */
+/* $OpenBSD: cvs.h,v 1.155 2008/02/09 11:17:02 tobias Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -303,6 +303,7 @@ extern char *cvs_rsh;
extern char *cvs_tmpdir;
extern char *import_repository;
extern char *cvs_server_path;
+extern time_t cvs_specified_date;
extern char *cvs_specified_tag;
extern char *cvs_directory_tag;
diff --git a/usr.bin/cvs/file.c b/usr.bin/cvs/file.c
index dd215b1e958..9db785d4187 100644
--- a/usr.bin/cvs/file.c
+++ b/usr.bin/cvs/file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file.c,v 1.217 2008/02/08 22:07:50 joris Exp $ */
+/* $OpenBSD: file.c,v 1.218 2008/02/09 11:17:02 tobias Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
@@ -703,11 +703,11 @@ cvs_file_classify(struct cvs_file *cf, const char *tag)
notag = 0;
cf->file_flags |= FILE_HAS_TAG;
if (tag != NULL && cf->file_rcs != NULL) {
- if ((cf->file_rcsrev = rcs_translate_tag(tag,
- cf->file_rcs)) != NULL) {
+ if ((cf->file_rcsrev = rcs_translate_tag(tag, cf->file_rcs))
+ != NULL) {
rcsnum_tostr(cf->file_rcsrev, r1, sizeof(r1));
} else {
- cf->file_rcsrev = rcs_head_get(cf->file_rcs);
+ cf->file_rcsrev = rcs_translate_tag(NULL, cf->file_rcs);
if (cf->file_rcsrev != NULL) {
notag = 1;
cf->file_flags &= ~FILE_HAS_TAG;
@@ -717,7 +717,7 @@ cvs_file_classify(struct cvs_file *cf, const char *tag)
cf->file_rcsrev = rcsnum_alloc();
rcsnum_cpy(cf->file_ent->ce_rev, cf->file_rcsrev, 0);
} else if (cf->file_rcs != NULL) {
- cf->file_rcsrev = rcs_head_get(cf->file_rcs);
+ cf->file_rcsrev = rcs_translate_tag(NULL, cf->file_rcs);
} else {
cf->file_rcsrev = NULL;
}
@@ -745,7 +745,7 @@ cvs_file_classify(struct cvs_file *cf, const char *tag)
}
if (ismodified == 1 && cf->fd != -1 && cf->file_rcs != NULL &&
- !RCSNUM_ISBRANCH(cf->file_rcsrev)) {
+ cf->file_rcsrev != NULL && !RCSNUM_ISBRANCH(cf->file_rcsrev)) {
b1 = rcs_rev_getbuf(cf->file_rcs, cf->file_rcsrev, 0);
if (b1 == NULL)
fatal("failed to get HEAD revision for comparison");
@@ -771,7 +771,7 @@ cvs_file_classify(struct cvs_file *cf, const char *tag)
if (!strcmp(state, RCS_STATE_DEAD))
rcsdead = 1;
- if (tag == NULL &&cf->in_attic &&
+ if (cvs_specified_date == 0 && tag == NULL && cf->in_attic &&
!RCSNUM_ISBRANCHREV(cf->file_rcsrev))
rcsdead = 1;
@@ -798,7 +798,7 @@ cvs_file_classify(struct cvs_file *cf, const char *tag)
} else if (cvs_cmdop != CVS_OP_ADD) {
cf->file_status = FILE_UNKNOWN;
}
- } else if (notag == 0) {
+ } else if (notag == 0 && cf->file_rcsrev != NULL) {
cf->file_status = FILE_CHECKOUT;
} else {
cf->file_status = FILE_UPTODATE;
@@ -846,9 +846,9 @@ cvs_file_classify(struct cvs_file *cf, const char *tag)
}
break;
case CVS_ENT_REG:
- if (cf->file_rcs == NULL || rcsdead == 1 ||
- (reset_stickies == 1 && cf->in_attic == 1) ||
- (notag == 1 && tag != NULL)) {
+ if (cf->file_rcs == NULL || cf->file_rcsrev == NULL ||
+ rcsdead == 1 || (reset_stickies == 1 &&
+ cf->in_attic == 1)|| (notag == 1 && tag != NULL)) {
if (cf->fd == -1 && server_has_file == 0) {
cvs_log(LP_NOTICE,
"warning: %s's entry exists but"
@@ -874,7 +874,9 @@ cvs_file_classify(struct cvs_file *cf, const char *tag)
cf->file_status = FILE_UNLINK;
}
}
- } else {
+ } else if (cf->file_rcsrev == NULL) {
+ cf->file_status = FILE_UNLINK;
+ } else{
if (cf->fd == -1 && server_has_file == 0) {
if (cvs_cmdop != CVS_OP_REMOVE) {
cvs_log(LP_NOTICE,
@@ -882,6 +884,8 @@ cvs_file_classify(struct cvs_file *cf, const char *tag)
cf->file_path);
}
cf->file_status = FILE_LOST;
+ } else if (cf->file_rcsrev == NULL) {
+ cf->file_status = FILE_UNLINK;
} else {
if (ismodified == 1)
cf->file_status = FILE_MODIFIED;
diff --git a/usr.bin/cvs/rcs.c b/usr.bin/cvs/rcs.c
index fab8c63ad5b..a70435ef53a 100644
--- a/usr.bin/cvs/rcs.c
+++ b/usr.bin/cvs/rcs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcs.c,v 1.245 2008/02/03 16:59:11 tobias Exp $ */
+/* $OpenBSD: rcs.c,v 1.246 2008/02/09 11:17:02 tobias Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -225,6 +225,7 @@ static const char *rcs_errstrs[] = {
int rcs_errno = RCS_ERR_NOERR;
+static RCSNUM *rcs_get_revision(const char *, RCSFILE *);
int rcs_patch_lines(struct cvs_lines *, struct cvs_lines *,
struct cvs_line **, struct rcs_delta *);
static void rcs_parse_init(RCSFILE *);
@@ -2627,9 +2628,9 @@ rcs_state_get(RCSFILE *rfp, RCSNUM *rev)
return (rdp->rd_state);
}
-/* rcs_translate_tag() */
-RCSNUM *
-rcs_translate_tag(const char *revstr, RCSFILE *rfp)
+/* rcs_get_revision() */
+static RCSNUM *
+rcs_get_revision(const char *revstr, RCSFILE *rfp)
{
RCSNUM *rev, *brev, *frev;
struct rcs_branch *brp;
@@ -2677,7 +2678,7 @@ rcs_translate_tag(const char *revstr, RCSFILE *rfp)
rcsnum_cpy(rev, brev, rev->rn_len - 1);
if ((rdp = rcs_findrev(rfp, brev)) == NULL)
- fatal("rcs_translate_tag: tag `%s' does not exist", revstr);
+ fatal("rcs_get_revision: tag `%s' does not exist", revstr);
rcsnum_free(brev);
TAILQ_FOREACH(brp, &(rdp->rd_branches), rb_list) {
@@ -2697,13 +2698,15 @@ rcs_translate_tag(const char *revstr, RCSFILE *rfp)
} else {
/* Fetch the delta with the correct branch num */
if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL)
- fatal("rcs_translate_tag: could not fetch branch delta");
+ fatal("rcs_get_revision: could not fetch branch "
+ "delta");
/* Find the latest delta on that branch */
for (;;) {
if (rdp->rd_next->rn_len == 0)
break;
if ((rdp = rcs_findrev(rfp, rdp->rd_next)) == NULL)
- fatal("rcs_translate_tag: could not fetch branch delta");
+ fatal("rcs_get_revision: could not fetch "
+ "branch delta");
}
rcsnum_cpy(rdp->rd_num, frev, 0);
return (frev);
@@ -3516,3 +3519,67 @@ rcs_kwexp_line(char *rcsfile, struct rcs_delta *rdp, struct cvs_lines *lines,
line->l_needsfree = 1;
}
}
+
+/* rcs_translate_tag() */
+RCSNUM *
+rcs_translate_tag(const char *revstr, RCSFILE *rfp)
+{
+ int follow;
+ RCSNUM *brev, *frev, *rev;
+ struct rcs_delta *rdp, *trdp;
+
+ brev = frev = NULL;
+
+ if (revstr == NULL)
+ revstr = RCS_HEAD_BRANCH;
+
+ if ((rev = rcs_get_revision(revstr, rfp)) == NULL)
+ return NULL;
+
+ /* let's see if we must follow a branch */
+ if (!strcmp(revstr, RCS_HEAD_BRANCH))
+ follow = 1;
+ else {
+ frev = rcs_sym_getrev(rfp, revstr);
+
+ if (frev != NULL && RCSNUM_ISBRANCH(frev))
+ follow = 1;
+ else
+ follow = 0;
+ }
+
+ if ((rdp = rcs_findrev(rfp, rev)) == NULL)
+ fatal("rcs_datetorev: cannot find revision");
+
+ if (cvs_specified_date == 0)
+ return rev;
+
+ if (frev != NULL) {
+ brev = rcsnum_revtobr(frev);
+ brev->rn_len = rev->rn_len;
+ }
+
+ rcsnum_free(rev);
+
+ do {
+ if (timelocal(&(rdp->rd_date)) < cvs_specified_date) {
+ rev = rcsnum_alloc();
+ rcsnum_cpy(rdp->rd_num, rev, 0);
+ return rev;
+ }
+
+ if (follow && rdp->rd_next->rn_len != 0) {
+ if (brev != NULL && !rcsnum_cmp(brev, rdp->rd_num, 0))
+ break;
+
+ trdp = rcs_findrev(rfp, rdp->rd_next);
+ if (trdp == NULL)
+ fatal("failed to grab next revision");
+ rdp = trdp;
+ } else
+ follow = 0;
+ } while (follow);
+
+ return NULL;
+}
+