summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorNiall O'Higgins <niallo@cvs.openbsd.org>2007-06-01 17:47:48 +0000
committerNiall O'Higgins <niallo@cvs.openbsd.org>2007-06-01 17:47:48 +0000
commit55f2ba3781318b7859fa01dea8f70c83af0e2fcd (patch)
tree67b92eb83492cf561bdcde3e70c211dcc3df0783 /usr.bin
parentc54ed097c1e1ef429f60d9c3b2d45d7188f30599 (diff)
add support for local and remote branch checkout. for example,
cvs co -rOPENBSD_3_0 works now. along the way, simplify and rationalise code and fix a few nits. ok joris@ xsa@ ray@
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/cvs/checkout.c15
-rw-r--r--usr.bin/cvs/commit.c4
-rw-r--r--usr.bin/cvs/file.c68
-rw-r--r--usr.bin/cvs/file.h3
-rw-r--r--usr.bin/cvs/import.c4
-rw-r--r--usr.bin/cvs/rcs.c141
-rw-r--r--usr.bin/cvs/rcs.h3
-rw-r--r--usr.bin/cvs/repository.c3
-rw-r--r--usr.bin/cvs/repository.h1
-rw-r--r--usr.bin/cvs/status.c4
-rw-r--r--usr.bin/cvs/update.c4
11 files changed, 132 insertions, 118 deletions
diff --git a/usr.bin/cvs/checkout.c b/usr.bin/cvs/checkout.c
index 94620c61351..b044af1cbbb 100644
--- a/usr.bin/cvs/checkout.c
+++ b/usr.bin/cvs/checkout.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: checkout.c,v 1.92 2007/02/22 06:42:09 otto Exp $ */
+/* $OpenBSD: checkout.c,v 1.93 2007/06/01 17:47:47 niallo Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
*
@@ -34,6 +34,7 @@ static void checkout_repository(const char *, const char *);
extern int prune_dirs;
extern int build_dirs;
extern int reset_stickies;
+extern char *tag;
static int flags = CR_REPO | CR_RECURSE_DIRS;
@@ -76,6 +77,9 @@ cvs_checkout(int argc, char **argv)
break;
case 'R':
break;
+ case 'r':
+ tag = xstrdup(optarg);
+ break;
default:
fatal("%s", cvs_cmd_checkout.cmd_synopsis);
}
@@ -133,6 +137,8 @@ checkout_check_repository(int argc, char **argv)
if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
cvs_client_connect_to_server();
+ if (tag != NULL)
+ cvs_client_send_request("Argument -r%s", tag);
if (reset_stickies == 1)
cvs_client_send_request("Argument -A");
@@ -282,7 +288,12 @@ cvs_checkout_file(struct cvs_file *cf, RCSNUM *rnum, int co_flags)
}
if (co_flags & CO_SETSTICKY)
- (void)xsnprintf(stickytag, sizeof(stickytag), "T%s", rev);
+ if (tag != NULL)
+ (void)xsnprintf(stickytag, sizeof(stickytag), "T%s",
+ tag);
+ else
+ (void)xsnprintf(stickytag, sizeof(stickytag), "T%s",
+ rev);
else
stickytag[0] = '\0';
diff --git a/usr.bin/cvs/commit.c b/usr.bin/cvs/commit.c
index 38ee6925a6a..4c68519b07f 100644
--- a/usr.bin/cvs/commit.c
+++ b/usr.bin/cvs/commit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: commit.c,v 1.105 2007/02/22 06:42:09 otto Exp $ */
+/* $OpenBSD: commit.c,v 1.106 2007/06/01 17:47:47 niallo Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
* Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org>
@@ -239,7 +239,7 @@ cvs_commit_local(struct cvs_file *cf)
rcsflags = RCS_CREATE;
openflags = O_CREAT | O_TRUNC | O_WRONLY;
if (cf->file_rcs != NULL) {
- if (cf->file_rcs->rf_inattic == 0)
+ if (cf->in_attic == 0)
cvs_log(LP_ERR, "warning: expected %s "
"to be in the Attic", cf->file_path);
diff --git a/usr.bin/cvs/file.c b/usr.bin/cvs/file.c
index 5816dee1416..dbc18144e52 100644
--- a/usr.bin/cvs/file.c
+++ b/usr.bin/cvs/file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file.c,v 1.189 2007/02/22 06:42:09 otto Exp $ */
+/* $OpenBSD: file.c,v 1.190 2007/06/01 17:47:47 niallo Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
@@ -504,7 +504,6 @@ cvs_file_walkdir(struct cvs_file *cf, struct cvs_recursion *cr)
if (!(cr->flags & CR_RECURSE_DIRS) &&
ent->ce_type == CVS_ENT_DIR)
continue;
-
if (ent->ce_type == CVS_ENT_DIR)
cvs_file_get(fpath, &dl);
else if (ent->ce_type == CVS_ENT_FILE)
@@ -558,6 +557,7 @@ cvs_file_classify(struct cvs_file *cf, const char *tag)
CVSENTRIES *entlist = NULL;
const char *state;
char repo[MAXPATHLEN], rcsfile[MAXPATHLEN], r1[16], r2[16];
+ char *tfname, *tpath, *p;
cvs_log(LP_TRACE, "cvs_file_classify(%s)", cf->file_path);
@@ -566,6 +566,7 @@ cvs_file_classify(struct cvs_file *cf, const char *tag)
return;
}
+
cvs_get_repository_path(cf->file_wd, repo, MAXPATHLEN);
(void)xsnprintf(rcsfile, MAXPATHLEN, "%s/%s",
repo, cf->file_name);
@@ -577,6 +578,21 @@ cvs_file_classify(struct cvs_file *cf, const char *tag)
}
cf->file_rpath = xstrdup(rcsfile);
+ /* XXX: likely wrong place for this shit */
+ /* is this file in the Attic? */
+ if (cf->file_type == CVS_FILE
+ && strstr(cf->file_rpath, CVS_PATH_ATTIC) != NULL) {
+ cf->in_attic = 1;
+ /* chop the 'Attic' out of cf->file_path */
+ if ((tfname = basename(cf->file_path)) == NULL)
+ fatal("cvs_file_classify: basename failure");
+ if ((tpath = dirname(cf->file_path)) == NULL)
+ fatal("cvs_file_classify: dirname failure");
+ if ((p = strstr(tpath, CVS_PATH_ATTIC)) == NULL)
+ fatal("cvs_file_classify: strstr failure");
+ strlcpy(cf->file_path, tpath, p - tpath + 1);
+ strlcat(cf->file_path, tfname, MAXPATHLEN);
+ }
entlist = cvs_ent_open(cf->file_wd);
cf->file_ent = cvs_ent_get(entlist, cf->file_name);
@@ -615,46 +631,46 @@ cvs_file_classify(struct cvs_file *cf, const char *tag)
break;
}
+ if (strncmp(cf->file_path, CVS_JUNK, strlen(CVS_JUNK)) == 0) {
+ cf->file_status = FILE_UNKNOWN;
+ return;
+ }
cf->repo_fd = open(cf->file_rpath, O_RDONLY);
if (cf->repo_fd != -1) {
cf->file_rcs = rcs_open(cf->file_rpath, cf->repo_fd, rflags);
if (cf->file_rcs == NULL)
fatal("cvs_file_classify: failed to parse RCS");
- cf->file_rcs->rf_inattic = 0;
- } else if (cvs_cmdop != CVS_OP_CHECKOUT) {
- (void)xsnprintf(rcsfile, MAXPATHLEN, "%s/%s/%s%s",
- repo, CVS_PATH_ATTIC, cf->file_name, RCS_FILE_EXT);
-
- cf->repo_fd = open(rcsfile, O_RDONLY);
- if (cf->repo_fd != -1) {
- xfree(cf->file_rpath);
- cf->file_rpath = xstrdup(rcsfile);
- cf->file_rcs = rcs_open(cf->file_rpath,
- cf->repo_fd, rflags);
- if (cf->file_rcs == NULL)
- fatal("cvs_file_classify: failed to parse RCS");
- cf->file_rcs->rf_inattic = 1;
- } else {
- cf->file_rcs = NULL;
- }
- } else
- cf->file_rcs = NULL;
+ } else {
+
+ fatal("cvs_file_classify: failed to open file `%s' of type %d",
+ cf->file_rpath, cf->file_type);
+ }
if (tag != NULL && cf->file_rcs != NULL) {
- if ((cf->file_rcsrev = rcs_translate_tag(tag, cf->file_rcs)) == NULL)
- fatal("cvs_file_classify: could not translate tag `%s'", tag);
+ /* if we could not translate tag, means that we should
+ * skip this file. */
+ if ((cf->file_rcsrev = rcs_translate_tag(tag, cf->file_rcs)) == NULL) {
+ cf->file_status = FILE_SKIP;
+ cvs_ent_close(entlist, ENT_NOSYNC);
+ return;
+ }
+
+ rcsnum_tostr(cf->file_rcsrev, r1, sizeof(r1));
+
} else if (cf->file_ent != NULL && cf->file_ent->ce_tag != NULL) {
cf->file_rcsrev = rcsnum_alloc();
rcsnum_cpy(cf->file_ent->ce_rev, cf->file_rcsrev, 0);
- } else if (cf->file_rcs != NULL)
+ } else if (cf->file_rcs != NULL) {
cf->file_rcsrev = rcs_head_get(cf->file_rcs);
- else
+ } else {
cf->file_rcsrev = NULL;
+ }
if (cf->file_ent != NULL)
rcsnum_tostr(cf->file_ent->ce_rev, r1, sizeof(r1));
- if (cf->file_rcsrev != NULL)
+ if (cf->file_rcsrev != NULL) {
rcsnum_tostr(cf->file_rcsrev, r2, sizeof(r2));
+ }
ismodified = rcsdead = 0;
if (cf->fd != -1 && cf->file_ent != NULL) {
diff --git a/usr.bin/cvs/file.h b/usr.bin/cvs/file.h
index 951ddf9b8da..498480dcfb3 100644
--- a/usr.bin/cvs/file.h
+++ b/usr.bin/cvs/file.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: file.h,v 1.43 2007/02/22 06:42:09 otto Exp $ */
+/* $OpenBSD: file.h,v 1.44 2007/06/01 17:47:47 niallo Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
@@ -46,6 +46,7 @@ struct cvs_file {
int file_type;
int file_status;
int file_flags;
+ int in_attic;
RCSNUM *file_rcsrev;
RCSFILE *file_rcs;
diff --git a/usr.bin/cvs/import.c b/usr.bin/cvs/import.c
index c15de550ccf..b2034ed006c 100644
--- a/usr.bin/cvs/import.c
+++ b/usr.bin/cvs/import.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: import.c,v 1.72 2007/02/22 06:42:09 otto Exp $ */
+/* $OpenBSD: import.c,v 1.73 2007/06/01 17:47:47 niallo Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
*
@@ -338,7 +338,7 @@ import_update(struct cvs_file *cf)
import_tag(cf, brev, newrev);
- if (cf->file_rcs->rf_branch == NULL || cf->file_rcs->rf_inattic == 1 ||
+ if (cf->file_rcs->rf_branch == NULL || cf->in_attic == 1 ||
strcmp(branch, import_branch)) {
import_conflicts++;
cvs_printf("C %s/%s\n", import_repository, cf->file_path);
diff --git a/usr.bin/cvs/rcs.c b/usr.bin/cvs/rcs.c
index ebdcad29a2a..7ddf5df508f 100644
--- a/usr.bin/cvs/rcs.c
+++ b/usr.bin/cvs/rcs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcs.c,v 1.212 2007/05/29 00:19:10 ray Exp $ */
+/* $OpenBSD: rcs.c,v 1.213 2007/06/01 17:47:47 niallo Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -269,7 +269,6 @@ rcs_open(const char *path, int fd, int flags, ...)
rfp->rf_mode = fmode;
rfp->fd = fd;
rfp->rf_dead = 0;
- rfp->rf_inattic = 0;
TAILQ_INIT(&(rfp->rf_delta));
TAILQ_INIT(&(rfp->rf_access));
@@ -529,14 +528,27 @@ rcs_write(RCSFILE *rfp)
RCSNUM *
rcs_head_get(RCSFILE *file)
{
- char br[16];
- RCSNUM *rev;
+ struct rcs_branch *brp;
+ struct rcs_delta *rdp;
+ RCSNUM *rev, *rootrev;
+ rev = rcsnum_alloc();
if (file->rf_branch != NULL) {
- rcsnum_tostr(file->rf_branch, br, sizeof(br));
- rev = rcs_translate_tag(br, file);
+ /* we have a default branch, use that to calculate the
+ * real HEAD*/
+ rootrev = rcsnum_alloc();
+ rcsnum_cpy(file->rf_branch, rootrev, 2);
+ if ((rdp = rcs_findrev(file, rootrev)) == NULL)
+ fatal("rcs_head_get: could not find root revision");
+
+ /* HEAD should be the last revision on the default branch */
+ TAILQ_FOREACH(brp, &(rdp->rd_branches), rb_list) {
+ if (TAILQ_NEXT(brp, rb_list) == NULL)
+ break;
+ }
+ rcsnum_free(rootrev);
+ rcsnum_cpy(brp->rb_num, rev, 0);
} else {
- rev = rcsnum_alloc();
rcsnum_cpy(file->rf_head, rev, 0);
}
@@ -2537,85 +2549,65 @@ rcs_state_get(RCSFILE *rfp, RCSNUM *rev)
return (rdp->rd_state);
}
+/* rcs_translate_tag() */
RCSNUM *
rcs_translate_tag(const char *revstr, RCSFILE *rfp)
{
- size_t i;
- char *sdate;
- RCSNUM *rev, *brev;
+ RCSNUM *rev, *brev, *frev;
struct rcs_branch *brp;
struct rcs_delta *rdp;
- time_t givendate, rcsdate;
+ size_t i;
rdp = NULL;
- rev = rcs_sym_getrev(rfp, revstr);
- if (rev == NULL) {
- if ((rev = rcsnum_parse(revstr)) == NULL) {
- if ((givendate = cvs_date_parse(revstr)) == -1)
- fatal("tag %s does not exist (0)", revstr);
-
- rcs_parse_deltas(rfp, NULL);
-
- TAILQ_FOREACH(rdp, &(rfp->rf_delta), rd_list) {
- sdate = asctime(&rdp->rd_date);
- if (sdate == NULL)
- fatal("failed to parse rcs date");
- rcsdate = cvs_date_parse(sdate);
- if (rcsdate == -1)
- fatal("failed to parse %s", sdate);
- if (givendate <= rcsdate)
- continue;
- break;
- }
+ /* Possibly we could be passed a version number */
+ if ((frev = rcsnum_parse(revstr)) != NULL)
+ return (frev);
- if (rdp == NULL)
- fatal("no revision that matches date %s",
- revstr);
+ /* More likely we will be passed a symbol */
+ rev = rcs_sym_getrev(rfp, revstr);
+
+ if (rev == NULL)
+ return (NULL);
- rev = rdp->rd_num;
- }
- }
+ /* If this isn't a branch revision, we have a problem */
+ if (!RCSNUM_ISBRANCH(rev))
+ fatal("rcs_translate_tag: tag `%s' is not a branch", revstr);
- if (RCSNUM_ISBRANCH(rev)) {
- brev = rcsnum_alloc();
- rcsnum_cpy(rev, brev, rev->rn_len - 1);
- } else {
- brev = rev;
- }
+ brev = rcsnum_alloc();
+ rcsnum_cpy(rev, brev, rev->rn_len - 1);
if ((rdp = rcs_findrev(rfp, brev)) == NULL)
- fatal("tag %s does not exist (1)", revstr);
+ fatal("rcs_translate_tag: tag `%s' does not exist", revstr);
+ rcsnum_free(brev);
- if (RCSNUM_ISBRANCH(rev)) {
- rcsnum_free(brev);
- TAILQ_FOREACH(brp, &(rdp->rd_branches), rb_list) {
- for (i = 0; i < rev->rn_len; i++) {
- if (brp->rb_num->rn_id[i] != rev->rn_id[i])
- break;
- }
-
- if (i != rev->rn_len)
- continue;
-
- break;
- }
-
- if (brp == NULL)
- return (NULL);
+ TAILQ_FOREACH(brp, &(rdp->rd_branches), rb_list) {
+ for (i = 0; i < rev->rn_len; i++)
+ if (brp->rb_num->rn_id[i] != rev->rn_id[i])
+ break;
+ if (i != rev->rn_len)
+ continue;
+ break;
+ }
+ frev = rcsnum_alloc();
+ if (brp == NULL) {
+ rcsnum_cpy(rdp->rd_num, frev, 0);
+ return (frev);
+ } else {
+ /* Fetch the delta with the correct branch num */
if ((rdp = rcs_findrev(rfp, brp->rb_num)) == NULL)
- fatal("tag %s does not exist (3)", revstr);
-
- while (rdp->rd_next->rn_len != 0) {
+ fatal("rcs_translate_tag: 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("tag %s does not exist (4)", revstr);
+ fatal("rcs_translate_tag: could not fetch branch delta");
}
-
- rcsnum_cpy(rdp->rd_num, rev, 0);
+ rcsnum_cpy(rdp->rd_num, frev, 0);
+ return (frev);
}
-
- return (rev);
}
/*
@@ -2628,7 +2620,7 @@ struct cvs_lines *
rcs_rev_getlines(RCSFILE *rfp, RCSNUM *frev)
{
size_t plen;
- int i, done, nextroot, found;
+ int i, done, nextroot;
RCSNUM *tnum, *bnum;
struct rcs_branch *brp;
struct rcs_delta *hrdp, *trdp, *rdp;
@@ -2699,17 +2691,12 @@ next:
nextroot += 2;
rcsnum_cpy(frev, bnum, nextroot);
- /* XXX strange loop and "found" set but not used */
TAILQ_FOREACH(brp, &(rdp->rd_branches), rb_list) {
- found = 1;
- for (i = 0; i < nextroot - 1; i++) {
- if (brp->rb_num->rn_id[i] != bnum->rn_id[i]) {
- found = 0;
+ for (i = 0; i < nextroot - 1; i++)
+ if (brp->rb_num->rn_id[i] != bnum->rn_id[i])
break;
- }
- }
-
- break;
+ if (i == nextroot - 1)
+ break;
}
if (brp == NULL)
diff --git a/usr.bin/cvs/rcs.h b/usr.bin/cvs/rcs.h
index ff0a4240722..f3c2e763a5a 100644
--- a/usr.bin/cvs/rcs.h
+++ b/usr.bin/cvs/rcs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rcs.h,v 1.76 2007/05/26 20:58:36 niallo Exp $ */
+/* $OpenBSD: rcs.h,v 1.77 2007/06/01 17:47:47 niallo Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -195,7 +195,6 @@ struct rcs_delta {
typedef struct rcs_file {
int fd;
int rf_dead;
- int rf_inattic;
char *rf_path;
mode_t rf_mode;
int rf_flags;
diff --git a/usr.bin/cvs/repository.c b/usr.bin/cvs/repository.c
index e0773886081..423a9ce0768 100644
--- a/usr.bin/cvs/repository.c
+++ b/usr.bin/cvs/repository.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: repository.c,v 1.12 2007/02/22 06:42:09 otto Exp $ */
+/* $OpenBSD: repository.c,v 1.13 2007/06/01 17:47:47 niallo Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
*
@@ -101,7 +101,6 @@ cvs_repository_getdir(const char *dir, const char *wdir,
while ((dp = readdir(dirp)) != NULL) {
if (!strcmp(dp->d_name, ".") ||
!strcmp(dp->d_name, "..") ||
- !strcmp(dp->d_name, CVS_PATH_ATTIC) ||
!strcmp(dp->d_name, CVS_LOCK))
continue;
diff --git a/usr.bin/cvs/repository.h b/usr.bin/cvs/repository.h
index 57233adfcb9..6375f3c4780 100644
--- a/usr.bin/cvs/repository.h
+++ b/usr.bin/cvs/repository.h
@@ -18,6 +18,7 @@
#define REPO_H
#define CVS_LOCK "#cvs.lock"
+#define CVS_JUNK "#cvs."
#define CVS_LOCK_SLEEP 30
#define CVS_LOCK_TRIES 5
diff --git a/usr.bin/cvs/status.c b/usr.bin/cvs/status.c
index ded805a93d6..b83bd963224 100644
--- a/usr.bin/cvs/status.c
+++ b/usr.bin/cvs/status.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: status.c,v 1.73 2007/02/22 06:42:09 otto Exp $ */
+/* $OpenBSD: status.c,v 1.74 2007/06/01 17:47:47 niallo Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
* Copyright (c) 2005, 2006 Xavier Santolaria <xsa@openbsd.org>
@@ -141,7 +141,7 @@ cvs_status_local(struct cvs_file *cf)
if (cf->file_status == FILE_LOST ||
cf->file_status == FILE_UNKNOWN ||
- (cf->file_rcs != NULL && cf->file_rcs->rf_inattic == 1)) {
+ (cf->file_rcs != NULL && cf->in_attic == 1)) {
(void)xsnprintf(buf, sizeof(buf), "no file %s\t",
cf->file_name);
} else
diff --git a/usr.bin/cvs/update.c b/usr.bin/cvs/update.c
index edcf37ec8e0..dce2818db7f 100644
--- a/usr.bin/cvs/update.c
+++ b/usr.bin/cvs/update.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: update.c,v 1.98 2007/05/27 21:02:23 ray Exp $ */
+/* $OpenBSD: update.c,v 1.99 2007/06/01 17:47:47 niallo Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
*
@@ -30,7 +30,7 @@ int prune_dirs = 0;
int print = 0;
int build_dirs = 0;
int reset_stickies = 0;
-static char *tag = NULL;
+char *tag = NULL;
static void update_clear_conflict(struct cvs_file *);