diff options
author | Niall O'Higgins <niallo@cvs.openbsd.org> | 2007-06-01 17:47:48 +0000 |
---|---|---|
committer | Niall O'Higgins <niallo@cvs.openbsd.org> | 2007-06-01 17:47:48 +0000 |
commit | 55f2ba3781318b7859fa01dea8f70c83af0e2fcd (patch) | |
tree | 67b92eb83492cf561bdcde3e70c211dcc3df0783 /usr.bin | |
parent | c54ed097c1e1ef429f60d9c3b2d45d7188f30599 (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.c | 15 | ||||
-rw-r--r-- | usr.bin/cvs/commit.c | 4 | ||||
-rw-r--r-- | usr.bin/cvs/file.c | 68 | ||||
-rw-r--r-- | usr.bin/cvs/file.h | 3 | ||||
-rw-r--r-- | usr.bin/cvs/import.c | 4 | ||||
-rw-r--r-- | usr.bin/cvs/rcs.c | 141 | ||||
-rw-r--r-- | usr.bin/cvs/rcs.h | 3 | ||||
-rw-r--r-- | usr.bin/cvs/repository.c | 3 | ||||
-rw-r--r-- | usr.bin/cvs/repository.h | 1 | ||||
-rw-r--r-- | usr.bin/cvs/status.c | 4 | ||||
-rw-r--r-- | usr.bin/cvs/update.c | 4 |
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 *); |