baseline

yet another open-source distributed versioning control system
Log | Files | Refs

commit eb8814dd1c59a478b2d3a3e496dbad576d00517c
parent 9ea49a139ac0c786f9f2e4a03c8fdcabbdcfb53d
Author: Mohamed Aslan <maslan@sce.carleton.ca>
Date:   Wed, 18 Jun 2014 04:26:00 -0400

check if the heads of both the current branch and working dir match before commit

Diffstat:
Mcmd-commit.c | 24+++++++++++++++++++++---
Mdircache-simple.c | 24++++++++++++++++--------
2 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/cmd-commit.c b/cmd-commit.c @@ -108,16 +108,20 @@ cmd_commit(int argc, char **argv) { char *commit_msg = NULL, *msg_file; char *exec; + char *branch_head, *workdir_head; const char *editor; int ch; - int flag_msg = 0, flag_error = 0; + int flag_msg = 0, flag_error = 0, flag_force = 0; struct session s; baseline_session_begin(&s, 0); /* parse command line options */ - while ((ch = getopt(argc, argv, "m:")) != -1) { + while ((ch = getopt(argc, argv, "fm:")) != -1) { switch (ch) { + case 'f': + flag_force = 1; + break; case 'm': flag_msg = 1; commit_msg = strdup(optarg); @@ -161,8 +165,22 @@ cmd_commit(int argc, char **argv) if (process_msgfile(s.repo_baselinedir, &msg_file) == EXIT_FAILURE) errx(EXIT_FAILURE, "error, failed to process commit message."); + /* make sure that the working dir matches the branch's head */ + if (s.db_ops->branch_get_head(s.db_ctx, s.branch, &branch_head) == EXIT_FAILURE) + errx(EXIT_FAILURE, "error, failed to query the status of the current branch."); + if (s.dc_ops->workdir_get(s.dc_ctx, &workdir_head) == EXIT_FAILURE) + errx(EXIT_FAILURE, "error, failed to query the status of the working directory."); + /* check if it's the first commit ever */ + if ((branch_head == NULL && workdir_head == NULL) || (strcmp(branch_head, workdir_head) == 0) || flag_force) + goto next; + else + errx(EXIT_FAILURE, "error, the heads of the current branch and working directory do not match.\n" + "you can:\n\t[1] switch to the correct branch, or\n\t[2] checkout the last head, or\n\t[3] use -f to force commit"); + +next: if (s.dc_ops->commit(s.dc_ctx, msg_file) == EXIT_FAILURE) - fprintf(stderr, "baseline: error, failed to commit your changes.\n"); + errx(EXIT_FAILURE, "error, failed to commit your changes.\n"); + unlink(msg_file); free(msg_file); diff --git a/dircache-simple.c b/dircache-simple.c @@ -414,6 +414,13 @@ simple_commit(struct dircache_ctx *dc_ctx, const char *msgfile) return EXIT_FAILURE; if (!S_ISDIR(s.st_mode)) return EXIT_FAILURE; + /* get current branch */ + if (simple_branch_get(dc_ctx, &cur_branch) == EXIT_FAILURE) + return EXIT_FAILURE; + /* get current branch's head (commit's parent) */ + if (dc_ctx->db_ops->branch_get_head(dc_ctx->db_ctx, cur_branch, &cur_head) == EXIT_FAILURE) + return EXIT_FAILURE; + /* FIXME: empty dirache directory */ gen_dindex(dc_ctx, &didx_path); if ((didx_fp = fopen(didx_path, "r")) == NULL) @@ -498,17 +505,17 @@ simple_commit(struct dircache_ctx *dc_ctx, const char *msgfile) if (mkdir(dircache_path, S_IRUSR | S_IWUSR | S_IXUSR) == -1) { return EXIT_FAILURE; } - /* get commit's parent */ - if (simple_branch_get(dc_ctx, &cur_branch) == EXIT_FAILURE) - return EXIT_FAILURE; - if (dc_ctx->db_ops->branch_get_head(dc_ctx->db_ctx, cur_branch, &cur_head) == EXIT_FAILURE) - return EXIT_FAILURE; + /* generate commit */ if ((com = baseline_helper_commit_build(dc_ctx, objid, cur_head, msgfile)) == NULL) return EXIT_FAILURE; + /* insert the commit into the db */ dc_ctx->db_ops->insert_commit(dc_ctx->db_ctx, com); printf("commit id: %s\n", com->id); unlink(path); + /* update the branch's head */ dc_ctx->db_ops->branch_set_head(dc_ctx->db_ctx, cur_branch, com->id); + /* update the working dir */ + simple_workdir_set(dc_ctx, com->id); free(cur_branch); free(cur_head); free(path); @@ -566,12 +573,13 @@ simple_workdir_get(struct dircache_ctx *dc_ctx, char **commit_id) if (dc_ctx == NULL || commit_id == NULL) return EXIT_FAILURE; asprintf(&fname, "%s/workdir", dc_ctx->repo_baselinepath); - *commit_id = NULL; if ((fp = fopen(fname, "r")) == NULL) return EXIT_FAILURE; + *commit_id = NULL; if (getline(commit_id, &size, fp) == -1) { - free(*commit_id); - return EXIT_FAILURE; + /* assuming the file is empty */ + /* FIXME: check for errors */ + *commit_id = NULL; } fclose(fp); free(fname);