From 7211f9c57204dc3b27327fc92352d99ad080a8db Mon Sep 17 00:00:00 2001 From: Galin Simeonov Date: Sat, 25 Sep 2021 23:15:21 +0300 Subject: made it create a directory with files containing the output of the program --- CMakeLists.txt | 1 + git_part.c | 47 ++++++++++++++-------- git_part.h | 9 +++-- system_part.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ system_part.h | 32 +++++++++++++++ volgit.c | 15 ++++--- 6 files changed, 196 insertions(+), 29 deletions(-) create mode 100644 system_part.c create mode 100644 system_part.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a2b6a1c..8640830 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,7 @@ endif( NOT CMAKE_BUILD_TYPE) include_directories(${CMAKE_SOURCE_DIR}) set(SOURCES git_part.c + system_part.c volgit.c ) diff --git a/git_part.c b/git_part.c index 6d91717..f3b0877 100644 --- a/git_part.c +++ b/git_part.c @@ -2,16 +2,16 @@ #define VOLGIT_GIT_PART_C VOLGIT_GIT_PART_C #include -int print_diff_line(const git_diff_delta *delta,const git_diff_hunk *hunk,const git_diff_line *line,void *payload) +int print_diff_line(const git_diff_delta *delta,const git_diff_hunk *hunk,const git_diff_line *line,FILE *out) { size_t i; - printf("%c ",line->origin); + fprintf(out,"%c ",line->origin); for(i=0;icontent_len;++i) - printf("%c",line->content[i]); + fprintf(out,"%c",line->content[i]); return 0; } -void print_diff(git_tree *parent_tree,git_tree *current_tree,git_repository *repo) +void print_diff(FILE *out,git_tree *parent_tree,git_tree *current_tree,git_repository *repo) { git_diff *diff_from_parent; size_t number_of_deltas=0; @@ -19,28 +19,32 @@ void print_diff(git_tree *parent_tree,git_tree *current_tree,git_repository *rep git_diff_tree_to_tree(&diff_from_parent,repo,current_tree,parent_tree,NULL); - git_diff_print(diff_from_parent,GIT_DIFF_FORMAT_PATCH,print_diff_line,NULL); + git_diff_print(diff_from_parent,GIT_DIFF_FORMAT_PATCH_ID,(git_diff_line_cb)print_diff_line,out); if(diff_from_parent) git_diff_free(diff_from_parent); } -void print_headers_and_commit_message(git_commit *current_commit,git_oid *current) +void print_headers_and_commit_message(FILE *where,git_commit *current_commit,git_oid *current) { const git_signature *who_commited; - printf("COMMIT: %s\n",git_oid_tostr_s(current)); + fprintf(where,"COMMIT: %s\n",git_oid_tostr_s(current)); who_commited=git_commit_committer(current_commit); - printf("AUTHOR: %s <%s>\n",who_commited->name,who_commited->email); + fprintf(where,"AUTHOR: %s <%s>\n",who_commited->name,who_commited->email); - printf("DATE: %s\n",ctime(&who_commited->when.time)); + fprintf(where,"DATE: %s\n",ctime(&who_commited->when.time)); - printf("\t%s\n",git_commit_message(current_commit)); + fprintf(where,"\t%s\n",git_commit_message(current_commit)); } -void print_commits(const git_reference *branch, git_repository *repo) +void print_commits(int dir_fd,const git_reference *branch, git_repository *repo) { const git_oid *id; + FILE *log_file; + FILE *diff_file; + int diff_directory_fd; + git_revwalk *walker; git_oid current; git_commit *current_commit; @@ -51,6 +55,10 @@ void print_commits(const git_reference *branch, git_repository *repo) git_revwalk_new(&walker,repo); id=git_reference_target(branch); git_revwalk_push(walker,id); + + + log_file=create_file(dir_fd,"log"); + diff_directory_fd=create_diff_dir(dir_fd); while(!git_revwalk_next(¤t,walker)) { @@ -58,22 +66,25 @@ void print_commits(const git_reference *branch, git_repository *repo) git_commit_tree(¤t_tree,current_commit); if(parent_tree!=NULL) { - print_diff(parent_tree,current_tree,repo); + diff_file=create_file(diff_directory_fd,git_oid_tostr_s(¤t)); + print_diff(diff_file,parent_tree,current_tree,repo); git_tree_free(parent_tree); } - print_headers_and_commit_message(current_commit,¤t); + print_headers_and_commit_message(log_file,current_commit,¤t); parent_tree=current_tree; git_commit_free(current_commit); } - + git_revwalk_free(walker); + fclose(log_file); } void print_branches(git_repository *repo) { const char *branch_name; + int branch_dir_fd; git_branch_iterator *it; git_reference *ref; git_branch_t branch_type=GIT_BRANCH_LOCAL; @@ -84,9 +95,11 @@ void print_branches(git_repository *repo) git_branch_name(&branch_name,ref); if(branch_name) { - printf("------- %s -------\n",branch_name); - print_commits(ref,repo); - printf("------------------\n"); + branch_dir_fd=create_branch_dir(branch_name); + + print_commits(branch_dir_fd,ref,repo); + + close(branch_dir_fd); }else { printf("NULL\n"); diff --git a/git_part.h b/git_part.h index 9f39423..f1f8072 100644 --- a/git_part.h +++ b/git_part.h @@ -2,11 +2,12 @@ #define VOLGIT_GIT_PART_H VOLGIT_GIT_PART_H #include #include +#include -int print_diff_line(const git_diff_delta *delta,const git_diff_hunk *hunk,const git_diff_line *line,void *payload); -void print_diff(git_tree *parent_tree,git_tree *current_tree,git_repository *repo); -void print_headers_and_commit_message(git_commit *current_commit,git_oid *current); -void print_commits(const git_reference *branch, git_repository *repo); +int print_diff_line(const git_diff_delta *delta,const git_diff_hunk *hunk,const git_diff_line *line,FILE *out); +void print_diff(FILE *out,git_tree *parent_tree,git_tree *current_tree,git_repository *repo); +void print_headers_and_commit_message(FILE* where,git_commit *current_commit,git_oid *current); +void print_commits(int dir_fd,const git_reference *branch, git_repository *repo); void print_branches(git_repository *repo); diff --git a/system_part.c b/system_part.c new file mode 100644 index 0000000..aaf2301 --- /dev/null +++ b/system_part.c @@ -0,0 +1,121 @@ +#ifndef VOLGIT_SYSTEM_PART_C +#define VOLGIT_SYSTEM_PART_C VOLGIT_SYSTEM_PART_C +#include + +const char *default_header="GIT"; +const char *default_footer=""; + +struct Volgit_Options options; + +void parse_options(int argc,char **argv) +{ + + options.header=default_header; + options.footer=default_footer; + switch(argc) + { + case 5: + options.header=read_file(argv[3]); + options.footer=read_file(argv[4]); + /*falltrough*/ + case 3: + options.input_path=argv[1]; + options.output_path=argv[2]; + break; + default: + die("Usage: volgit source destination [ file-containint-header file-containing-footer ]\n"); + } + + options.output_dir_fd=open(options.output_path,O_RDONLY|O_DIRECTORY); + if(options.output_dir_fd==-1) + { + mkdir(options.output_path,0770); + options.output_dir_fd=open(options.output_path,O_RDONLY|O_DIRECTORY); + if(options.output_dir_fd==-1) + die("Could not open output dir\n"); + } +} +char* read_file(const char *filename) +{ + long file_size; + int file; + char *ret; + struct stat file_stats; + + file=open(filename,O_RDONLY|O_CREAT); + if(file==-1) + die("Could not open file %s\n",filename); + + fstat(file,&file_stats); + + ret=malloc(file_stats.st_size+1); + + if(ret==NULL) + die("Ran out of memory!\n"); + + close(file); + return ret; +} + +int create_branch_dir(const char *branch_name) +{ + int ret=0; + + ret=openat(options.output_dir_fd,branch_name,O_DIRECTORY|O_RDONLY); + if(ret==-1) + { + if(mkdirat(options.output_dir_fd,branch_name,0770)==-1) + die("Could not create branch directory for %s\n",branch_name); + + ret=openat(options.output_dir_fd,branch_name,O_DIRECTORY|O_RDONLY); + if(ret==-1) + die("Could not open newly created directory for branch %s\n",branch_name); + } + + return ret; +} +FILE* create_file(int branch_dir,const char *filename) +{ + int fd; + unlinkat(branch_dir,filename,0); + fd=openat(branch_dir,filename,O_CREAT|O_RDWR,0660); + if(fd==-1) + die("Could not open the file '%s' for one of the branches\n",filename); + return fdopen(fd,"w"); +} +int create_files_dir(int branch_dir) +{ + int ret; + + ret=openat(branch_dir,"files",O_DIRECTORY|O_RDONLY); + if(ret!=-1) + return ret; + + ret=mkdirat(branch_dir,"files",0770); + if(ret==-1) + die("Could not create the 'files' subdirectory of one of the branch dirs\n"); + + return ret; +} +int create_diff_dir(int branch_dir) +{ + int ret; + + ret=openat(branch_dir,"diffs",O_DIRECTORY|O_RDONLY); + if(ret!=-1) + return ret; + mkdirat(branch_dir,"diffs",0770); + ret=openat(branch_dir,"diffs",O_DIRECTORY|O_RDONLY); + if(ret==-1) + die("Could not create the 'diffs' subdirectory of one of the branch dirs\n"); + return ret; +} + +void die(const char *format, ...) +{ + va_list args; + va_start(args,format); + vfprintf(stderr,format,args); + exit(1); +} +#endif diff --git a/system_part.h b/system_part.h new file mode 100644 index 0000000..ac06166 --- /dev/null +++ b/system_part.h @@ -0,0 +1,32 @@ +#ifndef VOLGIT_SYSTEM_PART_H +#define VOLGIT_SYSTEM_PART_H VOLGIT_SYSTEM_PART_H +#include +#include +#include +#include +#include +#include + +extern const char *default_header; +extern const char *default_footer; + +extern struct Volgit_Options +{ + const char *input_path; + const char *output_path; + const char *header; + const char *footer; + int output_dir_fd; +}options; + +void die(const char *format, ...); + +void parse_options(int argc,char **argv); +char* read_file(const char *filename); +int create_branch_dir(const char *branch_name); +FILE* create_file(int branch_dir,const char *filename); +int create_files_dir(int branch_dir); +int create_diff_dir(int branch_dir); + + +#endif diff --git a/volgit.c b/volgit.c index dc391e7..cca9ae6 100644 --- a/volgit.c +++ b/volgit.c @@ -1,21 +1,20 @@ #include #include +#include #include int main(int argc,char **argv) { - const char *repo_path; - - if(argc<=1) - { - fprintf(stderr,"You need to specify a source dir for the repo\n"); - return 1; - } git_repository *repo; git_libgit2_init(); - git_repository_open(&repo,argv[1]); + + parse_options(argc,argv); + + git_repository_open(&repo,options.input_path); + if(repo==NULL) + die("Could not open input git repository\n"); print_branches(repo); -- cgit v1.2.3