#ifndef VOLGIT_GIT_PART_C #define VOLGIT_GIT_PART_C VOLGIT_GIT_PART_C #include static const char *special_chars[256] = { ['\"']=""", ['\'']="'", ['&']="&", ['<']="<", ['>']=">", }; int print_diff_line(const git_diff_delta *delta,const git_diff_hunk *hunk,const git_diff_line *line,FILE *out) { size_t i; if(line->origin=='+') fprintf(out,"
"); else if(line->origin=='-') fprintf(out,"
"); else fprintf(out,"
"); fprintf(out,"%c ",line->origin); for(i=0;icontent_len;++i) if(special_chars[line->content[i]]) { fwrite(special_chars[line->content[i]],1,strlen(special_chars[line->content[i]]),out); }else { fwrite(line->content+i,1,1,out); } fprintf(out,"
"); return 0; } 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; size_t i; fprintf(out,"
");
	git_diff_tree_to_tree(&diff_from_parent,repo,parent_tree,current_tree,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);
	fprintf(out,"
"); } void print_headers_and_commit_message(FILE *where,git_commit *current_commit,const git_oid *current,_Bool has_diff) { const git_signature *who_commited; fprintf(where,"
COMMIT: %s",git_oid_tostr_s(current)); if(has_diff) fprintf(where," [DIFF]
\n",git_oid_tostr_s(current)); else fprintf(where,"
\n"); who_commited=git_commit_committer(current_commit); fprintf(where,"
AUTHOR: %s <%s>
\n",who_commited->name,who_commited->email); fprintf(where,"
DATE: %s
\n",ctime(&who_commited->when.time)); fprintf(where,"
\t%s
\n",git_commit_message(current_commit)); } void print_commits(int dir_fd,const git_reference *branch, git_repository *repo) { const git_oid *id; FILE *log_file; int diff_directory_fd; int files_directory_fd; git_revwalk *walker; git_oid current; git_commit *current_commit; git_commit *parent_commit=NULL; 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_dir(dir_fd,"diffs"); files_directory_fd=create_dir(dir_fd,"files"); if(git_revwalk_next(¤t,walker)) return; git_commit_lookup(¤t_commit,repo,¤t); print_files_top(files_directory_fd,current_commit,repo); while(!git_revwalk_next(¤t,walker)) { git_commit_lookup(&parent_commit,repo,¤t); print_commit(current_commit,parent_commit,log_file,diff_directory_fd,repo); git_commit_free(current_commit); current_commit=parent_commit; } if(parent_commit!=NULL) print_commit(current_commit,NULL,log_file,diff_directory_fd,repo); git_revwalk_free(walker); close_file(log_file); } void print_commit(git_commit *current_commit,git_commit *parent_commit,FILE *log_file,int diff_directory_fd,git_repository *repo) { git_tree *current_tree; git_tree *parent_tree; FILE *diff_file; git_commit_tree(¤t_tree,current_commit); if(parent_commit==NULL) parent_tree=NULL; else git_commit_tree(&parent_tree,parent_commit); diff_file=create_file(diff_directory_fd,git_oid_tostr_s(git_commit_id(current_commit))); print_diff(diff_file,parent_tree,current_tree,repo); git_tree_free(parent_tree); print_headers_and_commit_message(log_file,current_commit,git_commit_id(current_commit),1); close_file(diff_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; git_branch_iterator_new(&it,repo,branch_type); while(git_branch_next(&ref,&branch_type,it)==0) { git_branch_name(&branch_name,ref); if(branch_name) { branch_dir_fd=create_branch_dir(branch_name); print_commits(branch_dir_fd,ref,repo); close(branch_dir_fd); }else { printf("NULL\n"); } } git_branch_iterator_free(it); } void print_files(int dir_fd,git_tree *tree,git_repository *repo) { size_t number_of_entries; size_t i; const git_tree_entry *current_entry; FILE *index_file; number_of_entries=git_tree_entrycount(tree); index_file=create_file(dir_fd,"index"); for(i=0;i\n"); } close_file(index_file); } void print_files_top(int dir_fd,git_commit *top_commit,git_repository *repo) { git_tree *tree; git_commit_tree(&tree,top_commit); print_files(dir_fd,tree,repo); } int print_entry(FILE *index_file,const git_tree_entry *entry,int base_dir_fd,git_repository *repo) { git_object *obj; const git_oid *obj_oid; const char *entry_name; const char *entry_oid; git_tree_entry_to_object(&obj,repo,entry); obj_oid=git_object_id(obj); entry_name=git_tree_entry_name(entry); entry_oid=git_oid_tostr_s(obj_oid); switch(git_object_type(obj)) { case GIT_OBJECT_TREE: push_html_link_for_tree(index_file,entry_name,entry_oid); { int new_dir_fd; git_tree *tree; tree=(git_tree*)obj; new_dir_fd=create_dir(base_dir_fd,entry_oid); print_files(new_dir_fd,tree,repo); } break; case GIT_OBJECT_BLOB: push_html_link_for_blob(index_file,entry_name,entry_oid); { FILE *blob_file; const unsigned char *blob_data; size_t blob_size; size_t i; git_blob *blob; blob=(git_blob*)obj; blob_file=create_file(base_dir_fd,entry_oid); blob_size=git_blob_rawsize(blob); blob_data=git_blob_rawcontent(blob); fprintf(blob_file,"
\n");
				for(i=0;i\n");

				close_file(blob_file);
			}
			break;
	}

	git_object_free(obj);
	return 0;
}
#endif