commit 7ea3563926e47c2d63f21b839205f50244f729ac
parent 9249505d9bdb3ba01c87b6f82af2f6a81ea56eb3
Author: Mohamed Aslan <maslan@sce.carleton.ca>
Date:   Sun, 25 May 2014 16:31:13 -0400
some work done and bug fixes for branches support
Diffstat:
7 files changed, 94 insertions(+), 86 deletions(-)
diff --git a/cmd-branch.c b/cmd-branch.c
@@ -26,90 +26,70 @@
 
 #include "defaults.h"
 #include "config.h"
-#include "objdb.h"
-#include "dircache.h"
+#include "session.h"
 #include "cmd.h"
 
-extern int objdb_baseline_get_ops(struct objdb_ops **);
-extern int dircache_simple_get_ops(struct dircache_ops **);
-
-int cmd_branch(int, char **);
-
-/*
- * creates a new branch.
- */
-static int
-create(const char *branch_name) {
-	char *baseline_path;
-	int retval;
-	struct objdb_ops *objdb;
-	struct objdb_ctx *db_ctx;
-	objdb_baseline_get_ops(&objdb);
-	/* FIXME: get repository path correctly */
-	asprintf(&baseline_path, "%s", BASELINE_DIR);
-	/* FIXME: check if repository initialized */
-	if (objdb->open != NULL)
-		objdb->open(&db_ctx, "db", baseline_path);
-	if (objdb->init != NULL) /* TO BE REMOVED */
-		objdb->init(db_ctx);
-	retval = objdb->branch_create(db_ctx, branch_name);
-	if (objdb->close != NULL)
-		objdb->close(db_ctx);
-	free(baseline_path);
-	free(objdb);
-	return retval;
-}
-
-static int
-update(const char *branch_name, const char *head_objid)
-{
-	
-	return EXIT_SUCCESS;
-}
-
-static int
-ls()
-{
-	char *baseline_path;
-	int retval;
-	struct objdb_ops *objdb;
-	struct objdb_ctx *db_ctx;
-	objdb_baseline_get_ops(&objdb);
-	/* FIXME: get repository path correctly */
-	asprintf(&baseline_path, "%s", BASELINE_DIR);
-	/* FIXME: check if repository initialized */
-	if (objdb->open != NULL)
-		objdb->open(&db_ctx, "db", baseline_path);
-	if (objdb->init != NULL) /* TO BE REMOVED */
-		objdb->init(db_ctx);
-	retval = objdb->branch_ls(db_ctx);
-	if (objdb->close != NULL)
-		objdb->close(db_ctx);
-	free(baseline_path);
-	free(objdb);
-	return retval;
-}
 
 int
 cmd_branch(int argc, char **argv)
 {
-	/*
-	 * branch command can be used to:
-	 * 1. list all branches
-	 * 2. create a new branch
-	*/
+	char *branch = NULL;
+	char *head = NULL;
+	enum {
+		O_LISTCUR,
+		O_LISTALL,
+		O_CREATE,
+		O_SWITCH
+	} op = O_LISTCUR;
+	int ch, error = 0;
+	struct session s;
 
-	if (argc == 1) {	/* no args */
-		/* list all branches */
-		ls();
+	baseline_session_begin(&s, 0);
+
+	/* parse command line options */
+	while ((ch = getopt(argc, argv, "ac:s:")) != -1) {
+		switch (ch) {
+		case 'a':
+			op = O_LISTALL;
+			break;
+		case 'c':
+			op = O_CREATE;
+			branch = strdup(optarg);
+			break;
+		case 's':
+			op = O_SWITCH;
+		default:
+			error = 1;
+			break;
+		}
 	}
-	else if (argc == 2) {	/* 1 arg */
-		/* create a new branch */
-		if (create(argv[1]) == EXIT_FAILURE)
-			errx(EXIT_FAILURE, "failed to create branch \'%s\'", argv[1]);
+	argc -= optind;
+	argv += optind;
+
+	if (error) {
+		return EXIT_FAILURE;
 	}
-	else{
-		errx(EXIT_FAILURE, "wrong number of parameters for command \'branch\'");
+
+	switch (op) {
+	case O_LISTCUR:
+		if (s.db_ops->branch_get_head(s.db_ctx, s.branch, &head) == EXIT_FAILURE)
+			errx(EXIT_FAILURE, "error, failed to find branch head.");
+		printf("current branch: %s\nhead: %s\n", s.branch, head);
+		free(head);
+		break;
+	case O_LISTALL:
+		if (s.db_ops->branch_ls(s.db_ctx) == EXIT_FAILURE)
+			errx(EXIT_FAILURE, "error, failed to list branches.");
+		break;
+	case O_CREATE:
+		/* create a new branch */
+		if (s.db_ops->branch_create(s.db_ctx, branch) == EXIT_FAILURE)
+			errx(EXIT_FAILURE, "error, failed to create branch \'%s\'.", branch);
+		break;
+	case O_SWITCH:
+		break;
 	}
+
+	baseline_session_end(&s);
 	return EXIT_SUCCESS;
 }
diff --git a/cmd-commit.c b/cmd-commit.c
@@ -120,7 +120,7 @@ cmd_commit(int argc, char **argv)
 		switch (ch) {
 		case 'm':
 			flag_msg = 1;
-			asprintf(&commit_msg, "%s", optarg);
+			commit_msg = strdup(optarg);
 			break;
 		default:
 			flag_error = 1;
diff --git a/dircache-simple.c b/dircache-simple.c
@@ -35,6 +35,7 @@ static int simple_init(struct dircache_ctx *);
 static int simple_insert(struct dircache_ctx *, const char *);
 static int simple_checkout(struct dircache_ctx *, const char *);
 static int simple_commit(struct dircache_ctx *, const char *);
+static int simple_get_branch(struct dircache_ctx *, char **);
 
 static struct dircache_ops simple_ops = {
 	.name = "simple",
@@ -46,6 +47,7 @@ static struct dircache_ops simple_ops = {
 	.remove = NULL,
 	.commit = simple_commit,
 	.checkout = simple_checkout,
+	.get_branch = simple_get_branch,
 	.fsck = NULL,
 	.compress = NULL,
 	.dedup = NULL
@@ -305,7 +307,7 @@ simple_gen_commit(const char *dir_id, const char *msg_file, char **commit_file)
 }
 
 static int
-simple_get_current_branch(char **branch_name)
+simple_get_branch(struct dircache_ctx *dc_ctx, char **branch_name)
 {
 	size_t size = 0;
 	FILE *branch_fp;
@@ -355,7 +357,6 @@ simple_commit(struct dircache_ctx *dc_ctx, const char *msgfile)
 			path[len-1] = 0;
 			--len;
 		}
-		printf("DIR: %s\n", path);
 		dc_ctx->db_ops->dir_begin(dc_ctx->db_ctx, &handle);
 		paths[0] = (char *)path;
 		paths[1] = NULL;
@@ -367,14 +368,21 @@ simple_commit(struct dircache_ctx *dc_ctx, const char *msgfile)
 				continue;
 			}
 			if (entry->fts_info & FTS_F) {
+#ifdef DEBUG
 				printf("\t FILE: %s\n", entry->fts_path);
+#endif
 				if ((fp = fopen(entry->fts_path, "r")) == NULL)
 					return EXIT_FAILURE;
 				fscanf(fp, "%c %s %o", &type, tmp_objid, &mode);
-				if (type == 'F')
+				if (type == 'F') {
 					dc_ctx->db_ops->dir_insert_object(dc_ctx->db_ctx, handle, tmp_objid, entry->fts_name, T_FILE, mode);
-				else if (type == 'D')
+					printf("[+] F %06o\t%s\n", mode, entry->fts_name);
+				}
+				else if (type == 'D') {
 					dc_ctx->db_ops->dir_insert_object(dc_ctx->db_ctx, handle, tmp_objid, entry->fts_name, T_DIR, mode);
+					/* FIXME: dir mode are copied from dircache, hence not preserved */
+					printf("[+] D %06o\t%s\n", mode, entry->fts_name);
+				}
 				fclose(fp);
 				unlink(entry->fts_path);
 			}
@@ -412,9 +420,9 @@ simple_commit(struct dircache_ctx *dc_ctx, const char *msgfile)
 		return EXIT_FAILURE;
 	if (dc_ctx->db_ops->insert_from_file(dc_ctx->db_ctx, T_COMMIT, path, &objid) == EXIT_FAILURE)
 		return EXIT_FAILURE;
-	printf("COMMIT ID: %s\n", objid);
+	printf("commit id: %s\n", objid);
 	unlink(path);
-	simple_get_current_branch(&branch);
+	simple_get_branch(dc_ctx, &branch);
 	dc_ctx->db_ops->branch_set_head(dc_ctx->db_ctx, branch, objid);
 	free(path);
 	free(objid);
@@ -435,3 +443,4 @@ simple_checkout(struct dircache_ctx *dc_ctx, const char *branch_name)
 	return EXIT_SUCCESS;
 }
 
+
diff --git a/dircache.h b/dircache.h
@@ -36,6 +36,7 @@ struct dircache_ops {
 	int (*remove)(struct dircache_ctx *, const char *);
 	int (*commit)(struct dircache_ctx *, const char *);
 	int (*checkout)(struct dircache_ctx *, const char *);
+	int (*get_branch)(struct dircache_ctx *, char **);
 	int (*fsck)(struct dircache_ctx *);
 	int (*compress)(struct dircache_ctx *);
 	int (*dedup)(struct dircache_ctx *);
diff --git a/objdb-fs.c b/objdb-fs.c
@@ -343,7 +343,9 @@ objdb_bl_branch_create(struct objdb_ctx *ctx, const char *branch_name)
 {
 	char *db_dir_name = NULL;
 	char *branch_path = NULL;
+	char *branch_head = NULL;
 	int retval = EXIT_SUCCESS;
+	FILE *fp;
 
 	if (branch_name == NULL)
 		return EXIT_FAILURE;
@@ -353,10 +355,21 @@ objdb_bl_branch_create(struct objdb_ctx *ctx, const char *branch_name)
 #ifdef DEBUG
 	printf("creating branch %s\n", branch_path);
 #endif
-	if (mkdir(branch_path, S_IRUSR | S_IWUSR | S_IXUSR) == -1)
+	if (mkdir(branch_path, S_IRUSR | S_IWUSR | S_IXUSR) == -1) {
 		retval = EXIT_FAILURE;
+		goto ret;
+	}
+	/* create head */
+	asprintf(&branch_head, "%s/head", branch_path);
+	if ((fp = fopen(branch_head, "w")) == NULL) {
+		retval = EXIT_FAILURE;
+		goto ret;
+	}
+	fclose(fp);
+ret:	
 	free(db_dir_name);
 	free(branch_path);
+	free(branch_head);
 	return retval;
 }
 
@@ -429,8 +442,9 @@ objdb_bl_branch_get_head(struct objdb_ctx *ctx, const char *branch_name, char **
 		goto ret;
 	}
 	if (getline(head_objid, &size, head_fp) == -1) {
-		retval = EXIT_FAILURE;
-		goto ret;
+		/* assuming the head file is empty */
+		/* FIXME: check for errors */
+		*head_objid = NULL;
 	}
 	fclose(head_fp);
 ret:
@@ -458,7 +472,7 @@ objdb_bl_branch_ls(struct objdb_ctx *ctx)
 		if (entry->fts_level == FTS_ROOTLEVEL)
 				continue;
 		if (entry->fts_info & FTS_D) {
-			printf("%s\n", entry->fts_name);
+			printf("* %s\n", entry->fts_name);
 		}
 		else {
 			if (entry->fts_level >= 1)
diff --git a/session.c b/session.c
@@ -58,6 +58,9 @@ baseline_session_begin(struct session *s, u_int8_t options)
 		errx(EXIT_FAILURE, "failed to load configurations.");
 	free(config);
 
+	/* get current branch */
+	s->dc_ops->get_branch(s->dc_ctx, (char **)&(s->branch));
+
 	return EXIT_SUCCESS;
 }
 
diff --git a/session.h b/session.h
@@ -35,6 +35,7 @@ struct session {
 	const char *repo_rootdir;
 	const char *repo_baselinedir;
 	const char cwd[PATH_MAX+1];
+	const char *branch;
 };
 
 int baseline_session_begin(struct session *, u_int8_t);