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:
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);