diff options
Diffstat (limited to 'usr.bin/cvs/commit.c')
-rw-r--r-- | usr.bin/cvs/commit.c | 157 |
1 files changed, 128 insertions, 29 deletions
diff --git a/usr.bin/cvs/commit.c b/usr.bin/cvs/commit.c index 877a6284d71..02bc1240de3 100644 --- a/usr.bin/cvs/commit.c +++ b/usr.bin/cvs/commit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: commit.c,v 1.111 2007/09/23 11:19:24 joris Exp $ */ +/* $OpenBSD: commit.c,v 1.112 2007/09/24 13:44:20 joris Exp $ */ /* * Copyright (c) 2006 Joris Vink <joris@openbsd.org> * Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org> @@ -30,7 +30,7 @@ void cvs_commit_local(struct cvs_file *); void cvs_commit_check_files(struct cvs_file *); -static BUF *commit_diff_file(struct cvs_file *); +static BUF *commit_diff(struct cvs_file *, RCSNUM *, int); static void commit_desc_set(struct cvs_file *); struct cvs_flisthead files_affected; @@ -152,6 +152,10 @@ cvs_commit(int argc, char **argv) void cvs_commit_check_files(struct cvs_file *cf) { + char *tag; + RCSNUM *branch, *brev; + char rev[CVS_REV_BUFSZ]; + cvs_log(LP_TRACE, "cvs_commit_check_files(%s)", cf->file_path); if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) @@ -189,6 +193,51 @@ cvs_commit_check_files(struct cvs_file *cf) return; } + if (current_cvsroot->cr_method == CVS_METHOD_LOCAL) { + tag = cvs_directory_tag; + if (cf->file_ent != NULL) + tag = cf->file_ent->ce_tag; + + if (tag != NULL && cf->file_rcs != NULL) { + brev = rcs_sym_getrev(cf->file_rcs, tag); + if (brev != NULL) { + if (RCSNUM_ISBRANCH(brev)) + goto next; + } + + brev = rcs_translate_tag(tag, cf->file_rcs); + + if (brev == NULL) { + fatal("failed to resolve tag: %s", + cf->file_ent->ce_tag); + } + + rcsnum_tostr(brev, rev, sizeof(rev)); + if ((branch = rcsnum_revtobr(brev)) == NULL) { + cvs_log(LP_ERR, "%s is not a branch revision", + rev); + conflicts_found++; + return; + } + + if (!RCSNUM_ISBRANCHREV(brev)) { + cvs_log(LP_ERR, "%s is not a branch revision", + rev); + conflicts_found++; + return; + } + + rcsnum_tostr(branch, rev, sizeof(rev)); + if (!RCSNUM_ISBRANCH(branch)) { + cvs_log(LP_ERR, "%s (%s) is not a branch", + cf->file_ent->ce_tag, rev); + conflicts_found++; + return; + } + } + } + +next: if (cf->file_status == FILE_ADDED || cf->file_status == FILE_REMOVED || cf->file_status == FILE_MODIFIED) @@ -210,11 +259,12 @@ cvs_commit_check_files(struct cvs_file *cf) void cvs_commit_local(struct cvs_file *cf) { + char *tag; BUF *b, *d; - int isnew, histtype; - RCSNUM *head; + int onbranch, isnew, histtype; + RCSNUM *nrev, *crev, *rrev, *brev; int openflags, rcsflags; - char rbuf[24], nbuf[24]; + char foo[24], rbuf[24], nbuf[24]; CVSENTRIES *entlist; char attic[MAXPATHLEN], repo[MAXPATHLEN], rcsfile[MAXPATHLEN]; @@ -234,12 +284,52 @@ cvs_commit_local(struct cvs_file *cf) return; } + onbranch = 0; + nrev = RCS_HEAD_REV; + crev = NULL; + rrev = NULL; + if (cf->file_status == FILE_MODIFIED || cf->file_status == FILE_REMOVED || (cf->file_status == FILE_ADDED && cf->file_rcs != NULL && cf->file_rcs->rf_dead == 1)) { - head = rcs_head_get(cf->file_rcs); - rcsnum_tostr(head, rbuf, sizeof(rbuf)); - rcsnum_free(head); + rrev = rcs_head_get(cf->file_rcs); + crev = rcs_head_get(cf->file_rcs); + + tag = cvs_directory_tag; + if (cf->file_ent != NULL && cf->file_ent->ce_tag != NULL) + tag = cf->file_ent->ce_tag; + + if (tag != NULL) { + rcsnum_free(crev); + crev = rcs_translate_tag(tag, cf->file_rcs); + if (crev == NULL) { + fatal("failed to resolve existing tag: %s", + tag); + } + + if (RCSNUM_ISBRANCHREV(crev)) { + nrev = rcsnum_alloc(); + rcsnum_cpy(crev, nrev, 0); + rcsnum_inc(nrev); + } else if (!RCSNUM_ISBRANCH(crev)) { + brev = rcs_sym_getrev(cf->file_rcs, tag); + if (brev == NULL) + fatal("no more tag?"); + nrev = rcsnum_brtorev(brev); + if (nrev == NULL) + fatal("failed to create branch rev"); + } else { + fatal("this isnt suppose to happen, honestly"); + } + + rcsnum_free(rrev); + rrev = rcsnum_branch_root(nrev); + + /* branch stuff was checked in cvs_commit_check_files */ + onbranch = 1; + } + + rcsnum_tostr(crev, rbuf, sizeof(rbuf)); } else { strlcpy(rbuf, "Non-existent", sizeof(rbuf)); } @@ -295,33 +385,36 @@ cvs_commit_local(struct cvs_file *cf) cvs_printf("old revision: %s; ", rbuf); } - if (isnew == 0) - d = commit_diff_file(cf); + if (isnew == 0 && onbranch == 0) + d = commit_diff(cf, cf->file_rcs->rf_head, 0); if (cf->file_status == FILE_REMOVED) { - b = rcs_rev_getbuf(cf->file_rcs, cf->file_rcs->rf_head, 0); + b = rcs_rev_getbuf(cf->file_rcs, crev, 0); if (b == NULL) - fatal("cvs_commit_local: failed to get HEAD"); + fatal("cvs_commit_local: failed to get crev"); + } else if (onbranch == 1) { + b = commit_diff(cf, crev, 1); } else { if ((b = cvs_buf_load_fd(cf->fd, BUF_AUTOEXT)) == NULL) fatal("cvs_commit_local: failed to load file"); } - if (isnew == 0) { - if (rcs_deltatext_set(cf->file_rcs, - cf->file_rcs->rf_head, d) == -1) + if (isnew == 0 && onbranch == 0) { + if (rcs_deltatext_set(cf->file_rcs, crev, d) == -1) fatal("cvs_commit_local: failed to set delta"); } - if (rcs_rev_add(cf->file_rcs, RCS_HEAD_REV, logmsg, -1, NULL) == -1) + if (rcs_rev_add(cf->file_rcs, nrev, logmsg, -1, NULL) == -1) fatal("cvs_commit_local: failed to add new revision"); - if (rcs_deltatext_set(cf->file_rcs, cf->file_rcs->rf_head, b) == -1) + if (nrev == RCS_HEAD_REV) + nrev = cf->file_rcs->rf_head; + + if (rcs_deltatext_set(cf->file_rcs, nrev, b) == -1) fatal("cvs_commit_local: failed to set new HEAD delta"); if (cf->file_status == FILE_REMOVED) { - if (rcs_state_set(cf->file_rcs, - cf->file_rcs->rf_head, RCS_STATE_DEAD) == -1) + if (rcs_state_set(cf->file_rcs, nrev, RCS_STATE_DEAD) == -1) fatal("cvs_commit_local: failed to set state"); } @@ -345,10 +438,9 @@ cvs_commit_local(struct cvs_file *cf) if (cf->file_rcs->rf_dead == 1) strlcpy(nbuf, "Initial Revision", sizeof(nbuf)); else - rcsnum_tostr(cf->file_rcs->rf_head, - nbuf, sizeof(nbuf)); + rcsnum_tostr(nrev, nbuf, sizeof(nbuf)); } else if (cf->file_status == FILE_MODIFIED) { - rcsnum_tostr(cf->file_rcs->rf_head, nbuf, sizeof(nbuf)); + rcsnum_tostr(nrev, nbuf, sizeof(nbuf)); } if (verbosity > 1) @@ -359,7 +451,7 @@ cvs_commit_local(struct cvs_file *cf) cf->fd = -1; if (cf->file_status != FILE_REMOVED) { - cvs_checkout_file(cf, cf->file_rcs->rf_head, NULL, CO_COMMIT); + cvs_checkout_file(cf, nrev, NULL, CO_COMMIT); } else { entlist = cvs_ent_open(cf->file_wd); cvs_ent_remove(entlist, cf->file_name); @@ -407,9 +499,9 @@ cvs_commit_local(struct cvs_file *cf) } static BUF * -commit_diff_file(struct cvs_file *cf) +commit_diff(struct cvs_file *cf, RCSNUM *rev, int reverse) { - char *p1, *p2; + char *p1, *p2, *p; BUF *b1, *b2; (void)xasprintf(&p1, "%s/diff1.XXXXXXXXXX", cvs_tmpdir); @@ -422,18 +514,25 @@ commit_diff_file(struct cvs_file *cf) cvs_buf_write_stmp(b1, p1, NULL); cvs_buf_free(b1); } else { - rcs_rev_write_stmp(cf->file_rcs, cf->file_rcs->rf_head, p1, 0); + rcs_rev_write_stmp(cf->file_rcs, rev, p1, 0); } (void)xasprintf(&p2, "%s/diff2.XXXXXXXXXX", cvs_tmpdir); - rcs_rev_write_stmp(cf->file_rcs, cf->file_rcs->rf_head, p2, 0); + rcs_rev_write_stmp(cf->file_rcs, rev, p2, 0); if ((b2 = cvs_buf_alloc(128, BUF_AUTOEXT)) == NULL) - fatal("commit_diff_file: failed to create diff buf"); + fatal("commit_diff: failed to create diff buf"); diff_format = D_RCSDIFF; + + if (reverse == 1) { + p = p1; + p1 = p2; + p2 = p; + } + if (cvs_diffreg(p1, p2, b2) == D_ERROR) - fatal("commit_diff_file: failed to get RCS patch"); + fatal("commit_diff: failed to get RCS patch"); xfree(p1); xfree(p2); |