Command line

This commit is contained in:
womax
2024-06-03 19:28:08 +02:00
parent a5bbd3f86d
commit 0fb0039b7d
7 changed files with 535 additions and 84 deletions

View File

@@ -1,3 +1,4 @@
#include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -64,7 +65,10 @@ void free_commit(struct commit *commit)
int commit() int commit()
{ {
struct tree index = {0}; struct tree index = {0};
load_index(&index); if (load_index(&index) == REPO_NOT_INITIALIZED)
{
return REPO_NOT_INITIALIZED;
}
struct object last_commit = {0}; struct object last_commit = {0};
struct commit commit = {0}; struct commit commit = {0};
@@ -127,10 +131,6 @@ int commit()
} }
commit.tree = commit_tree_checksum; commit.tree = commit_tree_checksum;
debug_print("Author: %s", commit.author);
debug_print("Parent: %s", commit.parent);
debug_print("Tree: %s", commit.tree);
struct object commit_obj = {0}; struct object commit_obj = {0};
commit_to_object(&commit, &commit_obj); commit_to_object(&commit, &commit_obj);
write_object(&commit_obj); write_object(&commit_obj);
@@ -149,10 +149,22 @@ int commit()
save_index(&index); save_index(&index);
} }
void diff_commit_with_working_tree(struct commit *commit, int for_print) int diff_commit_with_working_tree(char *checksum, int for_print)
{ {
struct object commit_obj = {0};
if (read_object(checksum, &commit_obj) == OBJECT_DOES_NOT_EXIST)
{
return OBJECT_DOES_NOT_EXIST;
}
if (commit_obj.object_type != COMMIT)
return WRONG_OBJECT_TYPE;
struct commit commit = {0};
commit_from_object(&commit, &commit_obj);
struct object obj = {0}; struct object obj = {0};
read_object(commit->tree, &obj); read_object(commit.tree, &obj);
struct tree commit_tree = {0}; struct tree commit_tree = {0};
get_tree(obj.content, &commit_tree); get_tree(obj.content, &commit_tree);
@@ -177,18 +189,37 @@ void diff_commit_with_working_tree(struct commit *commit, int for_print)
pclose(p); pclose(p);
free_tree(&commit_tree); free_tree(&commit_tree);
free_commit(&commit);
free_object(&obj); free_object(&obj);
free_object(&commit_obj);
} }
void diff_commit(struct commit *commit_a, struct commit *commit_b, int for_print) int diff_commit(char* checksum_a, char* checksum_b, int for_print)
{ {
struct object tree_obj_a, tree_obj_b; struct object commit_a_obj = {0}, commit_b_obj = {0};
read_object(commit_a->tree, &tree_obj_a); if (read_object(checksum_a, &commit_a_obj) == OBJECT_DOES_NOT_EXIST)
read_object(commit_b->tree, &tree_obj_b); {
errno = 1;
return OBJECT_DOES_NOT_EXIST;
}
if (read_object(checksum_b, &commit_b_obj) == OBJECT_DOES_NOT_EXIST)
{
free_object(&commit_a_obj);
errno = 2;
return OBJECT_DOES_NOT_EXIST;
}
struct commit commit_a, commit_b;
commit_from_object(&commit_a, &commit_a_obj);
commit_from_object(&commit_b, &commit_b_obj);
struct object tree_a_obj, tree_b_obj;
read_object(commit_a.tree, &tree_a_obj);
read_object(commit_b.tree, &tree_b_obj);
struct tree tree_a, tree_b; struct tree tree_a, tree_b;
get_tree(tree_obj_a.content, &tree_a); get_tree(tree_a_obj.content, &tree_a);
get_tree(tree_obj_b.content, &tree_b); get_tree(tree_b_obj.content, &tree_b);
rmdir(TMP"/a"); rmdir(TMP"/a");
rmdir(TMP"/b"); rmdir(TMP"/b");
@@ -199,11 +230,16 @@ void diff_commit(struct commit *commit_a, struct commit *commit_b, int for_print
dump_tree(TMP"/a", &tree_a); dump_tree(TMP"/a", &tree_a);
dump_tree(TMP"/b", &tree_b); dump_tree(TMP"/b", &tree_b);
FILE *f = popen("diff -ruN "TMP"/a "TMP"/b > "LOCAL_REPO"/last.diff", "w"); FILE *f = popen("diff -ruN "TMP"/a "TMP"/b --color=always> "LOCAL_REPO"/last.diff", "w");
pclose(f); pclose(f);
free_tree(&tree_a); free_tree(&tree_a);
free_tree(&tree_b); free_tree(&tree_b);
free_object(&tree_obj_a); free_commit(&commit_a);
free_object(&tree_obj_b); free_commit(&commit_b);
free_object(&tree_a_obj);
free_object(&tree_b_obj);
free_object(&commit_a_obj);
free_object(&commit_b_obj);
return 0;
} }

View File

@@ -5,8 +5,8 @@
int commit_from_object(struct commit *commit, struct object *object); int commit_from_object(struct commit *commit, struct object *object);
void free_commit(struct commit *commit); void free_commit(struct commit *commit);
void diff_commit(struct commit *commit_a, struct commit *commit_b, int for_print); int diff_commit(char* checksum_a, char* checksum_b, int for_print);
void diff_commit_with_working_tree(struct commit *commit, int for_print); int diff_commit_with_working_tree(char *checksum, int for_print);
int commit(); int commit();
#endif // COMMIT_H #endif // COMMIT_H

207
src/fs.c
View File

@@ -194,6 +194,20 @@ defer:
return result; return result;
} }
int remove_object(char *checksum)
{
if(!local_repo_exist())
{
return REPO_NOT_INITIALIZED;
}
int result = FS_OK;
char path[strlen(OBJECTS_DIR) + strlen(checksum) + 2];
sprintf(path, "%s/%s", OBJECTS_DIR, checksum);
remove(path);
}
int create_dir(char *dir) int create_dir(char *dir)
{ {
struct stat buffer = {0}; struct stat buffer = {0};
@@ -361,7 +375,7 @@ int get_head_commit_checksum(char* checksum)
return REPO_NOT_INITIALIZED; return REPO_NOT_INITIALIZED;
} }
if(head_size == 0) return 0; if(head_size == 0) return NO_CURRENT_HEAD;
FILE *head_file = NULL; FILE *head_file = NULL;
head_file = fopen(HEAD_FILE, "r"); head_file = fopen(HEAD_FILE, "r");
@@ -383,7 +397,8 @@ int get_head_commit_checksum(char* checksum)
int get_last_commit(struct object *commit) int get_last_commit(struct object *commit)
{ {
char commit_checksum[DIGEST_LENGTH * 2 + 1]; char commit_checksum[DIGEST_LENGTH * 2 + 1];
get_head_commit_checksum(commit_checksum); if (get_head_commit_checksum(commit_checksum) == NO_CURRENT_HEAD)
return FS_OK;
int res = read_object(commit_checksum, commit); int res = read_object(commit_checksum, commit);
if (res != 0) return FS_ERROR; if (res != 0) return FS_ERROR;
@@ -465,24 +480,15 @@ int new_branch(char* branch_name)
return FS_OK; return FS_OK;
} }
int revert_to(char* commit_checksum) int reset_to(char* commit_checksum)
{ {
struct object obj = {0}; int res = diff_commit_with_working_tree(commit_checksum, 0);
read_object(commit_checksum, &obj); if(res != FS_OK)
return res;
if(obj.object_type != COMMIT)
return WRONG_OBJECT_TYPE;
struct commit commit = {0};
commit_from_object(&commit, &obj);
diff_commit_with_working_tree(&commit, 0);
FILE *p = popen("patch -p0 -R < "LOCAL_REPO"/last.diff > /dev/null", "w"); FILE *p = popen("patch -p0 -R < "LOCAL_REPO"/last.diff > /dev/null", "w");
pclose(p); pclose(p);
free_commit(&commit);
free_object(&obj);
return FS_OK; return FS_OK;
} }
@@ -501,15 +507,178 @@ int checkout_branch(char *branch)
fread(commit_checksum, DIGEST_LENGTH * 2 + 1, 1, branch_head); fread(commit_checksum, DIGEST_LENGTH * 2 + 1, 1, branch_head);
fclose(branch_head); fclose(branch_head);
revert_to(commit_checksum); reset_to(commit_checksum);
FILE *head_file = fopen(HEAD_FILE, "w"); FILE *head_file = fopen(HEAD_FILE, "w");
fwrite(branch_path, DIGEST_LENGTH * 2 + 1, 1, head_file); fwrite(branch_path, DIGEST_LENGTH * 2 + 1, 1, head_file);
fclose(head_file); fclose(head_file);
} }
void print_diff() int is_file_ignored(char *filename)
{ {
FILE *p = popen("cat "LOCAL_REPO"/last.diff | less -R", "w"); struct stat buffer = {0};
pclose(p); if (stat(IGNORE_FILE, &buffer) != 0)
{
return 0;
}
char content[buffer.st_size + 1];
memset(content, 0, buffer.st_size + 1);
FILE *ignore_file = fopen(IGNORE_FILE, "r");
fread(content, buffer.st_size, 1, ignore_file);
fclose(ignore_file);
char *current_line = strtok(content, "\n");
while(current_line != NULL)
{
if(strncmp(current_line, filename, strlen(current_line)) == 0)
{
return 1;
}
char alt[strlen(current_line) + 3];
sprintf(alt, "./%s", current_line);
if(strncmp(alt, filename, strlen(alt)) == 0)
return 1;
current_line = strtok(NULL, "\n");
}
return 0;
}
int add_file_to_index(struct tree *index, char *filename)
{
if (is_file_ignored(filename)) {
return 0;
}
struct stat st = {0};
if (stat(filename, &st) != 0)
{
return FILE_NOT_FOUND;
}
if (!S_ISREG(st.st_mode))
{
DIR *dp;
struct dirent *ep;
dp = opendir(filename);
if (dp != NULL)
{
while ((ep = readdir(dp)) != NULL)
{
if (strcmp(ep->d_name, "..") != 0 && strcmp(ep->d_name, ".") != 0)
{
char path[strlen(ep->d_name) + strlen(filename) + 2];
if (strcmp(filename, "./") == 0)
sprintf(path, "%s", ep->d_name);
else if (strcmp(filename, ".") == 0)
sprintf(path, "%s", ep->d_name);
else if(filename[strlen(filename) - 1] == '/')
sprintf(path, "%s%s", filename, ep->d_name);
else
sprintf(path, "%s/%s", filename, ep->d_name);
add_file_to_index(index, path);
}
}
closedir(dp);
return 0;
}
} else {
if (add_to_index(index, filename) == FILE_NOT_FOUND)
return FILE_NOT_FOUND;
}
}
int remove_file_from_index(struct tree *index, char *filename)
{
if (is_file_ignored(filename))
return 0;
struct stat st = {0};
if (stat(filename, &st) != 0)
return FILE_NOT_FOUND;
if (!S_ISREG(st.st_mode))
{
DIR *dp;
struct dirent *ep;
dp = opendir(filename);
if (dp != NULL)
{
while ((ep = readdir(dp)) != NULL)
{
if (strcmp(ep->d_name, "..") != 0 && strcmp(ep->d_name, ".") != 0)
{
char path[strlen(ep->d_name) + strlen(filename) + 2];
if (strcmp(filename, "./") == 0)
sprintf(path, "%s", ep->d_name);
else if(filename[strlen(filename) - 1] == '/')
sprintf(path, "%s%s", filename, ep->d_name);
else
sprintf(path, "%s/%s", filename, ep->d_name);
remove_file_from_index(index, path);
}
}
closedir(dp);
return 0;
}
} else {
remove_from_index(index, filename, 1);
}
}
int dump_log()
{
struct object current_obj = {0};
get_last_commit(&current_obj);
struct commit current = {0};
commit_from_object(&current, &current_obj);
FILE *log_file = fopen(LOG_FILE, "w");
char checksum[DIGEST_LENGTH * 2 + 1];
hash_object(&current_obj, checksum);
fprintf(log_file, "commit %s\n", checksum);
fprintf(log_file, "Author: %s\n", current.author);
fprintf(log_file, "Tree: %s\n", current.tree);
fprintf(log_file, "\n");
while (strcmp(current.parent, " ") != 0)
{
free_object(&current_obj);
read_object(current.parent, &current_obj);
free_commit(&current);
commit_from_object(&current, &current_obj);
checksum[DIGEST_LENGTH * 2 + 1];
hash_object(&current_obj, checksum);
fprintf(log_file, "commit %s\n", checksum);
fprintf(log_file, "Author: %s\n", current.author);
fprintf(log_file, "Tree: %s\n", current.tree);
fprintf(log_file, "\n");
}
fclose(log_file);
return 0;
}
int dump_branches()
{
if(!heads_dir_exist())
{
return REPO_NOT_INITIALIZED;
}
DIR *heads_dir = opendir(HEADS_DIR);
struct dirent *ep;
FILE *dump = fopen(TMP"/branches", "w");
if (heads_dir != NULL)
{
while ((ep = readdir(heads_dir)) != NULL)
{
if (strcmp(ep->d_name, "..") != 0 && strcmp(ep->d_name, ".") != 0)
fprintf(dump, "%s\n", ep->d_name);
}
fclose(dump);
closedir(heads_dir);
return 0;
} else
return FS_ERROR;
} }

View File

@@ -9,6 +9,8 @@
#define REFS_DIR LOCAL_REPO"/refs" #define REFS_DIR LOCAL_REPO"/refs"
#define HEADS_DIR REFS_DIR"/heads" #define HEADS_DIR REFS_DIR"/heads"
#define HEAD_FILE LOCAL_REPO"/HEAD" #define HEAD_FILE LOCAL_REPO"/HEAD"
#define IGNORE_FILE ".gitignore"
#define LOG_FILE LOCAL_REPO"/log"
#define TMP "/tmp" #define TMP "/tmp"
@@ -26,26 +28,40 @@
#define BRANCH_DOES_NOT_EXIST (-24) #define BRANCH_DOES_NOT_EXIST (-24)
#define FILE_NOT_FOUND (-30) #define FILE_NOT_FOUND (-30)
#define ENTRY_NOT_FOUND (-31) #define ENTRY_NOT_FOUND (-31)
#define NO_CURRENT_HEAD (-40)
int local_repo_exist(); int local_repo_exist();
int index_exist(); int index_exist();
int init_repo(); int init_repo();
int blob_from_file(char *filename, struct object *object); int blob_from_file(char *filename, struct object *object);
int write_object(struct object *obj); int write_object(struct object *obj);
int read_object(char *checksum, struct object *obj); int read_object(char *checksum, struct object *obj);
int remove_object(char *checksum);
int save_index(struct tree *tree); int save_index(struct tree *tree);
int load_index(struct tree *index); int load_index(struct tree *index);
int add_file_to_index(struct tree *index, char *filename);
int remove_file_from_index(struct tree *index, char *filename);
int load_tree(char* checksum, struct tree *tree); int load_tree(char* checksum, struct tree *tree);
int update_current_branch_head(char *new_head); int update_current_branch_head(char *new_head);
int get_last_commit(struct object *commit); int get_last_commit(struct object *commit);
int tmp_dump(struct object *obj, char* filename); int tmp_dump(struct object *obj, char* filename);
int init_tmp_diff_dir(char* dir); int init_tmp_diff_dir(char* dir);
int new_branch(char* branch_name); int new_branch(char* branch_name);
void print_diff(); int checkout_branch(char *branch);
int revert_to(char* commit_checksum);
int reset_to(char* commit_checksum);
int create_dir(char *dir); int create_dir(char *dir);
int dump_tree(char *cwd, struct tree *tree); int dump_tree(char *cwd, struct tree *tree);
int dump_log();
int dump_branches();
#endif // FS_H #endif // FS_H

View File

@@ -1,46 +1,267 @@
// Requirements #include <errno.h>
// commit
// branching
// revert
// pull/push
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include "includes.h" #include "includes.h"
#include "objects.h" #include "commit.h"
#include "types.h"
#include "fs.h" #include "fs.h"
#include "tree.h" #include "tree.h"
#include "commit.h"
int main(int argc, char** argv) #define ARGS_MAX_SIZE 256
int print_help()
{ {
// struct tree index = {0}; printf("Usage: cgit init\n");
// load_index(&index); printf(" cgit add [FILES]\n");
printf(" cgit remove [FILES]\n");
printf(" cgit commit -m [MESSAGE]\n");
printf(" cgit diff <COMMIT1> [COMMIT2]\n");
printf(" cgit branch [BRANCH]\n");
printf(" cgit checkout [BRANCH]\n");
printf(" cgit reset <COMMIT>\n");
printf(" cgit log\n");
return 0;
}
// add_to_index(&index, "src/commit.c"); int pop_arg(int *argc, char ***argv, char *buf)
// add_to_index(&index, "src/commit.h"); {
// add_to_index(&index, "src/fs.c"); if (*argc == 0)
// add_to_index(&index, "src/fs.h"); {
return 1;
}
// save_index(&index); strcpy(buf, *argv[0]);
*argc -= 1;
// commit(); *argv += 1;
struct object a = {0}, b = {0};
read_object("083fec39f677b81de863cb0b8575ac76e87b7bff", &a);
read_object("fb5d38457520619b6e2f3b162c2a21a22b531cb4", &b);
struct commit c_a, c_b;
commit_from_object(&c_a, &a);
commit_from_object(&c_b, &b);
diff_commit_with_working_tree(&c_b);
free_object(&a);
free_object(&b);
return 0; return 0;
}
int add(int argc, char **argv)
{
char buf[ARGS_MAX_SIZE];
int res;
res = pop_arg(&argc, &argv, buf);
if (res != 0)
{
printf("No file specified\n");
return 0;
}
struct tree index = {0};
if (load_index(&index) == REPO_NOT_INITIALIZED)
{
printf("Not a cgit repository\n");
return 128;
}
do {
if (add_file_to_index(&index, buf) == FILE_NOT_FOUND)
{
printf("File %s does not exist\n", buf);
return 1;
}
res = pop_arg(&argc, &argv, buf);
} while (res == 0);
save_index(&index);
free_tree(&index);
return 0;
}
int remove_cmd(int argc, char **argv)
{
char buf[ARGS_MAX_SIZE];
int res;
res = pop_arg(&argc, &argv, buf);
if (res != 0)
{
printf("No file specified\n");
return 0;
}
struct tree index = {0};
if (load_index(&index) == REPO_NOT_INITIALIZED)
{
printf("Not a cgit repository\n");
return 128;
}
do {
remove_file_from_index(&index, buf);
res = pop_arg(&argc, &argv, buf);
} while (res == 0);
save_index(&index);
free_tree(&index);
return 0;
}
int commit_cmd(int argc, char **argv)
{
if (commit() == REPO_NOT_INITIALIZED)
{
printf("Not a cgit repository\n");
return 128;
}
}
int diff(int argc, char **argv)
{
char checksum_a[ARGS_MAX_SIZE];
char checksum_b[ARGS_MAX_SIZE];
if(pop_arg(&argc, &argv, checksum_a) == 1)
{
printf("No commit specified\n");
return 0;
}
if(pop_arg(&argc, &argv, checksum_b) == 0)
{
if (diff_commit(checksum_a, checksum_b, 1) == OBJECT_DOES_NOT_EXIST)
{
if(errno == 1)
{
printf("Could not find commit %s\n", checksum_a);
} else if (errno == 2)
{
printf("Could not find commit %s\n", checksum_b);
}
return 0;
}
} else
{
if (diff_commit_with_working_tree(checksum_a, 1) == OBJECT_DOES_NOT_EXIST)
{
printf("Could not find commit %s\n", checksum_a);
return 0;
}
}
FILE *p = popen("cat "LOCAL_REPO"/last.diff | less -R", "w");
pclose(p);
return 0;
}
int checkout(int argc, char **argv)
{
char buf[ARGS_MAX_SIZE];
if(pop_arg(&argc, &argv, buf) == 1)
{
printf("No branch name specified\n");
return 0;
}
if (checkout_branch(buf) == BRANCH_DOES_NOT_EXIST)
{
printf("Branch %s does not exist, use cgit branch <name> to create one\n", buf);
}
}
int reset(int argc, char **argv)
{
char buf[ARGS_MAX_SIZE];
if(pop_arg(&argc, &argv, buf) == 1)
{
printf("You must give a commit to reset to\n");
return 0;
}
int res = reset_to(buf);
if (res == OBJECT_DOES_NOT_EXIST)
{
printf("There is no commit named %s\n", buf);
} else if (res == WRONG_OBJECT_TYPE)
{
printf("Object %s is not a commit and thus cannot be reset to\n", buf);
}
}
int branch(int argc, char **argv)
{
char buf[ARGS_MAX_SIZE];
if (pop_arg(&argc, &argv, buf) == 1)
{
if (dump_branches() == REPO_NOT_INITIALIZED)
{
printf("Not a cgit repository\n");
return 128;
}
FILE *p = popen("cat "TMP"/branches | less", "w");
pclose(p);
return 0;
}
if (new_branch(buf) == BRANCH_ALREADY_EXIST)
{
printf("Branch %s already exist\n", buf);
}
return 0;
}
int log_cmd(int argc, char **argv)
{
dump_log();
FILE *p = popen("cat "LOG_FILE" | less", "w");
pclose(p);
}
int main(int argc, char **argv)
{
char cmd[ARGS_MAX_SIZE];
char buf[ARGS_MAX_SIZE];
pop_arg(&argc, &argv, cmd);
if(pop_arg(&argc, &argv, buf) == 1)
{
print_help();
return 0;
}
if (strcmp(buf, "init") == 0)
{
return init_repo();
} else if (strcmp(buf, "add") == 0)
{
return add(argc, argv);
} else if (strcmp(buf, "remove") == 0)
{
return remove_cmd(argc, argv);
} else if (strcmp(buf, "commit") == 0)
{
return commit_cmd(argc, argv);
} else if (strcmp(buf, "diff") == 0)
{
return diff(argc, argv);
} else if (strcmp(buf, "branch") == 0)
{
return branch(argc, argv);
} else if (strcmp(buf, "checkout") == 0)
{
return checkout(argc, argv);
} else if (strcmp(buf, "reset") == 0)
{
return reset(argc, argv);
} else if (strcmp(buf, "log") == 0)
{
return log_cmd(argc, argv);
} else if (strcmp(buf, "-h") == 0) {
return print_help();
} else {
printf("Unknown command %s, try using %s -h\n", buf, cmd);
return 0;
}
} }

View File

@@ -155,25 +155,32 @@ int add_to_tree(struct tree *tree, struct object *object, char *filename)
int add_to_index(struct tree *index, char *filename) int add_to_index(struct tree *index, char *filename)
{ {
int result = FS_OK;
struct object object = {0}; struct object object = {0};
if (blob_from_file(filename, &object) != FS_OK) if (blob_from_file(filename, &object) != FS_OK)
{ {
return FILE_NOT_FOUND; return FILE_NOT_FOUND;
} }
add_to_tree(index, &object, filename); result = write_object(&object);
write_object(&object); if (result == FS_OK)
free_object(&object);
return FS_OK;
}
int remove_from_index(struct tree *index, char *filename)
{
if (!local_repo_exist() || !index_exist())
{ {
return REPO_NOT_INITIALIZED; add_to_tree(index, &object, filename);
defer(FS_OK);
} }
if (result == OBJECT_ALREADY_EXIST)
{
defer(FS_OK);
}
defer:
free_object(&object);
return result;
}
int remove_from_index(struct tree *index, char *filename, int delete)
{
struct entry *entry = find_entry(index, filename); struct entry *entry = find_entry(index, filename);
if (entry == NULL) if (entry == NULL)
{ {
@@ -196,6 +203,8 @@ int remove_from_index(struct tree *index, char *filename)
entry->next->previous = entry->previous; entry->next->previous = entry->previous;
} }
if (delete)
remove_object(entry->checksum);
index->entries_size = index->entries_size - 1; index->entries_size = index->entries_size - 1;
free_entry(entry); free_entry(entry);
free(entry); free(entry);
@@ -239,7 +248,7 @@ int add_object_to_tree(struct tree *tree, char* filename, struct object *source)
if(top_folder != NULL) if(top_folder != NULL)
{ {
load_tree(top_folder->checksum, &subtree); load_tree(top_folder->checksum, &subtree);
remove_from_index(tree, top_folder->filename); remove_from_index(tree, top_folder->filename, 0);
} }
add_to_tree(&subtree, source, path_left); add_to_tree(&subtree, source, path_left);
@@ -248,7 +257,7 @@ int add_object_to_tree(struct tree *tree, char* filename, struct object *source)
tree_to_object(&subtree, &result); tree_to_object(&subtree, &result);
write_object(&result); write_object(&result);
remove_from_index(tree, filename); remove_from_index(tree, filename, 0);
add_to_tree(tree, &result, top_folder_name); add_to_tree(tree, &result, top_folder_name);
free_object(&result); free_object(&result);
free_tree(&subtree); free_tree(&subtree);

View File

@@ -15,7 +15,7 @@ struct entry *find_entry(struct tree *index, char* filename);
void get_tree(char* content, struct tree *tree); void get_tree(char* content, struct tree *tree);
int add_to_tree(struct tree *tree, struct object *object, char *filename); int add_to_tree(struct tree *tree, struct object *object, char *filename);
int add_to_index(struct tree *index, char *filename); int add_to_index(struct tree *index, char *filename);
int remove_from_index(struct tree *index, char *filename); int remove_from_index(struct tree *index, char *filename, int delete);
int tree_to_object(struct tree *tree, struct object *object); int tree_to_object(struct tree *tree, struct object *object);
int add_object_to_tree(struct tree *tree, char* filename, struct object *source); int add_object_to_tree(struct tree *tree, char* filename, struct object *source);