summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--git_part.c47
-rw-r--r--git_part.h9
-rw-r--r--system_part.c121
-rw-r--r--system_part.h32
-rw-r--r--volgit.c15
6 files changed, 196 insertions, 29 deletions
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 <git_part.h>
-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;i<line->content_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(&current,walker))
{
@@ -58,22 +66,25 @@ void print_commits(const git_reference *branch, git_repository *repo)
git_commit_tree(&current_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(&current));
+ print_diff(diff_file,parent_tree,current_tree,repo);
git_tree_free(parent_tree);
}
- print_headers_and_commit_message(current_commit,&current);
+ print_headers_and_commit_message(log_file,current_commit,&current);
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 <stdio.h>
#include <git2.h>
+#include <system_part.h>
-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 <system_part.h>
+
+const char *default_header="<!DOCTYPE html><html><head><title>GIT</title></head><body>";
+const char *default_footer="</body></html>";
+
+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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+
+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 <stdio.h>
#include <git2.h>
+#include <system_part.h>
#include <git_part.h>
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);