OSDN Git Service

d0271dd979bfba76f56a6768c854f8ae5c25123d
[tortoisegit/TortoiseGitJp.git] / src / Git / Git.cpp
1 #include "StdAfx.h"\r
2 #include "Git.h"\r
3 #include "atlconv.h"\r
4 #include "GitRev.h"\r
5 \r
6 #define MAX_DIRBUFFER 1000\r
7 CGit g_Git;\r
8 CGit::CGit(void)\r
9 {\r
10         GetCurrentDirectory(MAX_DIRBUFFER,m_CurrentDir.GetBuffer(MAX_DIRBUFFER));\r
11 }\r
12 \r
13 CGit::~CGit(void)\r
14 {\r
15 }\r
16 \r
17 char buffer[4096];\r
18 \r
19 int CGit::Run(CString cmd, CString* output)\r
20 {\r
21         SECURITY_ATTRIBUTES sa;\r
22         HANDLE hRead, hWrite;\r
23 \r
24         sa.nLength = sizeof(SECURITY_ATTRIBUTES);\r
25         sa.lpSecurityDescriptor=NULL;\r
26         sa.bInheritHandle=TRUE;\r
27         if(!CreatePipe(&hRead,&hWrite,&sa,0))\r
28         {\r
29                 return GIT_ERROR_OPEN_PIP;\r
30         }\r
31         \r
32         STARTUPINFO si;\r
33         PROCESS_INFORMATION pi;\r
34         si.cb=sizeof(STARTUPINFO);\r
35         GetStartupInfo(&si);\r
36 \r
37         si.hStdError=hWrite;\r
38         si.hStdOutput=hWrite;\r
39         si.wShowWindow=SW_HIDE;\r
40         si.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;\r
41 \r
42         \r
43         if(!CreateProcess(NULL,(LPWSTR)cmd.GetString(), NULL,NULL,TRUE,NULL,NULL,(LPWSTR)m_CurrentDir.GetString(),&si,&pi))\r
44         {\r
45                 LPVOID lpMsgBuf;\r
46                 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,\r
47                         NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\r
48                         (LPTSTR)&lpMsgBuf,\r
49                         0,NULL);\r
50                 return GIT_ERROR_CREATE_PROCESS;\r
51         }\r
52         \r
53         CloseHandle(hWrite);\r
54 \r
55         DWORD readnumber;\r
56         while(ReadFile(hRead,buffer,4090,&readnumber,NULL))\r
57         {\r
58                 buffer[readnumber]=0;\r
59                 USES_CONVERSION;\r
60                 output->Append(A2W(buffer));\r
61         }\r
62 \r
63         \r
64         CloseHandle(pi.hThread);\r
65 \r
66         WaitForSingleObject(pi.hProcess, INFINITE);\r
67         DWORD exitcode =0;\r
68 \r
69         if(!GetExitCodeProcess(pi.hProcess,&exitcode))\r
70         {\r
71                 return GIT_ERROR_GET_EXIT_CODE;\r
72         }\r
73 \r
74         CloseHandle(pi.hProcess);\r
75 \r
76         CloseHandle(hRead);\r
77         return exitcode;\r
78 }\r
79 \r
80 CString CGit::GetUserName(void)\r
81 {\r
82         CString UserName;\r
83         Run(_T("git.cmd config user.name"),&UserName);\r
84         return UserName;\r
85 }\r
86 CString CGit::GetUserEmail(void)\r
87 {\r
88         CString UserName;\r
89         Run(_T("git.cmd config user.email"),&UserName);\r
90         return UserName;\r
91 }\r
92 \r
93 CString CGit::GetCurrentBranch(void)\r
94 {\r
95         CString branch;\r
96         Run(_T("git.cmd branch"),&branch);\r
97         if(branch.GetLength()>0)\r
98         {\r
99                 branch.Replace(_T('*'),_T(' '));\r
100                 branch.TrimLeft();\r
101                 return branch;\r
102         }\r
103         return CString("");\r
104 }\r
105 \r
106 int CGit::GetLog(CString& logOut)\r
107 {\r
108 \r
109         CString cmd;\r
110         CString log;\r
111         cmd=("git.cmd log -C --numstat --raw --pretty=format:\"");\r
112         log.Format(_T("#<%c>%%n"),LOG_REV_ITEM_BEGIN);\r
113         cmd += log;\r
114         log.Format(_T("#<%c>%%an%%n"),LOG_REV_AUTHOR_NAME);\r
115         cmd += log;\r
116         log.Format(_T("#<%c>%%ae%%n"),LOG_REV_AUTHOR_EMAIL);\r
117         cmd += log;\r
118         log.Format(_T("#<%c>%%ai%%n"),LOG_REV_AUTHOR_DATE);\r
119         cmd += log;\r
120         log.Format(_T("#<%c>%%cn%%n"),LOG_REV_COMMIT_NAME);\r
121         cmd += log;\r
122         log.Format(_T("#<%c>%%ce%%n"),LOG_REV_COMMIT_EMAIL);\r
123         cmd += log;\r
124         log.Format(_T("#<%c>%%ci%%n"),LOG_REV_COMMIT_DATE);\r
125         cmd += log;\r
126         log.Format(_T("#<%c>%%s%%n"),LOG_REV_COMMIT_SUBJECT);\r
127         cmd += log;\r
128         log.Format(_T("#<%c>%%b%%n"),LOG_REV_COMMIT_BODY);\r
129         cmd += log;\r
130         log.Format(_T("#<%c>%%H%%n"),LOG_REV_COMMIT_HASH);\r
131         cmd += log;\r
132         log.Format(_T("#<%c>%%P%%n"),LOG_REV_COMMIT_PARENT);\r
133         cmd += log;\r
134         log.Format(_T("#<%c>%%n"),LOG_REV_COMMIT_FILE);\r
135         cmd += log;\r
136         cmd += CString(_T("\""));\r
137         Run(cmd,&logOut);\r
138         return 0;\r
139 }\r
140 \r
141 #define BUFSIZE 512\r
142 void GetTempPath(CString &path)\r
143 {\r
144         TCHAR lpPathBuffer[BUFSIZE];\r
145         DWORD dwRetVal;\r
146         DWORD dwBufSize=BUFSIZE;\r
147         dwRetVal = GetTempPath(dwBufSize,     // length of the buffer\r
148                            lpPathBuffer); // buffer for path \r
149     if (dwRetVal > dwBufSize || (dwRetVal == 0))\r
150     {\r
151         path=_T("");\r
152     }\r
153         path.Format(_T("%s"),lpPathBuffer);\r
154 }\r
155 CString GetTempFile()\r
156 {\r
157         TCHAR lpPathBuffer[BUFSIZE];\r
158         DWORD dwRetVal;\r
159     DWORD dwBufSize=BUFSIZE;\r
160         TCHAR szTempName[BUFSIZE];  \r
161         UINT uRetVal;\r
162 \r
163         dwRetVal = GetTempPath(dwBufSize,     // length of the buffer\r
164                            lpPathBuffer); // buffer for path \r
165     if (dwRetVal > dwBufSize || (dwRetVal == 0))\r
166     {\r
167         return _T("");\r
168     }\r
169          // Create a temporary file. \r
170     uRetVal = GetTempFileName(lpPathBuffer, // directory for tmp files\r
171                               TEXT("Patch"),  // temp file name prefix \r
172                               0,            // create unique name \r
173                               szTempName);  // buffer for name \r
174 \r
175 \r
176     if (uRetVal == 0)\r
177     {\r
178         return _T("");\r
179     }\r
180 \r
181         return CString(szTempName);\r
182 \r
183 }\r
184 \r
185 int CGit::RunLogFile(CString cmd,CString &filename)\r
186 {\r
187         HANDLE hRead, hWrite;\r
188 \r
189         STARTUPINFO si;\r
190         PROCESS_INFORMATION pi;\r
191         si.cb=sizeof(STARTUPINFO);\r
192         GetStartupInfo(&si);\r
193 \r
194         SECURITY_ATTRIBUTES   psa={sizeof(psa),NULL,TRUE};;   \r
195         psa.bInheritHandle=TRUE;   \r
196     \r
197         HANDLE   houtfile=CreateFile(filename,GENERIC_WRITE,FILE_SHARE_READ   |   FILE_SHARE_WRITE,   \r
198                         &psa,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);   \r
199 \r
200 \r
201         si.wShowWindow=SW_HIDE;\r
202         si.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;\r
203         si.hStdOutput   =   houtfile; \r
204         \r
205         if(!CreateProcess(NULL,(LPWSTR)cmd.GetString(), NULL,NULL,TRUE,NULL,NULL,(LPWSTR)m_CurrentDir.GetString(),&si,&pi))\r
206         {\r
207                 LPVOID lpMsgBuf;\r
208                 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,\r
209                         NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\r
210                         (LPTSTR)&lpMsgBuf,\r
211                         0,NULL);\r
212                 return GIT_ERROR_CREATE_PROCESS;\r
213         }\r
214         \r
215         WaitForSingleObject(pi.hProcess,INFINITE);   \r
216         \r
217         CloseHandle(pi.hThread);\r
218         CloseHandle(pi.hProcess);\r
219         CloseHandle(houtfile);\r
220         return GIT_SUCCESS;\r
221         return 0;\r
222 }\r
223 \r
224 git_revnum_t CGit::GetHash(CString &friendname)\r
225 {\r
226         CString cmd;\r
227         CString out;\r
228         cmd.Format(_T("git.cmd rev-parse %s" ),friendname);\r
229         Run(cmd,&out);\r
230         int pos=out.ReverseFind(_T('\n'));\r
231         if(pos>0)\r
232                 return out.Left(pos);\r
233         return out;\r
234 }