1 // gitdll.cpp : Defines the exported functions for the DLL application.
5 #include "git-compat-util.h"
13 const char git_version_string
[] = GIT_VERSION
;
18 // This is an example of an exported variable
19 GITDLL_API
int ngitdll
=0;
21 // This is an example of an exported function.
22 GITDLL_API
int fngitdll(void)
27 // This is the constructor of a class that has been exported.
28 // see gitdll.h for the class definition
35 #define MAX_ERROR_STR_SIZE 512
36 char g_last_error
[MAX_ERROR_STR_SIZE
]={0};
39 char * get_git_last_error()
44 static void die_dll(const char *err
, va_list params
)
46 memset(g_last_error
,0,MAX_ERROR_STR_SIZE
);
47 vsnprintf(g_last_error
, MAX_ERROR_STR_SIZE
-1, err
, params
);
52 set_die_routine(die_dll
);
55 int git_get_sha1(const char *name
, GIT_HASH sha1
)
57 return get_sha1(name
,sha1
);
60 static int convert_slash(char * path
)
73 char path
[MAX_PATH
+1];
75 size_t homesize
,size
,httpsize
;
78 _setmode(_fileno(stdin
), _O_BINARY
);
79 _setmode(_fileno(stdout
), _O_BINARY
);
80 _setmode(_fileno(stderr
), _O_BINARY
);
82 // set HOME if not set already
83 getenv_s(&homesize
, NULL
, 0, "HOME");
86 _dupenv_s(&home
,&size
,"USERPROFILE");
87 _putenv_s("HOME",home
);
90 GetModuleFileName(NULL
, path
, MAX_PATH
);
93 git_extract_argv0_path(path
);
94 g_prefix
= prefix
= setup_git_directory();
95 return git_config(git_default_config
, NULL
);
98 static int git_parse_commit_author(struct GIT_COMMIT_AUTHOR
*author
, char *pbuff
)
103 end
=strchr(pbuff
,'<');
108 author
->NameSize
= end
- pbuff
- 1;
111 end
= strchr(pbuff
, '>');
115 author
->Email
= pbuff
;
116 author
->EmailSize
= end
- pbuff
;
120 author
->Date
= atol(pbuff
);
121 end
= strchr(pbuff
, ' ');
126 author
->TimeZone
= atol(pbuff
);
131 int git_parse_commit(GIT_COMMIT
*commit
)
138 p
= (struct commit
*)commit
->m_pGitCommit
;
140 memcpy(commit
->m_hash
,p
->object
.sha1
,GIT_HASH_SIZE
);
142 commit
->m_Encode
= NULL
;
143 commit
->m_EncodeSize
= 0;
145 if(p
->buffer
== NULL
)
151 if( strncmp(pbuf
,"author",6) == 0)
153 ret
= git_parse_commit_author(&commit
->m_Author
,pbuf
+ 7);
157 if( strncmp(pbuf
, "committer",9) == 0)
159 ret
= git_parse_commit_author(&commit
->m_Committer
,pbuf
+ 10);
163 pbuf
= strchr(pbuf
,'\n');
167 while((*pbuf
) && (*pbuf
== '\n'))
170 if( strncmp(pbuf
, "encoding",8) == 0 )
173 commit
->m_Encode
=pbuf
;
174 end
= strchr(pbuf
,'\n');
175 commit
->m_EncodeSize
=end
-pbuf
;
178 while((*pbuf
) && (*pbuf
== '\n'))
181 commit
->m_Subject
=pbuf
;
182 end
= strchr(pbuf
,'\n');
184 commit
->m_SubjectSize
= strlen(pbuf
);
187 commit
->m_SubjectSize
= end
- pbuf
;
189 commit
->m_Body
= pbuf
;
190 commit
->m_BodySize
= strlen(pbuf
);
196 pbuf
= strchr(pbuf
,'\n');
203 int git_get_commit_from_hash(GIT_COMMIT
*commit
, GIT_HASH hash
)
209 memset(commit
,0,sizeof(GIT_COMMIT
));
211 commit
->m_pGitCommit
= p
= lookup_commit(hash
);
219 ret
= parse_commit(p
);
223 return git_parse_commit(commit
);
226 int git_get_commit_first_parent(GIT_COMMIT
*commit
,GIT_COMMIT_LIST
*list
)
228 struct commit
*p
= commit
->m_pGitCommit
;
233 *list
= (GIT_COMMIT_LIST
*)p
->parents
;
236 int git_get_commit_next_parent(GIT_COMMIT_LIST
*list
, GIT_HASH hash
)
238 struct commit_list
*l
= *(struct commit_list
**)list
;
239 if(list
== NULL
|| l
==NULL
)
243 memcpy(hash
, l
->item
->object
.sha1
, GIT_HASH_SIZE
);
245 *list
= (GIT_COMMIT_LIST
*)l
->next
;
251 int git_free_commit(GIT_COMMIT
*commit
)
253 struct commit
*p
= commit
->m_pGitCommit
;
256 free_commit_list(p
->parents
);
266 memset(commit
,0,sizeof(GIT_COMMIT
));
270 char **strtoargv(char *arg
, int *size
)
292 argv
=malloc(strlen(arg
)+1 + (count
+2)*sizeof(void*));
293 p
=(char*)(argv
+count
+2);
302 while(*arg
&& *arg
!= '"')
313 while(*arg
&& *arg
!=' ')
324 int git_open_log(GIT_LOG
* handle
, char * arg
)
326 struct rev_info
*p_Rev
;
333 unsigned int obj_size
= get_max_object_index();
334 for(i
=0; i
<obj_size
; i
++)
336 struct object
*ob
= get_indexed_object(i
);
342 argv
= strtoargv(arg
,&argc
);
344 p_Rev
= malloc(sizeof(struct rev_info
));
345 memset(p_Rev
,0,sizeof(struct rev_info
));
350 init_revisions(p_Rev
, g_prefix
);
353 cmd_log_init(argc
, argv
, g_prefix
,p_Rev
);
355 p_Rev
->pPrivate
= argv
;
360 int git_get_log_firstcommit(GIT_LOG handle
)
362 return prepare_revision_walk(handle
);
365 int git_get_log_estimate_commit_count(GIT_LOG handle
)
367 struct rev_info
*p_Rev
;
368 p_Rev
=(struct rev_info
*)handle
;
370 return estimate_commit_count(p_Rev
, p_Rev
->commits
);
373 int git_get_log_nextcommit(GIT_LOG handle
, GIT_COMMIT
*commit
)
377 commit
->m_pGitCommit
= get_revision(handle
);
378 if( commit
->m_pGitCommit
== NULL
)
381 ret
=git_parse_commit(commit
);
388 int git_close_log(GIT_LOG handle
)
392 struct rev_info
*p_Rev
;
393 p_Rev
=(struct rev_info
*)handle
;
395 free(p_Rev
->pPrivate
);
402 int git_open_diff(GIT_DIFF
*diff
, char * arg
)
404 struct rev_info
*p_Rev
;
410 argv
= strtoargv(arg
,&argc
);
412 p_Rev
= malloc(sizeof(struct rev_info
));
413 memset(p_Rev
,0,sizeof(struct rev_info
));
415 p_Rev
->pPrivate
= argv
;
416 *diff
= (GIT_DIFF
)p_Rev
;
418 init_revisions(p_Rev
, g_prefix
);
419 git_config(git_diff_basic_config
, NULL
); /* no "diff" UI options */
422 argc
= setup_revisions(argc
, argv
, p_Rev
, NULL
);
426 int git_close_diff(GIT_DIFF handle
)
428 git_diff_flush(handle
);
431 struct rev_info
*p_Rev
;
432 p_Rev
=(struct rev_info
*)handle
;
434 free(p_Rev
->pPrivate
);
439 int git_diff_flush(GIT_DIFF diff
)
441 struct diff_queue_struct
*q
= &diff_queued_diff
;
442 struct rev_info
*p_Rev
;
444 p_Rev
= (struct rev_info
*)diff
;
449 for (i
= 0; i
< q
->nr
; i
++)
450 diff_free_filepair(q
->queue
[i
]);
456 q
->nr
= q
->alloc
= 0;
459 if (p_Rev
->diffopt
.close_file
)
460 fclose(p_Rev
->diffopt
.close_file
);
462 free_diffstat_info(&p_Rev
->diffstat
);
465 int git_root_diff(GIT_DIFF diff
, GIT_HASH hash
,GIT_FILE
*file
, int *count
)
468 struct rev_info
*p_Rev
;
470 struct diff_queue_struct
*q
= &diff_queued_diff
;
472 p_Rev
= (struct rev_info
*)diff
;
474 ret
=diff_root_tree_sha1(hash
, "", &p_Rev
->diffopt
);
479 diffcore_std(&p_Rev
->diffopt
);
481 memset(&p_Rev
->diffstat
, 0, sizeof(struct diffstat_t
));
482 for (i
= 0; i
< q
->nr
; i
++) {
483 struct diff_filepair
*p
= q
->queue
[i
];
484 //if (check_pair_status(p))
485 diff_flush_stat(p
, &p_Rev
->diffopt
, &p_Rev
->diffstat
);
496 int git_diff(GIT_DIFF diff
, GIT_HASH hash1
, GIT_HASH hash2
, GIT_FILE
* file
, int *count
)
498 struct rev_info
*p_Rev
;
501 struct diff_queue_struct
*q
= &diff_queued_diff
;
503 p_Rev
= (struct rev_info
*)diff
;
505 ret
= diff_tree_sha1(hash1
,hash2
,"",&p_Rev
->diffopt
);
509 diffcore_std(&p_Rev
->diffopt
);
511 memset(&p_Rev
->diffstat
, 0, sizeof(struct diffstat_t
));
512 for (i
= 0; i
< q
->nr
; i
++) {
513 struct diff_filepair
*p
= q
->queue
[i
];
514 //if (check_pair_status(p))
515 diff_flush_stat(p
, &p_Rev
->diffopt
, &p_Rev
->diffstat
);
525 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
)
527 struct diff_queue_struct
*q
= &diff_queued_diff
;
528 struct rev_info
*p_Rev
;
529 p_Rev
= (struct rev_info
*)diff
;
531 q
= (struct diff_queue_struct
*)file
;
538 *newname
= q
->queue
[i
]->two
->path
;
541 *oldname
= q
->queue
[i
]->one
->path
;
544 *status
= q
->queue
[i
]->status
;
546 if(p_Rev
->diffstat
.files
)
549 for(j
=0;j
<p_Rev
->diffstat
.nr
;j
++)
551 if(strcmp(*newname
,p_Rev
->diffstat
.files
[j
]->name
)==0)
554 if( j
== p_Rev
->diffstat
.nr
)
562 *IsBin
= p_Rev
->diffstat
.files
[j
]->is_binary
;
564 *inc
= p_Rev
->diffstat
.files
[j
]->added
;
566 *dec
= p_Rev
->diffstat
.files
[j
]->deleted
;