libgit2: implement clone command
[TortoiseGit.git] / src / TortoiseProc / Commands / CloneCommand.cpp
blobb51400bbbbf505e3ad3714f1cd3bb69f0513be40
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2008-2012 - TortoiseGit
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "stdafx.h"
20 #include "CloneCommand.h"
22 //#include "SVNProgressDlg.h"
23 #include "StringUtils.h"
24 #include "Hooks.h"
25 #include "MessageBox.h"
27 #include "CloneDlg.h"
28 #include "ProgressDlg.h"
29 #include "AppUtils.h"
30 #include "git2.h"
31 #include "UnicodeUtils.h"
32 #include "SysProgressDlg.h"
34 static bool clone_libgit2(const CString URL, const CString PATH, bool bBare)
36 CStringA url = CUnicodeUtils::GetMulti(URL, CP_UTF8);
37 CStringA path = CUnicodeUtils::GetMulti(PATH, CP_UTF8);
39 CSysProgressDlg progress;
41 git_repository *cloned_repo = NULL;
42 git_remote *origin = NULL;
44 int error = 0;
45 error = git_remote_new(&origin, NULL, "origin", url, GIT_REMOTE_DEFAULT_FETCH);
46 git_remote_set_cred_acquire_cb(origin, CAppUtils::Git2GetUserPassword, NULL);
48 git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
49 git_checkout_opts checkout_opts = GIT_CHECKOUT_OPTS_INIT;
51 checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
52 checkout_opts.progress_cb = CAppUtils::Git2CheckoutProgress;;
53 checkout_opts.progress_payload = &progress;
55 clone_opts.checkout_opts = &checkout_opts;
56 clone_opts.fetch_progress_cb = CAppUtils::Git2FetchProgress;
57 clone_opts.fetch_progress_payload = &progress;
59 progress.SetTitle(CString(MAKEINTRESOURCE(IDS_PROG_CLONE)));
60 progress.SetAnimation(IDR_DOWNLOAD);
61 progress.SetTime(true);
62 progress.ShowModeless((CWnd*)NULL);
64 error = git_clone(&cloned_repo, origin, path, &clone_opts);
65 git_remote_free(origin);
66 if (error) {
67 const git_error *err = giterr_last();
68 if (err)
69 printf("ERROR %d: %s\n", err->klass, err->message);
70 else
71 printf("ERROR %d: no detailed info\n", error);
72 return false;
74 else if (cloned_repo)
75 git_repository_free(cloned_repo);
77 return true;
80 bool CloneCommand::Execute()
82 CCloneDlg dlg;
83 dlg.m_Directory=this->orgCmdLinePath.GetWinPathString();
85 if (parser.HasKey(_T("url")))
86 dlg.m_URL = parser.GetVal(_T("url"));
88 if(dlg.DoModal()==IDOK)
90 CString recursiveStr;
91 if(dlg.m_bRecursive)
92 recursiveStr = _T("--recursive");
93 else
94 recursiveStr = _T("");
96 CString bareStr;
97 if(dlg.m_bBare)
98 bareStr = _T("--bare");
99 else
100 bareStr = _T("");
102 CString nocheckoutStr;
103 if (dlg.m_bNoCheckout)
104 nocheckoutStr = _T("--no-checkout");
106 CString branchStr;
107 if (dlg.m_bBranch)
108 branchStr = _T("--branch ") + dlg.m_strBranch;
110 if(dlg.m_bAutoloadPuttyKeyFile)
112 CAppUtils::LaunchPAgent(&dlg.m_strPuttyKeyFile);
115 CAppUtils::RemoveTrailSlash(dlg.m_Directory);
116 if (!dlg.m_bSVN)
117 CAppUtils::RemoveTrailSlash(dlg.m_URL);
119 CString dir=dlg.m_Directory;
120 CString url=dlg.m_URL;
122 // is this a windows format UNC path, ie starts with \\?
123 if (url.Find(_T("\\\\")) == 0)
125 // yes, change all \ to /
126 // this should not be necessary but msysgit does not support the use \ here yet
127 int atSign = url.Find(_T('@'));
128 if (atSign > 0)
130 CString path = url.Mid(atSign);
131 path.Replace(_T('\\'), _T('/'));
132 url = url.Mid(0, atSign) + path;
134 else
135 url.Replace( _T('\\'), _T('/'));
138 CString depth;
139 if (dlg.m_bDepth)
141 depth.Format(_T(" --depth %d"),dlg.m_nDepth);
144 g_Git.m_CurrentDir = this->orgCmdLinePath.GetWinPathString();
146 CString cmd;
147 CString progressarg;
149 int ver = CAppUtils::GetMsysgitVersion();
151 if(ver >= 0x01070002) //above 1.7.0.2
152 progressarg = _T("--progress");
154 cmd.Format(_T("git.exe clone %s %s %s %s %s -v %s \"%s\" \"%s\""),
155 nocheckoutStr,
156 recursiveStr,
157 bareStr,
158 branchStr,
159 progressarg,
160 depth,
161 url,
162 dir);
164 // Handle Git SVN-clone
165 if(dlg.m_bSVN)
167 //g_Git.m_CurrentDir=dlg.m_Directory;
168 cmd.Format(_T("git.exe svn clone \"%s\" \"%s\""),
169 url,dlg.m_Directory);
171 if(dlg.m_bSVNTrunk)
172 cmd+=_T(" -T ")+dlg.m_strSVNTrunk;
174 if(dlg.m_bSVNBranch)
175 cmd+=_T(" -b ")+dlg.m_strSVNBranchs;
177 if(dlg.m_bSVNTags)
178 cmd+=_T(" -t ")+dlg.m_strSVNTags;
180 if(dlg.m_bSVNFrom)
182 CString str;
183 str.Format(_T("%d:HEAD"),dlg.m_nSVNFrom);
184 cmd+=_T(" -r ")+str;
187 if(dlg.m_bSVNUserName)
189 cmd+= _T(" --username ");
190 cmd+=dlg.m_strUserName;
193 else
195 if (g_Git.UsingLibGit2(CGit::GIT_CMD_CLONE))
196 return clone_libgit2(url, dir, dlg.m_bBare);
198 CProgressDlg progress;
199 progress.m_GitCmd=cmd;
200 INT_PTR ret = progress.DoModal();
202 if( progress.m_GitStatus == 0)
204 if(dlg.m_bAutoloadPuttyKeyFile)
206 g_Git.m_CurrentDir = dlg.m_Directory;
207 SetCurrentDirectory(g_Git.m_CurrentDir);
209 if(g_Git.SetConfigValue(_T("remote.origin.puttykeyfile"), dlg.m_strPuttyKeyFile, CONFIG_LOCAL, CP_UTF8, &dlg.m_Directory))
211 CMessageBox::Show(NULL,_T("Fail set config remote.origin.puttykeyfile"),_T("TortoiseGit"),MB_OK|MB_ICONERROR);
212 return FALSE;
216 if(ret == IDOK)
217 return TRUE;
220 return FALSE;