summaryrefslogtreecommitdiffstats
path: root/usr.bin/cvs/commit.c
diff options
context:
space:
mode:
authorjoris <joris@openbsd.org>2007-09-24 13:44:20 +0000
committerjoris <joris@openbsd.org>2007-09-24 13:44:20 +0000
commit18cf78299d520e9a86dae86bb6a418844341c770 (patch)
tree403e131428abad8bc155f86c2cbe54c568aec81f /usr.bin/cvs/commit.c
parentnewly discovered init problem (diff)
downloadwireguard-openbsd-18cf78299d520e9a86dae86bb6a418844341c770.tar.xz
wireguard-openbsd-18cf78299d520e9a86dae86bb6a418844341c770.zip
add support to commit modified files to branches.
Diffstat (limited to 'usr.bin/cvs/commit.c')
-rw-r--r--usr.bin/cvs/commit.c157
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);