From 75e1c88d068174f14ec0793d082d262684f7e509 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Mon, 28 Jan 2013 13:59:36 +0800 Subject: [PATCH] libgit2: implement clone command Show download and checkout progress, but can't cancel. Signed-off-by: Frank Li Signed-off-by: Sven Strickroth --- src/Git/Git.cpp | 9 ++++ src/Git/Git.h | 7 +++ src/Resources/TortoiseProcENG.rc | 24 ++++++++++ src/TortoiseProc/AppUtils.cpp | 58 ++++++++++++++++++++++- src/TortoiseProc/AppUtils.h | 6 +++ src/TortoiseProc/Commands/CloneCommand.cpp | 54 ++++++++++++++++++++++ src/TortoiseProc/TortoiseProc.vcxproj | 2 + src/TortoiseProc/TortoiseProc.vcxproj.filters | 6 +++ src/TortoiseProc/UserPassword.cpp | 66 +++++++++++++++++++++++++++ src/TortoiseProc/UserPassword.h | 43 +++++++++++++++++ src/TortoiseProc/resource.h | 5 ++ 11 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 src/TortoiseProc/UserPassword.cpp create mode 100644 src/TortoiseProc/UserPassword.h diff --git a/src/Git/Git.cpp b/src/Git/Git.cpp index 5331e0bc6..65771a77a 100644 --- a/src/Git/Git.cpp +++ b/src/Git/Git.cpp @@ -163,6 +163,8 @@ CGit::CGit(void) m_GitSimpleListDiff=0; m_IsUseGitDLL = !!CRegDWORD(_T("Software\\TortoiseGit\\UsingGitDLL"),1); m_IsUseLibGit2 = !!CRegDWORD(_T("Software\\TortoiseGit\\UseLibgit2"), TRUE); + m_IsUseLibGit2_mask = CRegDWORD(_T("Software\\TortoiseGit\\UseLibgit2_mask"), 0); + GetSortOptions(); this->m_bInitialized =false; CheckMsysGitDir(); @@ -2214,3 +2216,10 @@ CString CGit::GetShortName(CString ref, REF_TYPE *out_type) return shortname; } + +BOOL CGit::UsingLibGit2(int cmd) +{ + if (cmd >= 0 && cmd < 32) + return ((1 << cmd) & m_IsUseLibGit2_mask) ? FALSE : TRUE; + return FALSE; +} diff --git a/src/Git/Git.h b/src/Git/Git.h index 9abfb3940..11acf16ab 100644 --- a/src/Git/Git.h +++ b/src/Git/Git.h @@ -82,6 +82,7 @@ public: CComCriticalSection m_critGitDllSec; bool m_IsUseGitDLL; bool m_IsUseLibGit2; + DWORD m_IsUseLibGit2_mask; CEnvironment m_Environment; @@ -347,6 +348,12 @@ public: } static CString GetShortName(CString ref, REF_TYPE *type); + + enum + { + GIT_CMD_CLONE, + }; + BOOL UsingLibGit2(int cmd); }; extern void GetTempPath(CString &path); extern CString GetTempFile(); diff --git a/src/Resources/TortoiseProcENG.rc b/src/Resources/TortoiseProcENG.rc index a3aa2f1b1..9d4d0bfe0 100644 --- a/src/Resources/TortoiseProcENG.rc +++ b/src/Resources/TortoiseProcENG.rc @@ -1748,6 +1748,19 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN END +IDD_USER_PASSWD DIALOGEX 0, 0, 241, 82 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Password" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "&Username:",IDC_LABEL,7,22,51,8 + DEFPUSHBUTTON "OK",IDOK,120,61,50,14 + PUSHBUTTON "Cancel",IDCANCEL,184,61,50,14 + LTEXT "&Password:",IDC_LABEL2,7,38,57,8 + EDITTEXT IDC_USER_NAME,77,18,157,14,ES_AUTOHSCROLL + EDITTEXT IDC_USER_PASSWORD,77,36,157,14,ES_PASSWORD | ES_AUTOHSCROLL +END + ///////////////////////////////////////////////////////////////////////////// // @@ -2548,6 +2561,16 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 95 END + + IDD_USER_PASSWD, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 234 + VERTGUIDE, 42 + VERTGUIDE, 170 + TOPMARGIN, 6 + BOTTOMMARGIN, 75 + END END #endif // APSTUDIO_INVOKED @@ -2757,6 +2780,7 @@ BEGIN "Not enough memory!\nTry reducing the size of the revision graph by either\ncollapsing nodes or reducing the zoom factor." IDS_PROC_RESET "Reset" IDS_FETCH_TAGS_ONLY "All tags only" + IDS_PROG_CLONE "Clone" END STRINGTABLE diff --git a/src/TortoiseProc/AppUtils.cpp b/src/TortoiseProc/AppUtils.cpp index a43640d1d..61e12f566 100644 --- a/src/TortoiseProc/AppUtils.cpp +++ b/src/TortoiseProc/AppUtils.cpp @@ -63,6 +63,8 @@ #include "SmartHandle.h" #include "BisectStartDlg.h" #include "SysProgressDlg.h" +#include "UserPassword.h" +#include "git2.h" CAppUtils::CAppUtils(void) { @@ -3026,4 +3028,58 @@ bool CAppUtils::BisectStart(CString lastGood, CString firstBad, bool autoClose) } return false; -} \ No newline at end of file +} + +int CAppUtils::Git2GetUserPassword(git_cred **out, const char *url, unsigned int /*allowed_types*/, void * /*payload*/) +{ + CUserPassword dlg; + dlg.m_URL = CUnicodeUtils::GetUnicode(url, CP_UTF8); + CStringA username, password; + if (dlg.DoModal() == IDOK) + { + username = CUnicodeUtils::GetMulti(dlg.m_UserName, CP_UTF8); + password = CUnicodeUtils::GetMulti(dlg.m_Password, CP_UTF8); + return git_cred_userpass_plaintext_new(out, username, password); + } + return -1; +} + +void CAppUtils::Git2FetchProgress(const git_transfer_progress *stats, void *payload) +{ + CSysProgressDlg *pDlg = (CSysProgressDlg*)payload; + if (pDlg == NULL) + return; + static unsigned int start = 0; + if (GetCurrentTime() - start > 100) + start = GetCurrentTime(); + else + return; + + pDlg->FormatPathLine(1, _T("net %3d%% (%4d kb, %5d/%5d) / idx %3d%% (%5d/%5d)"), + (100 * stats->received_objects) / stats->total_objects, + stats->received_bytes / 1024, + stats->received_objects, + stats->total_objects, + (100 * stats->indexed_objects) / stats->total_objects, + stats->indexed_objects, + stats->total_objects); + pDlg->SetProgress(stats->received_objects, stats->total_objects); + +} +void CAppUtils::Git2CheckoutProgress(const char *path, size_t cur, size_t tot, void *payload) +{ + CSysProgressDlg *pDlg = (CSysProgressDlg*)payload; + CString str; + if (pDlg == NULL) + return; + + static unsigned int start = 0; + if (GetCurrentTime() - start > 100) + start = GetCurrentTime(); + else + return; + + pDlg->FormatPathLine(0, _T("Check Out")); + pDlg->FormatPathLine(1, _T("%s"), CUnicodeUtils::GetUnicode(path, CP_ACP)); + pDlg->SetProgress(cur, tot); +} diff --git a/src/TortoiseProc/AppUtils.h b/src/TortoiseProc/AppUtils.h index 029b57458..b2ff28b15 100644 --- a/src/TortoiseProc/AppUtils.h +++ b/src/TortoiseProc/AppUtils.h @@ -23,6 +23,8 @@ #include "CommonAppUtils.h" class CTGitPath; +struct git_cred; +struct git_transfer_progress; enum GIT_POST_CMD { @@ -211,6 +213,10 @@ public: static bool BisectStart(CString lastGood, CString firstBad, bool autoClose = false); + static int Git2GetUserPassword(git_cred **out, const char *url, unsigned int allowed_types, void *payload); + static void Git2FetchProgress(const git_transfer_progress *stats, void *payload); + static void Git2CheckoutProgress(const char *path, size_t cur, size_t tot, void *payload); + private: static CString PickDiffTool(const CTGitPath& file1, const CTGitPath& file2); static bool GetMimeType(const CTGitPath& file, CString& mimetype); diff --git a/src/TortoiseProc/Commands/CloneCommand.cpp b/src/TortoiseProc/Commands/CloneCommand.cpp index 6961b5104..b51400bbb 100644 --- a/src/TortoiseProc/Commands/CloneCommand.cpp +++ b/src/TortoiseProc/Commands/CloneCommand.cpp @@ -27,6 +27,55 @@ #include "CloneDlg.h" #include "ProgressDlg.h" #include "AppUtils.h" +#include "git2.h" +#include "UnicodeUtils.h" +#include "SysProgressDlg.h" + +static bool clone_libgit2(const CString URL, const CString PATH, bool bBare) +{ + CStringA url = CUnicodeUtils::GetMulti(URL, CP_UTF8); + CStringA path = CUnicodeUtils::GetMulti(PATH, CP_UTF8); + + CSysProgressDlg progress; + + git_repository *cloned_repo = NULL; + git_remote *origin = NULL; + + int error = 0; + error = git_remote_new(&origin, NULL, "origin", url, GIT_REMOTE_DEFAULT_FETCH); + git_remote_set_cred_acquire_cb(origin, CAppUtils::Git2GetUserPassword, NULL); + + git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT; + git_checkout_opts checkout_opts = GIT_CHECKOUT_OPTS_INIT; + + checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; + checkout_opts.progress_cb = CAppUtils::Git2CheckoutProgress;; + checkout_opts.progress_payload = &progress; + + clone_opts.checkout_opts = &checkout_opts; + clone_opts.fetch_progress_cb = CAppUtils::Git2FetchProgress; + clone_opts.fetch_progress_payload = &progress; + + progress.SetTitle(CString(MAKEINTRESOURCE(IDS_PROG_CLONE))); + progress.SetAnimation(IDR_DOWNLOAD); + progress.SetTime(true); + progress.ShowModeless((CWnd*)NULL); + + error = git_clone(&cloned_repo, origin, path, &clone_opts); + git_remote_free(origin); + if (error) { + const git_error *err = giterr_last(); + if (err) + printf("ERROR %d: %s\n", err->klass, err->message); + else + printf("ERROR %d: no detailed info\n", error); + return false; + } + else if (cloned_repo) + git_repository_free(cloned_repo); + + return true; +} bool CloneCommand::Execute() { @@ -141,6 +190,11 @@ bool CloneCommand::Execute() cmd+=dlg.m_strUserName; } } + else + { + if (g_Git.UsingLibGit2(CGit::GIT_CMD_CLONE)) + return clone_libgit2(url, dir, dlg.m_bBare); + } CProgressDlg progress; progress.m_GitCmd=cmd; INT_PTR ret = progress.DoModal(); diff --git a/src/TortoiseProc/TortoiseProc.vcxproj b/src/TortoiseProc/TortoiseProc.vcxproj index c8873ea3e..2eda01b14 100644 --- a/src/TortoiseProc/TortoiseProc.vcxproj +++ b/src/TortoiseProc/TortoiseProc.vcxproj @@ -302,6 +302,7 @@ Create + @@ -458,6 +459,7 @@ + diff --git a/src/TortoiseProc/TortoiseProc.vcxproj.filters b/src/TortoiseProc/TortoiseProc.vcxproj.filters index 24a7677b7..b86e00b01 100644 --- a/src/TortoiseProc/TortoiseProc.vcxproj.filters +++ b/src/TortoiseProc/TortoiseProc.vcxproj.filters @@ -632,6 +632,9 @@ Utils\UI + + Utils + @@ -1096,6 +1099,9 @@ Utils\UI + + Utils + diff --git a/src/TortoiseProc/UserPassword.cpp b/src/TortoiseProc/UserPassword.cpp new file mode 100644 index 000000000..d36498a88 --- /dev/null +++ b/src/TortoiseProc/UserPassword.cpp @@ -0,0 +1,66 @@ +// TortoiseGit - a Windows shell extension for easy version control + +// Copyright (C) 2013 - TortoiseGit + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// UserPassword.cpp : implementation file +// +#include "stdafx.h" +#include "resource.h" +#include "UserPassword.h" +#include "afxdialogex.h" + +// CUserPassword dialog + +IMPLEMENT_DYNAMIC(CUserPassword, CDialog) + +CUserPassword::CUserPassword(CWnd* pParent /*=NULL*/) + : CDialog(CUserPassword::IDD, pParent) + , m_UserName(_T("")) + , m_Password(_T("")) +{ + +} + +CUserPassword::~CUserPassword() +{ +} + +void CUserPassword::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Text(pDX, IDC_USER_NAME, m_UserName); + DDX_Text(pDX, IDC_USER_PASSWORD, m_Password); +} + +BEGIN_MESSAGE_MAP(CUserPassword, CDialog) +END_MESSAGE_MAP() + +// CUserPassword message handlers + +BOOL CUserPassword::OnInitDialog() +{ + CDialog::OnInitDialog(); + if (!m_URL.IsEmpty()) + { + CString title; + this->GetWindowText(title); + title += _T(" - "); + title += m_URL; + this->SetWindowText(title); + } + return TRUE; // return TRUE unless you set the focus to a control +} diff --git a/src/TortoiseProc/UserPassword.h b/src/TortoiseProc/UserPassword.h new file mode 100644 index 000000000..429dbdad9 --- /dev/null +++ b/src/TortoiseProc/UserPassword.h @@ -0,0 +1,43 @@ +// TortoiseGit - a Windows shell extension for easy version control + +// Copyright (C) 2013 - TortoiseGit + +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software Foundation, +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +#pragma once + +// CUserPassword dialog + +class CUserPassword : public CDialog +{ + DECLARE_DYNAMIC(CUserPassword) + +public: + CUserPassword(CWnd* pParent = NULL); // standard constructor + virtual ~CUserPassword(); + +// Dialog Data + enum { IDD = IDD_USER_PASSWD }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + DECLARE_MESSAGE_MAP() +public: + CString m_UserName; + CString m_Password; + CString m_URL; + virtual BOOL OnInitDialog(); +}; diff --git a/src/TortoiseProc/resource.h b/src/TortoiseProc/resource.h index 28d7d2f59..73be69eef 100644 --- a/src/TortoiseProc/resource.h +++ b/src/TortoiseProc/resource.h @@ -1524,6 +1524,7 @@ #define ID_REVGRAPH_ZOOMCOMBO 4583 #define IDD_REVGRAPHFILTER 4584 #define IDC_FROMREV 4585 +#define IDD_USER_PASSWD 4585 #define IDC_FROMSPIN 4586 #define IDC_TOREV 4587 #define IDC_TOSPIN 4588 @@ -1532,6 +1533,7 @@ #define IDC_COMBOBOXEX_LOCAL_BRANCH 5000 #define IDC_COMBOBOXEX_REMOTE_BRANCH 5001 #define IDC_COMBOBOXEX_BAD 5001 +#define IDC_LABEL2 5002 #define IDS_FILEDIFF_FILE 5100 #define IDS_FILEDIFF_COMMENT 5101 #define IDS_FILEDIFF_ACTION 5101 @@ -1634,6 +1636,9 @@ #define IDS_REVGRAPH_ERR_NOMEMORY 9688 #define IDS_PROC_RESET 9689 #define IDS_FETCH_TAGS_ONLY 9690 +#define IDS_PROG_CLONE 9691 +#define IDC_USER_NAME 9692 +#define IDC_USER_PASSWORD 9693 #define ID_VIEW_ZOOMIN 32772 #define ID_VIEW_ZOOMOUT 32773 #define ID_VIEW_ZOOM100 32803 -- 2.11.4.GIT