7 #include "git-compat-util.h"
15 #define IGIT_VERSION "0.1.0"
18 #define SAFE_FREE(_x) if (_x) { free(_x); _x = NULL; }
20 #define ASSERT(_x) //assert(_x)
23 static char l_sGitBinPath
[2048];
26 /////////////////////////////////////////////////////////////////////
29 // GitCommandInit flags (mirrored from git.c)
30 #define RUN_SETUP (1<<0)
31 #define USE_PAGER (1<<1)
32 #define NEED_WORK_TREE (1<<2)
35 // GitCommandInit - does the basic init of run_command in git.c (returns path relative to project root)
36 static const char* GitCommandInit(int flags
)
38 // simple init in main of git.c to set up git sys path
40 git_extract_argv0_path(l_sGitBinPath
);
44 // init from run_command
46 const char *prefix
= NULL
;
48 if (flags
& RUN_SETUP
)
49 prefix
= setup_git_directory();
51 if (flags
& NEED_WORK_TREE
)
58 void fputsha1(LPBYTE sha1
, FILE *fp
)
63 fprintf(fp
, "%02x", (UINT
)*sha1
++);
67 /////////////////////////////////////////////////////////////////////
70 static LPSTR
nextpath(LPCSTR src
, LPSTR dst
, UINT maxlen
)
82 while (*src
&& *src
!= ';')
96 while (*src
&& *src
!= '"')
118 return (orgsrc
!= src
) ? (LPSTR
)src
: NULL
;
121 static inline BOOL
FileExists(LPCSTR lpszFileName
)
124 return lstat(lpszFileName
, &st
) == 0;
127 static BOOL
FindGitPath()
131 if ( !(env
= getenv("PATH")) )
138 const LPCSTR filename
= "git.exe";
139 const int filelen
= strlen(filename
);
141 // search in all paths defined in PATH
142 while ((env
= nextpath(env
, buf
, _MAX_PATH
-1)) && *buf
)
144 char *pfin
= buf
+ strlen(buf
)-1;
146 // ensure trailing slash
147 if (*pfin
!= '/' && *pfin
!= '\\')
148 strcpy(pfin
+1, "\\");
150 const int len
= strlen(buf
);
152 if ((len
+ filelen
) < _MAX_PATH
)
153 strcpy(buf
+len
, filename
);
157 if ( FileExists(buf
) )
160 memcpy(l_sGitBinPath
, buf
, len
);
161 l_sGitBinPath
[len
] = 0;
170 BOOL
igInitPath(void)
172 if ( !FindGitPath() )
174 // fallback and use path of libiconv2.dll which wingit is linked to and normally is located in the git dir
175 if ( !GetModuleFileName(GetModuleHandle("libiconv2.dll"), l_sGitBinPath
, sizeof(l_sGitBinPath
)) )
177 OutputDebugString("[IGIT] Failed to locate Git/bin path\r\n");
182 // slashify path to avoid mixing back and forward slashes (git uses forward)
183 char *p
= l_sGitBinPath
;
186 if (*p
== '\\') *p
= '/';
194 /////////////////////////////////////////////////////////////////////
195 // igEnumFiles - based on builtin-ls-files
197 extern BOOL
ig_enum_files(const char *pszProjectPath
, const char *pszSubPath
, const char *prefix
, unsigned int nFlags
);
200 int igEnumFiles(const char *pszProjectPath
, const char *pszSubPath
, unsigned int nFlags
)
205 int len
= strlen(pszSubPath
);
207 //char *s = alloca(len+1);
208 //strcpy(s, pszSubPath);
209 char *s
= strdup(pszSubPath
);
215 if (*p
== '\\') *p
= '/';
219 // remove trailing slashes
221 while (*c
== '/' && c
> s
) *c
-- = 0;
222 // remove initial slashes
223 while (*s
== '/') s
++;
225 pszSubPath
= *s
? s
: NULL
;
228 const char *prefix
= GitCommandInit(RUN_SETUP
);
230 if ( !ig_enum_files(pszProjectPath
, pszSubPath
, prefix
, nFlags
) )
239 /////////////////////////////////////////////////////////////////////
242 int igGetRevisionID(const char *pszName
)
248 git_config(git_default_config
, NULL
);
250 if ( !get_sha1(pszName
, sha1
) )
252 fputsha1(sha1
, stdout
);
262 /////////////////////////////////////////////////////////////////////
265 int main(int argc
, const char **argv
)
269 if (argc
== 2 && !strcasecmp(argv
[1], "version"))
271 fputs(IGIT_VERSION
, stdout
);
276 fputs("igit v"IGIT_VERSION
" - backend interface to git intended for use by frontends\n\n", stderr
);
277 fputs("usage: igit <project path> <command> [params]*\n", stderr
);
278 fputs(" igit version\n\n", stderr
);
279 fputs("commands:\n", stderr
);
280 fputs(" revision [name] SHA1 for specified commit or HEAD if none\n", stderr
);
281 fputs(" status [flags [sub path]] list working copy files with status\n", stderr
);
282 fputs(" flags: CdDefrs-\n", stderr
);
291 //if (argv[0] && *argv[0])
292 // git_extract_argv0_path(argv[0]);
293 git_extract_argv0_path(l_sGitBinPath
);
300 const char *projpath
= argv
[0];
302 if ( chdir(projpath
) )
310 const char *cmd
= argv
[0];
319 if ( !strcasecmp(cmd
, "revision") )
321 const char *name
= argc
? argv
[0] : "HEAD";
323 res
= igGetRevisionID(name
);
325 else if ( !strcasecmp(cmd
, "status") )
328 LPCSTR pszSubPath
= NULL
;
337 case 'd': nFlags
|= WGEFF_DirStatusDelta
; break;
338 case 'D': nFlags
|= WGEFF_DirStatusAll
; break;
339 case 'e': nFlags
|= WGEFF_EmptyAsNormal
; break;
340 case 'f': nFlags
|= WGEFF_FullPath
; break;
341 case 'r': nFlags
|= WGEFF_NoRecurse
; break;
342 case 's': nFlags
|= WGEFF_SingleFile
; break;
343 case 'C': nFlags
|= WGEFF_NoCacheIndex
; break;
348 pszSubPath
= argv
[1];
351 res
= igEnumFiles(projpath
, pszSubPath
, nFlags
);