1 // gitdll.cpp : Defines the exported functions for the DLL application.
\r
5 #include "git-compat-util.h"
\r
11 #include "revision.h"
\r
12 #include "diffcore.h"
\r
13 const char git_version_string[] = GIT_VERSION;
\r
18 // This is an example of an exported variable
\r
19 GITDLL_API int ngitdll=0;
\r
21 // This is an example of an exported function.
\r
22 GITDLL_API int fngitdll(void)
\r
27 // This is the constructor of a class that has been exported.
\r
28 // see gitdll.h for the class definition
\r
35 #define MAX_ERROR_STR_SIZE 512
\r
36 char g_last_error[MAX_ERROR_STR_SIZE]={0};
\r
39 char * get_git_last_error()
\r
41 return g_last_error;
\r
44 static void die_dll(const char *err, va_list params)
\r
46 memset(g_last_error,0,MAX_ERROR_STR_SIZE);
\r
47 vsnprintf(g_last_error, MAX_ERROR_STR_SIZE-1, err, params);
\r
52 set_die_routine(die_dll);
\r
55 int git_get_sha1(const char *name, GIT_HASH sha1)
\r
57 return get_sha1(name,sha1);
\r
60 static int convert_slash(char * path)
\r
73 char path[MAX_PATH+1];
\r
75 size_t homesize,size,httpsize;
\r
77 // set HOME if not set already
\r
78 getenv_s(&homesize, NULL, 0, "HOME");
\r
81 _dupenv_s(&home,&size,"USERPROFILE");
\r
82 _putenv_s("HOME",home);
\r
85 GetModuleFileName(NULL, path, MAX_PATH);
\r
86 convert_slash(path);
\r
88 git_extract_argv0_path(path);
\r
89 g_prefix = prefix = setup_git_directory();
\r
90 return git_config(git_default_config, NULL);
\r
93 static int git_parse_commit_author(struct GIT_COMMIT_AUTHOR *author, char *pbuff)
\r
98 end=strchr(pbuff,'<');
\r
103 author->NameSize = end - pbuff - 1;
\r
106 end = strchr(pbuff, '>');
\r
110 author->Email = pbuff ;
\r
111 author->EmailSize = end - pbuff;
\r
115 author->Date = atol(pbuff);
\r
116 end = strchr(pbuff, ' ');
\r
121 author->TimeZone = atol(pbuff);
\r
126 int git_parse_commit(GIT_COMMIT *commit)
\r
133 p= (struct commit *)commit->m_pGitCommit;
\r
135 memcpy(commit->m_hash,p->object.sha1,GIT_HASH_SIZE);
\r
137 if(p->buffer == NULL)
\r
143 if( strncmp(pbuf,"author",6) == 0)
\r
145 ret = git_parse_commit_author(&commit->m_Author,pbuf + 7);
\r
149 if( strncmp(pbuf, "committer",9) == 0)
\r
151 ret = git_parse_commit_author(&commit->m_Committer,pbuf + 10);
\r
155 pbuf = strchr(pbuf,'\n');
\r
159 while((*pbuf) && (*pbuf == '\n'))
\r
162 commit->m_Subject=pbuf;
\r
163 end = strchr(pbuf,'\n');
\r
165 commit->m_SubjectSize = strlen(pbuf);
\r
168 commit->m_SubjectSize = end - pbuf;
\r
170 commit->m_Body = pbuf;
\r
171 commit->m_BodySize = strlen(pbuf);
\r
177 pbuf = strchr(pbuf,'\n');
\r
184 int git_get_commit_from_hash(GIT_COMMIT *commit, GIT_HASH hash)
\r
189 commit->m_pGitCommit = p = lookup_commit(hash);
\r
197 ret = parse_commit(p);
\r
201 return git_parse_commit(commit);
\r
204 int git_get_commit_first_parent(GIT_COMMIT *commit,GIT_COMMIT_LIST *list)
\r
206 struct commit *p = commit->m_pGitCommit;
\r
211 *list = (GIT_COMMIT_LIST*)p->parents;
\r
214 int git_get_commit_next_parent(GIT_COMMIT_LIST *list, GIT_HASH hash)
\r
216 struct commit_list *l = *(struct commit_list **)list;
\r
217 if(list == NULL || l==NULL)
\r
221 memcpy(hash, l->item->object.sha1, GIT_HASH_SIZE);
\r
223 *list = (GIT_COMMIT_LIST *)l->next;
\r
229 int git_free_commit(GIT_COMMIT *commit)
\r
231 struct commit *p = commit->m_pGitCommit;
\r
234 free_commit_list(p->parents);
\r
240 p->object.parsed=0;
\r
244 memset(commit,0,sizeof(GIT_COMMIT));
\r
248 char **strtoargv(char *arg, int *size)
\r
261 argv=malloc(strlen(arg)+1 + (count +2)*sizeof(void*));
\r
262 p=(char*)(argv+count+2);
\r
271 while(*arg && *arg!= '"')
\r
282 while(*arg && *arg !=' ')
\r
293 int git_open_log(GIT_LOG * handle, char * arg)
\r
295 struct rev_info *p_Rev;
\r
301 argv = strtoargv(arg,&argc);
\r
303 p_Rev = malloc(sizeof(struct rev_info));
\r
304 memset(p_Rev,0,sizeof(struct rev_info));
\r
309 init_revisions(p_Rev, g_prefix);
\r
311 p_Rev->simplify_history = 0;
\r
313 cmd_log_init(argc, argv, g_prefix,p_Rev);
\r
315 p_Rev->pPrivate = argv;
\r
320 int git_get_log_firstcommit(GIT_LOG handle)
\r
322 return prepare_revision_walk(handle);
\r
325 int git_get_log_nextcommit(GIT_LOG handle, GIT_COMMIT *commit)
\r
329 commit->m_pGitCommit = get_revision(handle);
\r
330 if( commit->m_pGitCommit == NULL)
\r
333 ret=git_parse_commit(commit);
\r
340 int git_close_log(GIT_LOG handle)
\r
344 struct rev_info *p_Rev;
\r
345 p_Rev=(struct rev_info *)handle;
\r
346 if(p_Rev->pPrivate)
\r
347 free(p_Rev->pPrivate);
\r
354 int git_open_diff(GIT_DIFF *diff, char * arg)
\r
356 struct rev_info *p_Rev;
\r
362 argv = strtoargv(arg,&argc);
\r
364 p_Rev = malloc(sizeof(struct rev_info));
\r
365 memset(p_Rev,0,sizeof(struct rev_info));
\r
367 p_Rev->pPrivate = argv;
\r
368 *diff = (GIT_DIFF)p_Rev;
\r
370 init_revisions(p_Rev, g_prefix);
\r
371 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
\r
374 argc = setup_revisions(argc, argv, p_Rev, NULL);
\r
378 int git_close_diff(GIT_DIFF handle)
\r
380 git_diff_flush(handle);
\r
383 struct rev_info *p_Rev;
\r
384 p_Rev=(struct rev_info *)handle;
\r
385 if(p_Rev->pPrivate)
\r
386 free(p_Rev->pPrivate);
\r
391 int git_diff_flush(GIT_DIFF diff)
\r
393 struct diff_queue_struct *q = &diff_queued_diff;
\r
394 struct rev_info *p_Rev;
\r
396 p_Rev = (struct rev_info *)diff;
\r
401 for (i = 0; i < q->nr; i++)
\r
402 diff_free_filepair(q->queue[i]);
\r
408 q->nr = q->alloc = 0;
\r
411 if (p_Rev->diffopt.close_file)
\r
412 fclose(p_Rev->diffopt.close_file);
\r
414 free_diffstat_info(&p_Rev->diffstat);
\r
416 int git_diff(GIT_DIFF diff, GIT_HASH hash1, GIT_HASH hash2, GIT_FILE * file, int *count)
\r
418 struct rev_info *p_Rev;
\r
421 struct diff_queue_struct *q = &diff_queued_diff;
\r
423 p_Rev = (struct rev_info *)diff;
\r
425 ret = diff_tree_sha1(hash1,hash2,"",&p_Rev->diffopt);
\r
429 diffcore_std(&p_Rev->diffopt);
\r
431 memset(&p_Rev->diffstat, 0, sizeof(struct diffstat_t));
\r
432 for (i = 0; i < q->nr; i++) {
\r
433 struct diff_filepair *p = q->queue[i];
\r
434 //if (check_pair_status(p))
\r
435 diff_flush_stat(p, &p_Rev->diffopt, &p_Rev->diffstat);
\r
445 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
447 struct diff_queue_struct *q = &diff_queued_diff;
\r
448 struct rev_info *p_Rev;
\r
449 p_Rev = (struct rev_info *)diff;
\r
451 q = (struct diff_queue_struct *)file;
\r
458 *newname = q->queue[i]->one->path;
\r
461 *oldname = q->queue[i]->two->path;
\r
464 *status = q->queue[i]->status;
\r
466 if(p_Rev->diffstat.files)
\r
469 for(j=0;j<p_Rev->diffstat.nr;j++)
\r
471 if(strcmp(*newname,p_Rev->diffstat.files[j]->name)==0)
\r
474 if( j== p_Rev->diffstat.nr)
\r
482 *IsBin = p_Rev->diffstat.files[j]->is_binary;
\r
484 *inc = p_Rev->diffstat.files[j]->added;
\r
486 *dec = p_Rev->diffstat.files[j]->deleted;
\r