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 commit->m_Encode = NULL;
\r
138 commit->m_EncodeSize = 0;
\r
140 if(p->buffer == NULL)
\r
146 if( strncmp(pbuf,"author",6) == 0)
\r
148 ret = git_parse_commit_author(&commit->m_Author,pbuf + 7);
\r
152 if( strncmp(pbuf, "committer",9) == 0)
\r
154 ret = git_parse_commit_author(&commit->m_Committer,pbuf + 10);
\r
158 pbuf = strchr(pbuf,'\n');
\r
162 while((*pbuf) && (*pbuf == '\n'))
\r
165 if( strncmp(pbuf, "encoding",8) == 0 )
\r
168 commit->m_Encode=pbuf;
\r
169 end = strchr(pbuf,'\n');
\r
170 commit->m_EncodeSize=end -pbuf;
\r
173 while((*pbuf) && (*pbuf == '\n'))
\r
176 commit->m_Subject=pbuf;
\r
177 end = strchr(pbuf,'\n');
\r
179 commit->m_SubjectSize = strlen(pbuf);
\r
182 commit->m_SubjectSize = end - pbuf;
\r
184 commit->m_Body = pbuf;
\r
185 commit->m_BodySize = strlen(pbuf);
\r
191 pbuf = strchr(pbuf,'\n');
\r
198 int git_get_commit_from_hash(GIT_COMMIT *commit, GIT_HASH hash)
\r
204 memset(commit,0,sizeof(GIT_COMMIT));
\r
206 commit->m_pGitCommit = p = lookup_commit(hash);
\r
214 ret = parse_commit(p);
\r
218 return git_parse_commit(commit);
\r
221 int git_get_commit_first_parent(GIT_COMMIT *commit,GIT_COMMIT_LIST *list)
\r
223 struct commit *p = commit->m_pGitCommit;
\r
228 *list = (GIT_COMMIT_LIST*)p->parents;
\r
231 int git_get_commit_next_parent(GIT_COMMIT_LIST *list, GIT_HASH hash)
\r
233 struct commit_list *l = *(struct commit_list **)list;
\r
234 if(list == NULL || l==NULL)
\r
238 memcpy(hash, l->item->object.sha1, GIT_HASH_SIZE);
\r
240 *list = (GIT_COMMIT_LIST *)l->next;
\r
246 int git_free_commit(GIT_COMMIT *commit)
\r
248 struct commit *p = commit->m_pGitCommit;
\r
251 free_commit_list(p->parents);
\r
257 p->object.parsed=0;
\r
261 memset(commit,0,sizeof(GIT_COMMIT));
\r
265 char **strtoargv(char *arg, int *size)
\r
278 argv=malloc(strlen(arg)+1 + (count +2)*sizeof(void*));
\r
279 p=(char*)(argv+count+2);
\r
288 while(*arg && *arg!= '"')
\r
299 while(*arg && *arg !=' ')
\r
310 int git_open_log(GIT_LOG * handle, char * arg)
\r
312 struct rev_info *p_Rev;
\r
319 unsigned int obj_size = get_max_object_index();
\r
320 for(i =0; i<obj_size; i++)
\r
322 struct object *ob= get_indexed_object(i);
\r
328 argv = strtoargv(arg,&argc);
\r
330 p_Rev = malloc(sizeof(struct rev_info));
\r
331 memset(p_Rev,0,sizeof(struct rev_info));
\r
336 init_revisions(p_Rev, g_prefix);
\r
338 p_Rev->simplify_history = 0;
\r
340 cmd_log_init(argc, argv, g_prefix,p_Rev);
\r
342 p_Rev->pPrivate = argv;
\r
347 int git_get_log_firstcommit(GIT_LOG handle)
\r
349 return prepare_revision_walk(handle);
\r
352 int git_get_log_estimate_commit_count(GIT_LOG handle)
\r
354 struct rev_info *p_Rev;
\r
355 p_Rev=(struct rev_info *)handle;
\r
357 return estimate_commit_count(p_Rev, p_Rev->commits);
\r
360 int git_get_log_nextcommit(GIT_LOG handle, GIT_COMMIT *commit)
\r
364 commit->m_pGitCommit = get_revision(handle);
\r
365 if( commit->m_pGitCommit == NULL)
\r
368 ret=git_parse_commit(commit);
\r
375 int git_close_log(GIT_LOG handle)
\r
379 struct rev_info *p_Rev;
\r
380 p_Rev=(struct rev_info *)handle;
\r
381 if(p_Rev->pPrivate)
\r
382 free(p_Rev->pPrivate);
\r
389 int git_open_diff(GIT_DIFF *diff, char * arg)
\r
391 struct rev_info *p_Rev;
\r
397 argv = strtoargv(arg,&argc);
\r
399 p_Rev = malloc(sizeof(struct rev_info));
\r
400 memset(p_Rev,0,sizeof(struct rev_info));
\r
402 p_Rev->pPrivate = argv;
\r
403 *diff = (GIT_DIFF)p_Rev;
\r
405 init_revisions(p_Rev, g_prefix);
\r
406 git_config(git_diff_basic_config, NULL); /* no "diff" UI options */
\r
409 argc = setup_revisions(argc, argv, p_Rev, NULL);
\r
413 int git_close_diff(GIT_DIFF handle)
\r
415 git_diff_flush(handle);
\r
418 struct rev_info *p_Rev;
\r
419 p_Rev=(struct rev_info *)handle;
\r
420 if(p_Rev->pPrivate)
\r
421 free(p_Rev->pPrivate);
\r
426 int git_diff_flush(GIT_DIFF diff)
\r
428 struct diff_queue_struct *q = &diff_queued_diff;
\r
429 struct rev_info *p_Rev;
\r
431 p_Rev = (struct rev_info *)diff;
\r
436 for (i = 0; i < q->nr; i++)
\r
437 diff_free_filepair(q->queue[i]);
\r
443 q->nr = q->alloc = 0;
\r
446 if (p_Rev->diffopt.close_file)
\r
447 fclose(p_Rev->diffopt.close_file);
\r
449 free_diffstat_info(&p_Rev->diffstat);
\r
452 int git_root_diff(GIT_DIFF diff, GIT_HASH hash,GIT_FILE *file, int *count)
\r
455 struct rev_info *p_Rev;
\r
457 struct diff_queue_struct *q = &diff_queued_diff;
\r
459 p_Rev = (struct rev_info *)diff;
\r
461 ret=diff_root_tree_sha1(hash, "", &p_Rev->diffopt);
\r
466 diffcore_std(&p_Rev->diffopt);
\r
468 memset(&p_Rev->diffstat, 0, sizeof(struct diffstat_t));
\r
469 for (i = 0; i < q->nr; i++) {
\r
470 struct diff_filepair *p = q->queue[i];
\r
471 //if (check_pair_status(p))
\r
472 diff_flush_stat(p, &p_Rev->diffopt, &p_Rev->diffstat);
\r
483 int git_diff(GIT_DIFF diff, GIT_HASH hash1, GIT_HASH hash2, GIT_FILE * file, int *count)
\r
485 struct rev_info *p_Rev;
\r
488 struct diff_queue_struct *q = &diff_queued_diff;
\r
490 p_Rev = (struct rev_info *)diff;
\r
492 ret = diff_tree_sha1(hash1,hash2,"",&p_Rev->diffopt);
\r
496 diffcore_std(&p_Rev->diffopt);
\r
498 memset(&p_Rev->diffstat, 0, sizeof(struct diffstat_t));
\r
499 for (i = 0; i < q->nr; i++) {
\r
500 struct diff_filepair *p = q->queue[i];
\r
501 //if (check_pair_status(p))
\r
502 diff_flush_stat(p, &p_Rev->diffopt, &p_Rev->diffstat);
\r
512 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
514 struct diff_queue_struct *q = &diff_queued_diff;
\r
515 struct rev_info *p_Rev;
\r
516 p_Rev = (struct rev_info *)diff;
\r
518 q = (struct diff_queue_struct *)file;
\r
525 *newname = q->queue[i]->two->path;
\r
528 *oldname = q->queue[i]->one->path;
\r
531 *status = q->queue[i]->status;
\r
533 if(p_Rev->diffstat.files)
\r
536 for(j=0;j<p_Rev->diffstat.nr;j++)
\r
538 if(strcmp(*newname,p_Rev->diffstat.files[j]->name)==0)
\r
541 if( j== p_Rev->diffstat.nr)
\r
549 *IsBin = p_Rev->diffstat.files[j]->is_binary;
\r
551 *inc = p_Rev->diffstat.files[j]->added;
\r
553 *dec = p_Rev->diffstat.files[j]->deleted;
\r