//\r
\r
#include "stdafx.h"\r
+#include "git-compat-util.h"\r
+#include "msvc.h"\r
#include "gitdll.h"\r
#include "cache.h"\r
#include "commit.h"\r
+#include "diff.h"\r
+#include "revision.h"\r
+#include "diffcore.h"\r
+const char git_version_string[] = GIT_VERSION;\r
+\r
+\r
#if 0\r
\r
// This is an example of an exported variable\r
\r
#define MAX_ERROR_STR_SIZE 512\r
char g_last_error[MAX_ERROR_STR_SIZE]={0};\r
+void * g_prefix;\r
\r
char * get_git_last_error()\r
{\r
convert_slash(path);\r
\r
git_extract_argv0_path(path);\r
- prefix = setup_git_directory();\r
+ g_prefix = prefix = setup_git_directory();\r
return git_config(git_default_config, NULL);\r
}\r
\r
return 0;\r
}\r
\r
-static int git_parse_commit(GIT_COMMIT *commit)\r
+int git_parse_commit(GIT_COMMIT *commit)\r
{\r
int ret = 0;\r
char *pbuf;\r
\r
memcpy(commit->m_hash,p->object.sha1,GIT_HASH_SIZE);\r
\r
+ commit->m_Encode = NULL;\r
+ commit->m_EncodeSize = 0;\r
+\r
if(p->buffer == NULL)\r
return -1;\r
\r
while((*pbuf) && (*pbuf == '\n'))\r
pbuf ++;\r
\r
+ if( strncmp(pbuf, "encoding",8) == 0 )\r
+ {\r
+ pbuf += 9;\r
+ commit->m_Encode=pbuf;\r
+ end = strchr(pbuf,'\n');\r
+ commit->m_EncodeSize=end -pbuf;\r
+\r
+ pbuf = end +1;\r
+ while((*pbuf) && (*pbuf == '\n'))\r
+ pbuf ++;\r
+ }\r
commit->m_Subject=pbuf;\r
end = strchr(pbuf,'\n');\r
if( end == 0)\r
{\r
int ret = 0;\r
\r
- struct commit *p = (struct commit*)commit;\r
+ struct commit *p;\r
+ \r
+ memset(commit,0,sizeof(GIT_COMMIT));\r
+\r
commit->m_pGitCommit = p = lookup_commit(hash);\r
\r
if(commit == NULL)\r
return git_parse_commit(commit);\r
}\r
\r
+int git_get_commit_first_parent(GIT_COMMIT *commit,GIT_COMMIT_LIST *list)\r
+{\r
+ struct commit *p = commit->m_pGitCommit;\r
+\r
+ if(list == NULL)\r
+ return -1;\r
+ \r
+ *list = (GIT_COMMIT_LIST*)p->parents;\r
+ return 0;\r
+}\r
+int git_get_commit_next_parent(GIT_COMMIT_LIST *list, GIT_HASH hash)\r
+{\r
+ struct commit_list *l = *(struct commit_list **)list;\r
+ if(list == NULL || l==NULL)\r
+ return -1;\r
+\r
+ if(hash)\r
+ memcpy(hash, l->item->object.sha1, GIT_HASH_SIZE);\r
+\r
+ *list = (GIT_COMMIT_LIST *)l->next;\r
+ return 0;\r
+\r
+}\r
+\r
+\r
+int git_free_commit(GIT_COMMIT *commit)\r
+{\r
+ struct commit *p = commit->m_pGitCommit;\r
+\r
+ if( p->parents)\r
+ free_commit_list(p->parents); \r
+\r
+ if( p->buffer )\r
+ {\r
+ free(p->buffer);\r
+ p->buffer=NULL;\r
+ p->object.parsed=0;\r
+ p->parents=0;\r
+ p->tree=0;\r
+ }\r
+ memset(commit,0,sizeof(GIT_COMMIT));\r
+ return 0;\r
+}\r
+\r
+char **strtoargv(char *arg, int *size)\r
+{\r
+ int count=0;\r
+ char *p=arg;\r
+ char **argv;\r
+ \r
+ int i=0;\r
+ while(*p)\r
+ {\r
+ if(*p == '\\')\r
+ *p='/';\r
+ p++;\r
+ }\r
+ p=arg;\r
+\r
+ while(*p)\r
+ {\r
+ if(*p == ' ')\r
+ count ++;\r
+ p++;\r
+ }\r
+ \r
+ argv=malloc(strlen(arg)+1 + (count +2)*sizeof(void*));\r
+ p=(char*)(argv+count+2);\r
+\r
+ while(*arg)\r
+ {\r
+ if(*arg == '"')\r
+ {\r
+ argv[i] = p;\r
+ arg++;\r
+ *p=*arg;\r
+ while(*arg && *arg!= '"')\r
+ *p++=*arg++;\r
+ *p++=0;\r
+ arg++;\r
+ i++;\r
+ if(*arg == 0)\r
+ break;\r
+ }\r
+ if(*arg != ' ')\r
+ {\r
+ argv[i]=p;\r
+ while(*arg && *arg !=' ')\r
+ *p++ = *arg++;\r
+ i++;\r
+ *p++=0;\r
+ }\r
+ arg++;\r
+ }\r
+ argv[i]=NULL;\r
+ *size = i;\r
+ return argv;\r
+}\r
+int git_open_log(GIT_LOG * handle, char * arg)\r
+{\r
+ struct rev_info *p_Rev;\r
+ int size;\r
+ char ** argv=0;\r
+ int argc=0;\r
+ int i=0;\r
+\r
+ /* clear flags */\r
+ unsigned int obj_size = get_max_object_index();\r
+ for(i =0; i<obj_size; i++)\r
+ {\r
+ struct object *ob= get_indexed_object(i);\r
+ if(ob)\r
+ ob->flags=0;\r
+ }\r
+\r
+ if(arg != NULL)\r
+ argv = strtoargv(arg,&argc);\r
+\r
+ p_Rev = malloc(sizeof(struct rev_info));\r
+ memset(p_Rev,0,sizeof(struct rev_info));\r
+\r
+ if(p_Rev == NULL)\r
+ return -1;\r
+\r
+ init_revisions(p_Rev, g_prefix);\r
+ p_Rev->diff = 1;\r
+ \r
+ cmd_log_init(argc, argv, g_prefix,p_Rev);\r
+\r
+ p_Rev->pPrivate = argv;\r
+ *handle = p_Rev;\r
+ return 0;\r
+\r
+}\r
+int git_get_log_firstcommit(GIT_LOG handle)\r
+{\r
+ return prepare_revision_walk(handle);\r
+}\r
+\r
+int git_get_log_estimate_commit_count(GIT_LOG handle)\r
+{\r
+ struct rev_info *p_Rev;\r
+ p_Rev=(struct rev_info *)handle;\r
+\r
+ return estimate_commit_count(p_Rev, p_Rev->commits);\r
+}\r
+\r
+int git_get_log_nextcommit(GIT_LOG handle, GIT_COMMIT *commit)\r
+{\r
+ int ret =0;\r
+\r
+ commit->m_pGitCommit = get_revision(handle);\r
+ if( commit->m_pGitCommit == NULL)\r
+ return -2;\r
+ \r
+ ret=git_parse_commit(commit);\r
+ if(ret)\r
+ return ret;\r
+\r
+ return 0;\r
+}\r
+\r
+int git_close_log(GIT_LOG handle)\r
+{\r
+ if(handle)\r
+ {\r
+ struct rev_info *p_Rev;\r
+ p_Rev=(struct rev_info *)handle;\r
+ if(p_Rev->pPrivate)\r
+ free(p_Rev->pPrivate);\r
+ free(handle);\r
+ }\r
+ \r
+ return 0;\r
+}\r
+\r
+int git_open_diff(GIT_DIFF *diff, char * arg)\r
+{\r
+ struct rev_info *p_Rev;\r
+ int size;\r
+ char ** argv=0;\r
+ int argc=0;\r
+ \r
+ if(arg != NULL)\r
+ argv = strtoargv(arg,&argc);\r
+\r
+ p_Rev = malloc(sizeof(struct rev_info));\r
+ memset(p_Rev,0,sizeof(struct rev_info));\r
+\r
+ p_Rev->pPrivate = argv;\r
+ *diff = (GIT_DIFF)p_Rev;\r
+\r
+ init_revisions(p_Rev, g_prefix);\r
+ git_config(git_diff_basic_config, NULL); /* no "diff" UI options */\r
+ p_Rev->abbrev = 0;\r
+ p_Rev->diff = 1;\r
+ argc = setup_revisions(argc, argv, p_Rev, NULL);\r
+\r
+ return 0;\r
+}\r
+int git_close_diff(GIT_DIFF handle)\r
+{\r
+ git_diff_flush(handle);\r
+ if(handle)\r
+ {\r
+ struct rev_info *p_Rev;\r
+ p_Rev=(struct rev_info *)handle;\r
+ if(p_Rev->pPrivate)\r
+ free(p_Rev->pPrivate);\r
+ free(handle);\r
+ }\r
+ return 0;\r
+}\r
+int git_diff_flush(GIT_DIFF diff)\r
+{\r
+ struct diff_queue_struct *q = &diff_queued_diff;\r
+ struct rev_info *p_Rev;\r
+ int i;\r
+ p_Rev = (struct rev_info *)diff;\r
+ \r
+ if(q->nr == 0)\r
+ return 0;\r
+\r
+ for (i = 0; i < q->nr; i++)\r
+ diff_free_filepair(q->queue[i]);\r
+\r
+ if(q->queue)\r
+ {\r
+ free(q->queue);\r
+ q->queue = NULL;\r
+ q->nr = q->alloc = 0;\r
+ }\r
+\r
+ if (p_Rev->diffopt.close_file)\r
+ fclose(p_Rev->diffopt.close_file);\r
+\r
+ free_diffstat_info(&p_Rev->diffstat);\r
+}\r
+\r
+int git_root_diff(GIT_DIFF diff, GIT_HASH hash,GIT_FILE *file, int *count)\r
+{\r
+ int ret;\r
+ struct rev_info *p_Rev;\r
+ int i;\r
+ struct diff_queue_struct *q = &diff_queued_diff;\r
+\r
+ p_Rev = (struct rev_info *)diff;\r
+\r
+ ret=diff_root_tree_sha1(hash, "", &p_Rev->diffopt);\r
+\r
+ if(ret)\r
+ return ret;\r
+\r
+ diffcore_std(&p_Rev->diffopt);\r
+\r
+ memset(&p_Rev->diffstat, 0, sizeof(struct diffstat_t));\r
+ for (i = 0; i < q->nr; i++) {\r
+ struct diff_filepair *p = q->queue[i];\r
+ //if (check_pair_status(p))\r
+ diff_flush_stat(p, &p_Rev->diffopt, &p_Rev->diffstat);\r
+ }\r
+\r
+ if(file)\r
+ *file = q;\r
+ if(count)\r
+ *count = q->nr;\r
+\r
+ return 0;\r
+}\r
+\r
+int git_diff(GIT_DIFF diff, GIT_HASH hash1, GIT_HASH hash2, GIT_FILE * file, int *count)\r
+{\r
+ struct rev_info *p_Rev;\r
+ int ret;\r
+ int i;\r
+ struct diff_queue_struct *q = &diff_queued_diff;\r
+ \r
+ p_Rev = (struct rev_info *)diff;\r
+\r
+ ret = diff_tree_sha1(hash1,hash2,"",&p_Rev->diffopt);\r
+ if( ret )\r
+ return ret;\r
+ \r
+ diffcore_std(&p_Rev->diffopt);\r
+\r
+ memset(&p_Rev->diffstat, 0, sizeof(struct diffstat_t));\r
+ for (i = 0; i < q->nr; i++) {\r
+ struct diff_filepair *p = q->queue[i];\r
+ //if (check_pair_status(p))\r
+ diff_flush_stat(p, &p_Rev->diffopt, &p_Rev->diffstat);\r
+ }\r
+\r
+ if(file)\r
+ *file = q;\r
+ if(count)\r
+ *count = q->nr;\r
+ return 0;\r
+}\r
+\r
+int git_get_diff_file(GIT_DIFF diff,GIT_FILE file,int i, char **newname, char ** oldname, int *status, int *IsBin, int *inc, int *dec)\r
+{\r
+ struct diff_queue_struct *q = &diff_queued_diff;\r
+ struct rev_info *p_Rev;\r
+ p_Rev = (struct rev_info *)diff;\r
+ \r
+ q = (struct diff_queue_struct *)file;\r
+ if(file == 0)\r
+ return -1;\r
+ if(i>=q->nr)\r
+ return -1;\r
+\r
+ if(newname)\r
+ *newname = q->queue[i]->two->path;\r
+\r
+ if(oldname)\r
+ *oldname = q->queue[i]->one->path;\r
+\r
+ if(status)\r
+ *status = q->queue[i]->status;\r
+\r
+ if(p_Rev->diffstat.files)\r
+ {\r
+ int j;\r
+ for(j=0;j<p_Rev->diffstat.nr;j++)\r
+ {\r
+ if(strcmp(*newname,p_Rev->diffstat.files[j]->name)==0)\r
+ break;\r
+ }\r
+ if( j== p_Rev->diffstat.nr)\r
+ {\r
+ *IsBin=1;\r
+ *inc=0;\r
+ *dec=0;\r
+ return 0;\r
+ }\r
+ if(IsBin)\r
+ *IsBin = p_Rev->diffstat.files[j]->is_binary;\r
+ if(inc)\r
+ *inc = p_Rev->diffstat.files[j]->added;\r
+ if(dec)\r
+ *dec = p_Rev->diffstat.files[j]->deleted;\r
+ }else\r
+ {\r
+ *IsBin=1;\r
+ *inc=0;\r
+ *dec=0;\r
+ }\r
+\r
+ return 0;\r
+}
\ No newline at end of file