OSDN Git Service

Add Revert to Version feature.
[tortoisegit/TortoiseGitJp.git] / src / Git / GitStatusListCtrl.cpp
index 9fb6a37..fa4302a 100644 (file)
@@ -52,6 +52,7 @@
 //#include "EditPropertiesDlg.h"\r
 //#include "CreateChangelistDlg.h"\r
 #include "XPTheme.h"\r
+#include "CommonResource.h"\r
 \r
 const UINT CGitStatusListCtrl::SVNSLNM_ITEMCOUNTCHANGED\r
                                        = ::RegisterWindowMessage(_T("GITSLNM_ITEMCOUNTCHANGED"));\r
@@ -62,43 +63,7 @@ const UINT CGitStatusListCtrl::SVNSLNM_ADDFILE
 const UINT CGitStatusListCtrl::SVNSLNM_CHECKCHANGED\r
                                        = ::RegisterWindowMessage(_T("GITSLNM_CHECKCHANGED"));\r
 \r
-#define IDSVNLC_REVERT                  1\r
-#define IDSVNLC_COMPARE                         2\r
-#define IDSVNLC_OPEN                    3\r
-#define IDSVNLC_DELETE                  4\r
-#define IDSVNLC_IGNORE                  5\r
-#define IDSVNLC_GNUDIFF1                6\r
-#define IDSVNLC_UPDATE           7\r
-#define IDSVNLC_LOG              8\r
-#define IDSVNLC_EDITCONFLICT     9\r
-#define IDSVNLC_IGNOREMASK         10\r
-#define IDSVNLC_ADD                        11\r
-#define IDSVNLC_RESOLVECONFLICT 12\r
-#define IDSVNLC_LOCK                   13\r
-#define IDSVNLC_LOCKFORCE              14\r
-#define IDSVNLC_UNLOCK                 15\r
-#define IDSVNLC_UNLOCKFORCE            16\r
-#define IDSVNLC_OPENWITH               17\r
-#define IDSVNLC_EXPLORE                        18\r
-#define IDSVNLC_RESOLVETHEIRS  19\r
-#define IDSVNLC_RESOLVEMINE            20\r
-#define IDSVNLC_REMOVE                 21\r
-#define IDSVNLC_COMMIT                 22\r
-#define IDSVNLC_PROPERTIES             23\r
-#define IDSVNLC_COPY                   24\r
-#define IDSVNLC_COPYEXT                        25\r
-#define IDSVNLC_REPAIRMOVE             26\r
-#define IDSVNLC_REMOVEFROMCS   27\r
-#define IDSVNLC_CREATECS               28\r
-#define IDSVNLC_CREATEIGNORECS 29\r
-#define IDSVNLC_CHECKGROUP             30\r
-#define IDSVNLC_UNCHECKGROUP   31\r
-#define IDSVNLC_ADD_RECURSIVE   32\r
-#define IDSVNLC_COMPAREWC              33\r
-#define IDSVNLC_BLAME                  34\r
-// the IDSVNLC_MOVETOCS *must* be the last index, because it contains a dynamic submenu where \r
-// the submenu items get command ID's sequent to this number\r
-#define IDSVNLC_MOVETOCS               35\r
+\r
 \r
 \r
 BEGIN_MESSAGE_MAP(CGitStatusListCtrl, CListCtrl)\r
@@ -163,8 +128,8 @@ CGitStatusListCtrl::CGitStatusListCtrl() : CListCtrl()
 \r
 CGitStatusListCtrl::~CGitStatusListCtrl()\r
 {\r
-       if (m_pDropTarget)\r
-               delete m_pDropTarget;\r
+//     if (m_pDropTarget)\r
+//             delete m_pDropTarget;\r
        ClearStatusArray();\r
 }\r
 \r
@@ -234,7 +199,7 @@ int CGitStatusListCtrl::GetIndex(const CTGitPath& path)
 }\r
 #endif \r
 \r
-void CGitStatusListCtrl::Init(DWORD dwColumns, const CString& sColumnInfoContainer, DWORD dwContextMenus /* = GitSLC_POPALL */, bool bHasCheckboxes /* = true */)\r
+void CGitStatusListCtrl::Init(DWORD dwColumns, const CString& sColumnInfoContainer, unsigned __int64 dwContextMenus /* = GitSLC_POPALL */, bool bHasCheckboxes /* = true */)\r
 {\r
        Locker lock(m_critSec);\r
 \r
@@ -286,7 +251,7 @@ bool CGitStatusListCtrl::SetBackgroundImage(UINT nID)
        return CAppUtils::SetListCtrlBackgroundImage(GetSafeHwnd(), nID);\r
 }\r
 \r
-BOOL CGitStatusListCtrl::GetStatus ( const CTGitPathList& pathList\r
+BOOL CGitStatusListCtrl::GetStatus ( const CTGitPathList* pathList\r
                                    , bool bUpdate /* = FALSE */\r
                                    , bool bShowIgnores /* = false */\r
                                                                   , bool bShowUnRev\r
@@ -298,7 +263,8 @@ BOOL CGitStatusListCtrl::GetStatus ( const CTGitPathList& pathList
                mask|= CGitStatusListCtrl::FILELIST_IGNORE;\r
        if(bShowUnRev)\r
                mask|= CGitStatusListCtrl::FILELIST_UNVER;\r
-       this->UpdateFileList(mask,bUpdate,(CTGitPathList*)&pathList);\r
+       this->UpdateFileList(mask,bUpdate,(CTGitPathList*)pathList);\r
+\r
 \r
 #if 0\r
        \r
@@ -464,6 +430,7 @@ BOOL CGitStatusListCtrl::GetStatus ( const CTGitPathList& pathList
        SetCursorPos(pt.x, pt.y);\r
        return bRet;\r
 #endif \r
+       BuildStatistics();\r
        return TRUE;\r
 }\r
 \r
@@ -1054,7 +1021,7 @@ void CGitStatusListCtrl::Show(DWORD dwShow, DWORD dwCheck /*=0*/, bool bShowFold
                pApp->DoWaitCursor(1);\r
 \r
        Locker lock(m_critSec);\r
-       WORD langID = (WORD)CRegStdWORD(_T("Software\\TortoiseSVN\\LanguageID"), GetUserDefaultLangID());\r
+       WORD langID = (WORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), GetUserDefaultLangID());\r
        \r
        //SetItemCount(listIndex);\r
        SetRedraw(FALSE);\r
@@ -1080,10 +1047,18 @@ void CGitStatusListCtrl::Show(DWORD dwShow, DWORD dwCheck /*=0*/, bool bShowFold
                        m_arStatusArray.push_back((CTGitPath*)&m_IgnoreFileList[i]);\r
                }\r
        }\r
+       int index =0;\r
        for(int i=0;i<this->m_arStatusArray.size();i++)\r
        {\r
+               //set default checkbox status\r
+               if(((CTGitPath*)m_arStatusArray[i])->m_Action & dwCheck)\r
+                       ((CTGitPath*)m_arStatusArray[i])->m_Checked=true;\r
+\r
                if(((CTGitPath*)m_arStatusArray[i])->m_Action & dwShow)\r
-                               AddEntry((CTGitPath*)m_arStatusArray[i],langID,i);\r
+               {\r
+                       AddEntry((CTGitPath*)m_arStatusArray[i],langID,index);\r
+                       index++;\r
+               }\r
        }\r
        \r
        int maxcol = ((CHeaderCtrl*)(GetDlgItem(0)))->GetItemCount()-1;\r
@@ -1281,7 +1256,7 @@ void CGitStatusListCtrl::Show(DWORD dwShow, const CTGitPathList& checkedList, bo
 #if 0\r
 \r
        Locker lock(m_critSec);\r
-       WORD langID = (WORD)CRegStdWORD(_T("Software\\TortoiseSVN\\LanguageID"), GetUserDefaultLangID());\r
+       WORD langID = (WORD)CRegStdWORD(_T("Software\\TortoiseGit\\LanguageID"), GetUserDefaultLangID());\r
 \r
        CWinApp * pApp = AfxGetApp();\r
        if (pApp)\r
@@ -1415,7 +1390,7 @@ int CGitStatusListCtrl::GetColumnIndex(int mask)
        int i=0;\r
        for(i=0;i<32;i++)\r
                if(mask&0x1)\r
-                       return i-1;\r
+                       return i;\r
                else\r
                        mask=mask>>1;\r
        return -1;\r
@@ -1440,6 +1415,11 @@ void CGitStatusListCtrl::AddEntry(CTGitPath * GitPath, WORD langID, int listInde
                icon_idx = SYS_IMAGE_LIST().GetPathIconIndex(*GitPath);\r
        }\r
        // relative path\r
+       CString rename;\r
+       rename.Format(_T("(from %s)"),GitPath->GetGitOldPathString());\r
+       if(GitPath->m_Action & (CTGitPath::LOGACTIONS_REPLACED|CTGitPath::LOGACTIONS_COPY))\r
+               entryname+=rename;\r
+       \r
        InsertItem(index, entryname, icon_idx);\r
 \r
        this->SetItemData(index, (DWORD_PTR)GitPath);\r
@@ -1722,8 +1702,8 @@ void CGitStatusListCtrl::AddEntry(FileEntry * entry, WORD langID, int listIndex)
 #endif\r
 bool CGitStatusListCtrl::SetItemGroup(int item, int groupindex)\r
 {\r
-       if ((m_dwContextMenus & SVNSLC_POPCHANGELISTS) == NULL)\r
-               return false;\r
+//     if ((m_dwContextMenus & SVNSLC_POPCHANGELISTS) == NULL)\r
+//             return false;\r
        if (groupindex < 0)\r
                return false;\r
        LVITEM i = {0};\r
@@ -1780,7 +1760,9 @@ void CGitStatusListCtrl::OnHdnItemclick(NMHDR *pNMHDR, LRESULT *pResult)
        for (int i=0; i<GetItemCount(); ++i)\r
        {\r
                CTGitPath * entry = (CTGitPath*)GetItemData(i);\r
-               SetCheck(i, entry->m_Checked);\r
+               ASSERT(entry);\r
+               if(entry)\r
+                       SetCheck(i, entry->m_Checked);\r
        }\r
 \r
        m_bBlock = FALSE;\r
@@ -2029,19 +2011,8 @@ bool CGitStatusListCtrl::IsEntryVersioned(const FileEntry* pEntry1)
 #endif\r
 bool CGitStatusListCtrl::BuildStatistics()\r
 {\r
-#if 0\r
+\r
        bool bRefetchStatus = false;\r
-       FileEntryVector::iterator itFirstUnversionedEntry;\r
-       itFirstUnversionedEntry = std::partition(m_arStatusArray.begin(), m_arStatusArray.end(), IsEntryVersioned);\r
-       if (m_bUnversionedLast)\r
-       {\r
-               // We partition the list of items so that it's arrange with all the versioned items first\r
-               // then all the unversioned items afterwards.\r
-               // Then we sort the versioned part of this, so that we can do quick look-ups in it\r
-               std::sort(m_arStatusArray.begin(), itFirstUnversionedEntry, EntryPathCompareNoCase);\r
-               // Also sort the unversioned section, to make the list look nice...\r
-               std::sort(itFirstUnversionedEntry, m_arStatusArray.end(), EntryPathCompareNoCase);\r
-       }\r
 \r
        // now gather some statistics\r
        m_nUnversioned = 0;\r
@@ -2052,87 +2023,33 @@ bool CGitStatusListCtrl::BuildStatistics()
        m_nConflicted = 0;\r
        m_nTotal = 0;\r
        m_nSelected = 0;\r
+       \r
        for (int i=0; i < (int)m_arStatusArray.size(); ++i)\r
        {\r
-               const FileEntry * entry = m_arStatusArray[i];\r
-               if (entry)\r
-               {\r
-                       switch (entry->status)\r
-                       {\r
-                       case git_wc_status_normal:\r
-                               m_nNormal++;\r
-                               break;\r
-                       case git_wc_status_added:\r
-                               m_nAdded++;\r
-                               break;\r
-                       case git_wc_status_missing:\r
-                       case git_wc_status_deleted:\r
-                               m_nDeleted++;\r
-                               break;\r
-                       case git_wc_status_replaced:\r
-                       case git_wc_status_modified:\r
-                       case git_wc_status_merged:\r
-                               m_nModified++;\r
-                               break;\r
-                       case git_wc_status_conflicted:\r
-                       case git_wc_status_obstructed:\r
-                               m_nConflicted++;\r
-                               break;\r
-                       case git_wc_status_ignored:\r
-                               m_nUnversioned++;\r
-                               break;\r
-                       default:\r
-#if 0\r
-                               {\r
-                                       if (GitStatus::IsImportant(entry->remotestatus))\r
-                                               break;\r
-                                       m_nUnversioned++;\r
-                                       // If an entry is in an unversioned folder, we don't have to do an expensive array search\r
-                                       // to find out if it got case-renamed: an unversioned folder can't have versioned files\r
-                                       // But nested folders are also considered to be in unversioned folders, we have to do the\r
-                                       // check in that case too, otherwise we would miss case-renamed folders - they show up\r
-                                       // as nested folders.\r
-                                       if (((!entry->inunversionedfolder)||(entry->isNested))&&(m_bUnversionedLast))\r
-                                       {\r
-                                               // check if the unversioned item is just\r
-                                               // a file differing in case but still versioned\r
-                                               FileEntryVector::iterator itMatchingItem;\r
-                                               if(std::binary_search(m_arStatusArray.begin(), itFirstUnversionedEntry, entry, EntryPathCompareNoCase))\r
-                                               {\r
-                                                       // We've confirmed that there *is* a matching file\r
-                                                       // Find its exact location\r
-                                                       FileEntryVector::iterator itMatchingItem;\r
-                                                       itMatchingItem = std::lower_bound(m_arStatusArray.begin(), itFirstUnversionedEntry, entry, EntryPathCompareNoCase);\r
+               int status=((CTGitPath*)m_arStatusArray[i])->m_Action;\r
+\r
+               if(status&(CTGitPath::LOGACTIONS_ADDED|CTGitPath::LOGACTIONS_COPY))\r
+                       m_nAdded++;\r
+               \r
+               if(status&CTGitPath::LOGACTIONS_DELETED)\r
+                       m_nDeleted++;\r
+               \r
+               if(status&(CTGitPath::LOGACTIONS_REPLACED|CTGitPath::LOGACTIONS_MODIFIED))\r
+                       m_nModified++;\r
+               \r
+               if(status&CTGitPath::LOGACTIONS_UNMERGED)\r
+                       m_nConflicted++;\r
+               \r
+               if(status&(CTGitPath::LOGACTIONS_IGNORE|CTGitPath::LOGACTIONS_UNVER))\r
+                       m_nUnversioned++;\r
+       \r
+       \r
 \r
-                                                       // adjust the case of the filename\r
-                                                       if (MoveFileEx(entry->path.GetWinPath(), (*itMatchingItem)->path.GetWinPath(), MOVEFILE_REPLACE_EXISTING))\r
-                                                       {\r
-                                                               // We successfully adjusted the case in the filename. But there is now a file with status 'missing'\r
-                                                               // in the array, because that's the status of the file before we adjusted the case.\r
-                                                               // We have to refetch the status of that file.\r
-                                                               // Since fetching the status of single files/directories is very expensive and there can be\r
-                                                               // multiple case-renames here, we just set a flag and refetch the status at the end from scratch.\r
-                                                               bRefetchStatus = true;\r
-                                                               DeleteItem(i);\r
-                                                               m_arStatusArray.erase(m_arStatusArray.begin()+i);\r
-                                                               delete entry;\r
-                                                               i--;\r
-                                                               m_nUnversioned--;\r
-                                                               // now that we removed an unversioned item from the array, find the first unversioned item in the 'new'\r
-                                                               // list again.\r
-                                                               itFirstUnversionedEntry = std::partition(m_arStatusArray.begin(), m_arStatusArray.end(), IsEntryVersioned);\r
-                                                       }\r
-                                                       break;\r
-                                               }\r
-                                       }\r
-                               }\r
-#endif\r
-                               break;\r
-                       } // switch (entry->status)\r
-               } // if (entry)\r
+//                     } // switch (entry->status)\r
+//             } // if (entry)\r
        } // for (int i=0; i < (int)m_arStatusArray.size(); ++i)\r
        return !bRefetchStatus;\r
-#endif \r
+\r
        return FALSE;\r
 }\r
 \r
@@ -2279,14 +2196,14 @@ void CGitStatusListCtrl::OnContextMenuGroup(CWnd * /*pWnd*/, CPoint point)
                                                lv.mask = LVIF_GROUPID;\r
                                                lv.iItem = i;\r
                                                GetItem(&lv);\r
-#if 0\r
+\r
                                                if (lv.iGroupId == group)\r
                                                {\r
-                                                       FileEntry * entry = GetListEntry(i);\r
+                                                       CTGitPath * entry = (CTGitPath*)GetItemData(i);\r
                                                        if (entry)\r
                                                        {\r
-                                                               bool bOldCheck = !!GetCheck(i);\r
-                                                               //SetEntryCheck(entry, i, bCheck);\r
+                                                               bool bOldCheck = entry->m_Checked;\r
+                                                               SetEntryCheck(entry, i, bCheck);\r
                                                                if (bCheck != bOldCheck)\r
                                                                {\r
                                                                        if (bCheck)\r
@@ -2296,7 +2213,7 @@ void CGitStatusListCtrl::OnContextMenuGroup(CWnd * /*pWnd*/, CPoint point)
                                                                }\r
                                                        }\r
                                                }\r
-#endif\r
+\r
                                        }\r
                                        GetStatisticsString();\r
                                        NotifyCheck();\r
@@ -2358,6 +2275,26 @@ void CGitStatusListCtrl::OnContextMenuList(CWnd * pWnd, CPoint point)
                if (popup.CreatePopupMenu())\r
                {\r
                        //Add Menu for verion controled file\r
+               \r
+                       if (wcStatus & CTGitPath::LOGACTIONS_UNMERGED)\r
+                       {\r
+                               if ((m_dwContextMenus & SVNSLC_POPCONFLICT)/*&&(entry->textstatus == git_wc_status_conflicted)*/)\r
+                               {\r
+                                       popup.AppendMenuIcon(IDSVNLC_EDITCONFLICT, IDS_MENUCONFLICT, IDI_CONFLICT);\r
+                               }\r
+                               if (m_dwContextMenus & SVNSLC_POPRESOLVE)\r
+                               {\r
+                                       popup.AppendMenuIcon(IDSVNLC_RESOLVECONFLICT, IDS_STATUSLIST_CONTEXT_RESOLVED, IDI_RESOLVE);\r
+                               }\r
+                               if ((m_dwContextMenus & SVNSLC_POPRESOLVE)/*&&(entry->textstatus == git_wc_status_conflicted)*/)\r
+                               {\r
+                                       //popup.AppendMenuIcon(IDSVNLC_RESOLVETHEIRS, IDS_SVNPROGRESS_MENUUSETHEIRS, IDI_RESOLVE);\r
+                                       //popup.AppendMenuIcon(IDSVNLC_RESOLVEMINE, IDS_SVNPROGRESS_MENUUSEMINE, IDI_RESOLVE);\r
+                               }\r
+                               if ((m_dwContextMenus & SVNSLC_POPCONFLICT)||(m_dwContextMenus & SVNSLC_POPRESOLVE))\r
+                                       popup.AppendMenu(MF_SEPARATOR);\r
+                       }\r
+\r
                        if (!(wcStatus &CTGitPath::LOGACTIONS_UNVER))\r
                        {\r
                                if (m_dwContextMenus & SVNSLC_POPCOMPAREWITHBASE)\r
@@ -2410,6 +2347,7 @@ void CGitStatusListCtrl::OnContextMenuList(CWnd * pWnd, CPoint point)
                                //}\r
                        }\r
                        \r
+       \r
                        ///Select Multi item\r
                        //if (GetSelectedCount() > 0)\r
                        //{\r
@@ -2457,30 +2395,54 @@ void CGitStatusListCtrl::OnContextMenuList(CWnd * pWnd, CPoint point)
                        //              }\r
                        //      }\r
                        //}\r
-                       if ((GetSelectedCount() == 1)&&(!wcStatus & CTGitPath::LOGACTIONS_UNVER)\r
-                               &&(!wcStatus & CTGitPath::LOGACTIONS_IGNORE))\r
+\r
+                       if ( (GetSelectedCount() >0 ) && (!(wcStatus & CTGitPath::LOGACTIONS_UNVER)))\r
+                       {\r
+                               if (m_dwContextMenus & SVNSLC_POPREVERT)\r
+                               {\r
+                                       popup.AppendMenuIcon(IDSVNLC_REVERT, IDS_MENUREVERT, IDI_REVERT);\r
+                               }\r
+\r
+                               if ((m_dwContextMenus & GetContextMenuBit(IDSVNLC_REVERTTOREV)) && ( !this->m_CurrentVersion.IsEmpty() )\r
+                                       && this->m_CurrentVersion != GIT_REV_ZERO)\r
+                               {\r
+                                       popup.AppendMenuIcon(IDSVNLC_REVERTTOREV, IDS_LOG_POPUP_REVERTTOREV, IDI_REVERT);\r
+                               }\r
+                       }\r
+\r
+                       if ((GetSelectedCount() == 1)&&(!(wcStatus & CTGitPath::LOGACTIONS_UNVER))\r
+                               &&(!(wcStatus & CTGitPath::LOGACTIONS_IGNORE)))\r
                        {\r
                                if (m_dwContextMenus & SVNSLC_POPSHOWLOG)\r
                                {\r
                                        popup.AppendMenuIcon(IDSVNLC_LOG, IDS_REPOBROWSE_SHOWLOG, IDI_LOG);\r
                                }\r
-//                             if (m_dwContextMenus & SVNSLC_POPBLAME)\r
-//                             {\r
-//                                     popup.AppendMenuIcon(IDSVNLC_BLAME, IDS_MENUBLAME, IDI_BLAME);\r
-//                             }\r
+                               if (m_dwContextMenus & SVNSLC_POPBLAME)\r
+                               {\r
+                                       popup.AppendMenuIcon(IDSVNLC_BLAME, IDS_MENUBLAME, IDI_BLAME);\r
+                               }\r
                        }\r
 //                     if ((wcStatus != git_wc_status_deleted)&&(wcStatus != git_wc_status_missing) && (GetSelectedCount() == 1))\r
-//                     {\r
+                       if ( (GetSelectedCount() == 1) )\r
+                       {\r
+                               if (m_dwContextMenus & this->GetContextMenuBit(IDSVNLC_SAVEAS) ) \r
+                               {\r
+                                       popup.AppendMenuIcon(IDSVNLC_SAVEAS, IDS_LOG_POPUP_SAVE, IDI_SAVEAS);\r
+                               }\r
+\r
                                if (m_dwContextMenus & SVNSLC_POPOPEN)\r
                                {\r
+                                       popup.AppendMenuIcon(IDSVNLC_VIEWREV, IDS_LOG_POPUP_VIEWREV);\r
                                        popup.AppendMenuIcon(IDSVNLC_OPEN, IDS_REPOBROWSE_OPEN, IDI_OPEN);\r
                                        popup.AppendMenuIcon(IDSVNLC_OPENWITH, IDS_LOG_POPUP_OPENWITH, IDI_OPEN);\r
                                }\r
+                               \r
                                if (m_dwContextMenus & SVNSLC_POPEXPLORE)\r
                                {\r
                                        popup.AppendMenuIcon(IDSVNLC_EXPLORE, IDS_STATUSLIST_CONTEXT_EXPLORE, IDI_EXPLORER);\r
                                }\r
-//                     }\r
+       \r
+                       }\r
                        if (GetSelectedCount() > 0)\r
                        {\r
 //                             if (((wcStatus == git_wc_status_unversioned)||(wcStatus == git_wc_status_ignored))&&(m_dwContextMenus & SVNSLC_POPDELETE))\r
@@ -2558,27 +2520,8 @@ void CGitStatusListCtrl::OnContextMenuList(CWnd * pWnd, CPoint point)
                                        }\r
                                }\r
                        }\r
-#if 0\r
-                       if (((wcStatus == git_wc_status_conflicted)||(entry->isConflicted)))\r
-                       {\r
-                               if ((m_dwContextMenus & SVNSLC_POPCONFLICT)||(m_dwContextMenus & SVNSLC_POPRESOLVE))\r
-                                       popup.AppendMenu(MF_SEPARATOR);\r
 \r
-                               if ((m_dwContextMenus & SVNSLC_POPCONFLICT)&&(entry->textstatus == git_wc_status_conflicted))\r
-                               {\r
-                                       popup.AppendMenuIcon(IDSVNLC_EDITCONFLICT, IDS_MENUCONFLICT, IDI_CONFLICT);\r
-                               }\r
-                               if (m_dwContextMenus & SVNSLC_POPRESOLVE)\r
-                               {\r
-                                       popup.AppendMenuIcon(IDSVNLC_RESOLVECONFLICT, IDS_STATUSLIST_CONTEXT_RESOLVED, IDI_RESOLVE);\r
-                               }\r
-                               if ((m_dwContextMenus & SVNSLC_POPRESOLVE)&&(entry->textstatus == git_wc_status_conflicted))\r
-                               {\r
-                                       popup.AppendMenuIcon(IDSVNLC_RESOLVETHEIRS, IDS_SVNPROGRESS_MENUUSETHEIRS, IDI_RESOLVE);\r
-                                       popup.AppendMenuIcon(IDSVNLC_RESOLVEMINE, IDS_SVNPROGRESS_MENUUSEMINE, IDI_RESOLVE);\r
-                               }\r
-                       }\r
-#endif\r
+\r
 #if 0                  \r
                        if (GetSelectedCount() > 0)\r
                        {\r
@@ -2726,7 +2669,7 @@ void CGitStatusListCtrl::OnContextMenuList(CWnd * pWnd, CPoint point)
                                break;\r
                        case IDSVNLC_EXPLORE:\r
                                {\r
-                                       ShellExecute(this->m_hWnd, _T("explore"), filepath->GetWinPath(), NULL, NULL, SW_SHOW);\r
+                                       ShellExecute(this->m_hWnd, _T("explore"), filepath->GetDirectory().GetWinPath(), NULL, NULL, SW_SHOW);\r
                                }\r
                                break;\r
                        case IDSVNLC_COMPARE:\r
@@ -2763,10 +2706,13 @@ void CGitStatusListCtrl::OnContextMenuList(CWnd * pWnd, CPoint point)
                                        while ((index = GetNextSelectedItem(pos)) >= 0)\r
                                        {\r
                                                CTGitPath * path=(CTGitPath*)GetItemData(index);\r
+                                               ASSERT(path);\r
+                                               if(path == NULL)\r
+                                                       continue;\r
                                                CString cmd;\r
                                                cmd.Format(_T("git.exe add %s"),path->GetGitPathString());\r
                                                CString output;\r
-                                               if(!g_Git.Run(cmd,&output))\r
+                                               if(!g_Git.Run(cmd,&output,CP_OEMCP))\r
                                                {\r
                                                        path->m_Action = CTGitPath::LOGACTIONS_ADDED;\r
                                                        SetEntryCheck(path,index,true);\r
@@ -2780,438 +2726,268 @@ void CGitStatusListCtrl::OnContextMenuList(CWnd * pWnd, CPoint point)
                                        \r
                                }\r
                                break;\r
-#if 0\r
-                       case IDSVNLC_COPY:\r
-                               CopySelectedEntriesToClipboard(0);\r
-                               break;\r
-                       case IDSVNLC_COPYEXT:\r
-                               CopySelectedEntriesToClipboard((DWORD)-1);\r
-                               break;\r
-                       case IDSVNLC_PROPERTIES:\r
+\r
+                       case IDSVNLC_BLAME:\r
                                {\r
-                                       CTSVNPathList targetList;\r
-                                       FillListOfSelectedItemPaths(targetList);\r
-                                       CEditPropertiesDlg dlg;\r
-                                       dlg.SetPathList(targetList);\r
-                                       dlg.DoModal();\r
-                                       if (dlg.HasChanged())\r
-                                       {\r
-                                               // since the user might have changed/removed/added\r
-                                               // properties recursively, we don't really know\r
-                                               // which items have changed their status.\r
-                                               // So tell the parent to do a refresh.\r
-                                               CWnd* pParent = GetParent();\r
-                                               if (NULL != pParent && NULL != pParent->GetSafeHwnd())\r
-                                               {\r
-                                                       pParent->SendMessage(SVNSLNM_NEEDSREFRESH);\r
-                                               }\r
-                                       }\r
+                                       CString sCmd;\r
+                                       sCmd.Format(_T("\"%s\" /command:blame /path:\"%s\""),\r
+                                               (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")), g_Git.m_CurrentDir+_T("\\")+filepath->GetWinPath());\r
+\r
+                                       CAppUtils::LaunchApplication(sCmd, NULL, false);\r
                                }\r
                                break;\r
-                       case IDSVNLC_COMMIT:\r
+\r
+                       case IDSVNLC_LOG:\r
                                {\r
-                                       CTSVNPathList targetList;\r
-                                       FillListOfSelectedItemPaths(targetList);\r
-                                       CTSVNPath tempFile = CTempFiles::Instance().GetTempFilePath(false);\r
-                                       VERIFY(targetList.WriteToFile(tempFile.GetWinPathString()));\r
-                                       CString commandline = CPathUtils::GetAppDirectory();\r
-                                       commandline += _T("TortoiseProc.exe /command:commit /pathfile:\"");\r
-                                       commandline += tempFile.GetWinPathString();\r
-                                       commandline += _T("\"");\r
-                                       commandline += _T(" /deletepathfile");\r
-                                       CAppUtils::LaunchApplication(commandline, NULL, false);\r
+                                       CString sCmd;\r
+                                       sCmd.Format(_T("\"%s\" /command:log /path:\"%s\""),\r
+                                               (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")), g_Git.m_CurrentDir+_T("\\")+filepath->GetWinPath());\r
+\r
+                                       CAppUtils::LaunchApplication(sCmd, NULL, false);\r
                                }\r
                                break;\r
-                       case IDSVNLC_REVERT:\r
+\r
+                       case IDSVNLC_EDITCONFLICT:\r
+                       {\r
+                               CAppUtils::ConflictEdit(*filepath);\r
+                               break;\r
+                       }\r
+                       case IDSVNLC_RESOLVECONFLICT:\r
+                       {\r
+                               if (CMessageBox::Show(m_hWnd, IDS_PROC_RESOLVE, IDS_APPNAME, MB_ICONQUESTION | MB_YESNO)==IDYES)\r
                                {\r
-                                       // If at least one item is not in the status "added"\r
-                                       // we ask for a confirmation\r
-                                       BOOL bConfirm = FALSE;\r
                                        POSITION pos = GetFirstSelectedItemPosition();\r
-                                       int index;\r
-                                       while ((index = GetNextSelectedItem(pos)) >= 0)\r
+                                       while (pos != 0)\r
                                        {\r
-                                               FileEntry * fentry = GetListEntry(index);\r
-                                               if (fentry->textstatus != git_wc_status_added)\r
+                                               int index;\r
+                                               index = GetNextSelectedItem(pos);\r
+                                               CTGitPath * fentry =(CTGitPath*) this->GetItemData(index);\r
+                                               if(fentry == NULL)\r
+                                                       continue;\r
+\r
+                                               if ( fentry->m_Action & CTGitPath::LOGACTIONS_UNMERGED)\r
                                                {\r
-                                                       bConfirm = TRUE;\r
-                                                       break;\r
+                                                       CString cmd,output;\r
+                                                       cmd.Format(_T("git.exe add \"%s\""),fentry->GetGitPathString());\r
+                                                       if(g_Git.Run(cmd,&output,CP_OEMCP))\r
+                                                       {\r
+                                                               CMessageBox::Show(m_hWnd, output, _T("TortoiseSVN"), MB_ICONERROR);\r
+                                                       }else\r
+                                                       {\r
+                                                               fentry->m_Action |= CTGitPath::LOGACTIONS_MODIFIED;\r
+                                                               fentry->m_Action &=~CTGitPath::LOGACTIONS_UNMERGED;\r
+                                                       }\r
                                                }\r
-                                       }       \r
-\r
-                                       CString str;\r
-                                       str.Format(IDS_PROC_WARNREVERT,GetSelectedCount());\r
-\r
-                                       if (!bConfirm || CMessageBox::Show(this->m_hWnd, str, _T("TortoiseSVN"), MB_YESNO | MB_ICONQUESTION)==IDYES)\r
-                                       {\r
-                                               CTSVNPathList targetList;\r
-                                               FillListOfSelectedItemPaths(targetList);\r
+                                               \r
+                                       }\r
+                                       Show(m_dwShow, 0, m_bShowFolders);\r
+                               }\r
+                       }\r
+                       break;\r
 \r
-                                               // make sure that the list is reverse sorted, so that\r
-                                               // children are removed before any parents\r
-                                               targetList.SortByPathname(true);\r
+                       case IDSVNLC_IGNORE:\r
+                       {\r
+                               CTGitPathList ignorelist;\r
+                               //std::vector<CString> toremove;\r
+                               FillListOfSelectedItemPaths(ignorelist, true);\r
+                               SetRedraw(FALSE);\r
 \r
-                                               SVN git;\r
+                               if(!CAppUtils::IgnoreFile(ignorelist,false))\r
+                                       break;\r
 \r
-                                               // put all reverted files in the trashbin, except the ones with 'added'\r
-                                               // status because they are not restored by the revert.\r
-                                               CTSVNPathList delList;\r
-                                               POSITION pos = GetFirstSelectedItemPosition();\r
-                                               int index;\r
-                                               while ((index = GetNextSelectedItem(pos)) >= 0)\r
+                               for(int i=0;i<ignorelist.GetCount();i++)\r
+                               {\r
+                                       int nListboxEntries = GetItemCount();\r
+                                       for (int nItem=0; nItem<nListboxEntries; ++nItem)\r
+                                       {\r
+                                               CTGitPath *path=(CTGitPath*)GetItemData(nItem);\r
+                                               if (path->GetGitPathString()==ignorelist[i].GetGitPathString())\r
                                                {\r
-                                                       FileEntry * entry = GetListEntry(index);\r
-                                                       if (entry->status != git_wc_status_added)\r
-                                                               delList.AddPath(entry->GetPath());\r
+                                                       RemoveListEntry(nItem);\r
+                                                       break;\r
                                                }\r
-                                               if (DWORD(CRegDWORD(_T("Software\\TortoiseSVN\\RevertWithRecycleBin"), TRUE)))\r
-                                                       delList.DeleteAllFiles(true);\r
-\r
-                                               if (!git.Revert(targetList, CStringArray(), FALSE))\r
+                                       }\r
+                               }\r
+                               SetRedraw(TRUE);\r
+                       }\r
+#if 0\r
+                                       CTSVNPathList ignorelist;\r
+                                       std::vector<CString> toremove;\r
+                                       FillListOfSelectedItemPaths(ignorelist, true);\r
+                                       SetRedraw(FALSE);\r
+                                       for (int j=0; j<ignorelist.GetCount(); ++j)\r
+                                       {\r
+                                               int nListboxEntries = GetItemCount();\r
+                                               for (int i=0; i<nListboxEntries; ++i)\r
+                                               {\r
+                                                       if (GetListEntry(i)->GetPath().IsEquivalentTo(ignorelist[j]))\r
+                                                       {\r
+                                                               selIndex = i;\r
+                                                               break;\r
+                                                       }\r
+                                               }\r
+                                               CString name = CPathUtils::PathPatternEscape(ignorelist[j].GetFileOrDirectoryName());\r
+                                               CTSVNPath parentfolder = ignorelist[j].GetContainingDirectory();\r
+                                               SVNProperties props(parentfolder, SVNRev::REV_WC, false);\r
+                                               CStringA value;\r
+                                               for (int i=0; i<props.GetCount(); i++)\r
                                                {\r
-                                                       CMessageBox::Show(this->m_hWnd, git.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
+                                                       CString propname(props.GetItemName(i).c_str());\r
+                                                       if (propname.CompareNoCase(_T("git:ignore"))==0)\r
+                                                       {\r
+                                                               stdstring stemp;\r
+                                                               // treat values as normal text even if they're not\r
+                                                               value = (char *)props.GetItemValue(i).c_str();\r
+                                                       }\r
                                                }\r
+                                               if (value.IsEmpty())\r
+                                                       value = name;\r
                                                else\r
                                                {\r
-                                                       // since the entries got reverted we need to remove\r
-                                                       // them from the list too, if no remote changes are shown,\r
-                                                       // if the unmodified files are not shown\r
-                                                       // and if the item is not part of a changelist\r
-                                                       POSITION pos;\r
-                                                       SetRedraw(FALSE);\r
-                                                       while ((pos = GetFirstSelectedItemPosition())!=0)\r
+                                                       value = value.Trim("\n\r");\r
+                                                       value += "\n";\r
+                                                       value += name;\r
+                                                       value.Remove('\r');\r
+                                               }\r
+                                               if (!props.Add(_T("git:ignore"), (LPCSTR)value))\r
+                                               {\r
+                                                       CString temp;\r
+                                                       temp.Format(IDS_ERR_FAILEDIGNOREPROPERTY, (LPCTSTR)name);\r
+                                                       CMessageBox::Show(this->m_hWnd, temp, _T("TortoiseSVN"), MB_ICONERROR);\r
+                                                       break;\r
+                                               }\r
+                                               if (GetCheck(selIndex))\r
+                                                       m_nSelected--;\r
+                                               m_nTotal--;\r
+\r
+                                               // now, if we ignored a folder, remove all its children\r
+                                               if (ignorelist[j].IsDirectory())\r
+                                               {\r
+                                                       for (int i=0; i<(int)m_arListArray.size(); ++i)\r
                                                        {\r
-                                                               int index;\r
-                                                               index = GetNextSelectedItem(pos);\r
-                                                               FileEntry * fentry = m_arStatusArray[m_arListArray[index]];\r
-                                                               if ( fentry->IsFolder() )\r
+                                                               FileEntry * entry = GetListEntry(i);\r
+                                                               if (entry->status == git_wc_status_unversioned)\r
                                                                {\r
-                                                                       // refresh!\r
-                                                                       CWnd* pParent = GetParent();\r
-                                                                       if (NULL != pParent && NULL != pParent->GetSafeHwnd())\r
+                                                                       if (!ignorelist[j].IsEquivalentTo(entry->GetPath())&&(ignorelist[j].IsAncestorOf(entry->GetPath())))\r
                                                                        {\r
-                                                                               pParent->SendMessage(SVNSLNM_NEEDSREFRESH);\r
+                                                                               entry->status = git_wc_status_ignored;\r
+                                                                               entry->textstatus = git_wc_status_ignored;\r
+                                                                               if (GetCheck(i))\r
+                                                                                       m_nSelected--;\r
+                                                                               toremove.push_back(entry->GetPath().GetSVNPathString());\r
                                                                        }\r
-                                                                       break;\r
-                                                               }\r
-\r
-                                                               BOOL bAdded = (fentry->textstatus == git_wc_status_added);\r
-                                                               fentry->status = git_wc_status_normal;\r
-                                                               fentry->propstatus = git_wc_status_normal;\r
-                                                               fentry->textstatus = git_wc_status_normal;\r
-                                                               fentry->copied = false;\r
-                                                               fentry->isConflicted = false;\r
-                                                               if ((fentry->GetChangeList().IsEmpty()&&(fentry->remotestatus <= git_wc_status_normal))||(m_dwShow & SVNSLC_SHOWNORMAL))\r
-                                                               {\r
-                                                                       if ( bAdded )\r
-                                                                       {\r
-                                                                               // reverting added items makes them unversioned, not 'normal'\r
-                                                                               if (fentry->IsFolder())\r
-                                                                                       fentry->propstatus = git_wc_status_none;\r
-                                                                               else\r
-                                                                                       fentry->propstatus = git_wc_status_unversioned;\r
-                                                                               fentry->status = git_wc_status_unversioned;\r
-                                                                               fentry->textstatus = git_wc_status_unversioned;\r
-                                                                               SetItemState(index, 0, LVIS_SELECTED);\r
-                                                                               SetEntryCheck(fentry, index, false);\r
-                                                                       }\r
-                                                                       else if ((fentry->switched)||(m_dwShow & SVNSLC_SHOWNORMAL))\r
-                                                                       {\r
-                                                                               SetItemState(index, 0, LVIS_SELECTED);\r
-                                                                       }\r
-                                                                       else\r
-                                                                       {\r
-                                                                               m_nTotal--;\r
-                                                                               if (GetCheck(index))\r
-                                                                                       m_nSelected--;\r
-                                                                               RemoveListEntry(index);\r
-                                                                               Invalidate();\r
-                                                                       }\r
-                                                               }\r
-                                                               else\r
-                                                               {\r
-                                                                       SetItemState(index, 0, LVIS_SELECTED);\r
                                                                }\r
                                                        }\r
-                                                       SetRedraw(TRUE);\r
-                                                       SaveColumnWidths();\r
-                                                       Show(m_dwShow, 0, m_bShowFolders);\r
-                                                       NotifyCheck();\r
-                                               }\r
-                                       }\r
-                               }\r
-                               break;\r
-                       case IDSVNLC_COMPARE:\r
-                               {\r
-                                       POSITION pos = GetFirstSelectedItemPosition();\r
-                                       while ( pos )\r
-                                       {\r
-                                               int index = GetNextSelectedItem(pos);\r
-                                               StartDiff(index);\r
-                                       }\r
-                               }\r
-                               break;\r
-                       case IDSVNLC_COMPAREWC:\r
-                               {\r
-                                       POSITION pos = GetFirstSelectedItemPosition();\r
-                                       while ( pos )\r
-                                       {\r
-                                               int index = GetNextSelectedItem(pos);\r
-                                               FileEntry * entry = GetListEntry(index);\r
-                                               ASSERT(entry != NULL);\r
-                                               if (entry == NULL)\r
-                                                       continue;\r
-                                               SVNDiff diff(NULL, m_hWnd, true);\r
-                                               diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
-                                               git_revnum_t baseRev = entry->Revision;\r
-                                               diff.DiffFileAgainstBase(\r
-                                                       entry->path, baseRev, entry->textstatus, entry->propstatus);\r
-                                       }\r
-                               }\r
-                               break;\r
-                       case IDSVNLC_GNUDIFF1:\r
-                               {\r
-                                       SVNDiff diff(NULL, this->m_hWnd, true);\r
-\r
-                                       if (entry->remotestatus <= git_wc_status_normal)\r
-                                               CAppUtils::StartShowUnifiedDiff(m_hWnd, entry->path, SVNRev::REV_BASE, entry->path, SVNRev::REV_WC);\r
-                                       else\r
-                                               CAppUtils::StartShowUnifiedDiff(m_hWnd, entry->path, SVNRev::REV_WC, entry->path, SVNRev::REV_HEAD);\r
-                               }\r
-                               break;\r
-                       case IDSVNLC_UPDATE:\r
-                               {\r
-                                       CTSVNPathList targetList;\r
-                                       FillListOfSelectedItemPaths(targetList);\r
-                                       bool bAllExist = true;\r
-                                       for (int i=0; i<targetList.GetCount(); ++i)\r
-                                       {\r
-                                               if (!targetList[i].Exists())\r
-                                               {\r
-                                                       bAllExist = false;\r
-                                                       break;\r
                                                }\r
-                                       }\r
-                                       if (bAllExist)\r
-                                       {\r
-                                               CSVNProgressDlg dlg;\r
-                                               dlg.SetCommand(CSVNProgressDlg::SVNProgress_Update);\r
-                                               dlg.SetPathList(targetList);\r
-                                               dlg.SetRevision(SVNRev::REV_HEAD);\r
-                                               dlg.DoModal();\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               CString sTempFile = CTempFiles::Instance().GetTempFilePath(false).GetWinPathString();\r
-                                               targetList.WriteToFile(sTempFile, false);\r
-                                               CString sCmd;\r
-                                               sCmd.Format(_T("\"%s\" /command:update /rev /pathfile:\"%s\" /deletepathfile"),\r
-                                                       (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")), (LPCTSTR)sTempFile);\r
-\r
-                                               CAppUtils::LaunchApplication(sCmd, NULL, false);\r
-                                       }\r
-                               }\r
-                               break;\r
-                       case IDSVNLC_LOG:\r
-                               {\r
-                                       CString sCmd;\r
-                                       sCmd.Format(_T("\"%s\" /command:log /path:\"%s\""),\r
-                                               (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")), filepath.GetWinPath());\r
-\r
-                                       if (!filepath.IsUrl())\r
-                                       {\r
-                                               sCmd += _T(" /propspath:\"");\r
-                                               sCmd += filepath.GetWinPathString();\r
-                                               sCmd += _T("\"");\r
-                                       }       \r
-\r
-                                       CAppUtils::LaunchApplication(sCmd, NULL, false);\r
-                               }\r
-                               break;\r
-                       case IDSVNLC_BLAME:\r
-                               {\r
-                                       CString sCmd;\r
-                                       sCmd.Format(_T("\"%s\" /command:blame /path:\"%s\""),\r
-                                               (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")), filepath.GetWinPath());\r
 \r
-                                       if (!filepath.IsUrl())\r
-                                       {\r
-                                               sCmd += _T(" /propspath:\"");\r
-                                               sCmd += filepath.GetWinPathString();\r
-                                               sCmd += _T("\"");\r
-                                       }       \r
-\r
-                                       CAppUtils::LaunchApplication(sCmd, NULL, false);\r
-                               }\r
-                               break;\r
-                       case IDSVNLC_OPEN:\r
-                               {\r
-                                       int ret = (int)ShellExecute(this->m_hWnd, NULL, filepath.GetWinPath(), NULL, NULL, SW_SHOW);\r
-                                       if (ret <= HINSTANCE_ERROR)\r
-                                       {\r
-                                               CString cmd = _T("RUNDLL32 Shell32,OpenAs_RunDLL ");\r
-                                               cmd += filepath.GetWinPathString();\r
-                                               CAppUtils::LaunchApplication(cmd, NULL, false);\r
-                                       }\r
-                               }\r
-                               break;\r
-                       case IDSVNLC_OPENWITH:\r
-                               {\r
-                                       CString cmd = _T("RUNDLL32 Shell32,OpenAs_RunDLL ");\r
-                                       cmd += filepath.GetWinPathString() + _T(" ");\r
-                                       CAppUtils::LaunchApplication(cmd, NULL, false);\r
-                               }\r
-                               break;\r
-                       case IDSVNLC_EXPLORE:\r
-                               {\r
-                                       ShellExecute(this->m_hWnd, _T("explore"), filepath.GetDirectory().GetWinPath(), NULL, NULL, SW_SHOW);\r
-                               }\r
-                               break;\r
-                       case IDSVNLC_REMOVE:\r
-                               {\r
-                                       SVN git;\r
-                                       CTSVNPathList itemsToRemove;\r
-                                       FillListOfSelectedItemPaths(itemsToRemove);\r
+                                               CTSVNPath basepath = m_arStatusArray[m_arListArray[selIndex]]->basepath;\r
 \r
-                                       // We must sort items before removing, so that files are always removed\r
-                                       // *before* their parents\r
-                                       itemsToRemove.SortByPathname(true);\r
+                                               FileEntry * entry = m_arStatusArray[m_arListArray[selIndex]];\r
+                                               if ( entry->status == git_wc_status_unversioned ) // keep "deleted" items\r
+                                                       toremove.push_back(entry->GetPath().GetSVNPathString());\r
 \r
-                                       bool bSuccess = false;\r
-                                       if (git.Remove(itemsToRemove, FALSE, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000)))\r
-                                       {\r
-                                               bSuccess = true;\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               if ((git.Err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE) ||\r
-                                                       (git.Err->apr_err == SVN_ERR_CLIENT_MODIFIED))\r
+                                               if (!m_bIgnoreRemoveOnly)\r
                                                {\r
-                                                       CString msg, yes, no, yestoall;\r
-                                                       msg.Format(IDS_PROC_REMOVEFORCE, (LPCTSTR)git.GetLastErrorMessage());\r
-                                                       yes.LoadString(IDS_MSGBOX_YES);\r
-                                                       no.LoadString(IDS_MSGBOX_NO);\r
-                                                       yestoall.LoadString(IDS_PROC_YESTOALL);\r
-                                                       UINT ret = CMessageBox::Show(m_hWnd, msg, _T("TortoiseSVN"), 2, IDI_ERROR, yes, no, yestoall);\r
-                                                       if ((ret == 1)||(ret==3))\r
+                                                       SVNStatus status;\r
+                                                       git_wc_status2_t * s;\r
+                                                       CTSVNPath gitPath;\r
+                                                       s = status.GetFirstFileStatus(parentfolder, gitPath, false, git_depth_empty);\r
+                                                       // first check if the folder isn't already present in the list\r
+                                                       bool bFound = false;\r
+                                                       nListboxEntries = GetItemCount();\r
+                                                       for (int i=0; i<nListboxEntries; ++i)\r
                                                        {\r
-                                                               if (!git.Remove(itemsToRemove, TRUE, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000)))\r
+                                                               FileEntry * entry = GetListEntry(i);\r
+                                                               if (entry->path.IsEquivalentTo(gitPath))\r
                                                                {\r
-                                                                       CMessageBox::Show(m_hWnd, git.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
+                                                                       bFound = true;\r
+                                                                       break;\r
+                                                               }\r
+                                                       }\r
+                                                       if (!bFound)\r
+                                                       {\r
+                                                               if (s!=0)\r
+                                                               {\r
+                                                                       FileEntry * entry = new FileEntry();\r
+                                                                       entry->path = gitPath;\r
+                                                                       entry->basepath = basepath;\r
+                                                                       entry->status = SVNStatus::GetMoreImportant(s->text_status, s->prop_status);\r
+                                                                       entry->textstatus = s->text_status;\r
+                                                                       entry->propstatus = s->prop_status;\r
+                                                                       entry->remotestatus = SVNStatus::GetMoreImportant(s->repos_text_status, s->repos_prop_status);\r
+                                                                       entry->remotetextstatus = s->repos_text_status;\r
+                                                                       entry->remotepropstatus = s->repos_prop_status;\r
+                                                                       entry->inunversionedfolder = FALSE;\r
+                                                                       entry->checked = true;\r
+                                                                       entry->inexternal = false;\r
+                                                                       entry->direct = false;\r
+                                                                       entry->isfolder = true;\r
+                                                                       entry->last_commit_date = 0;\r
+                                                                       entry->last_commit_rev = 0;\r
+                                                                       entry->remoterev = 0;\r
+                                                                       if (s->entry)\r
+                                                                       {\r
+                                                                               if (s->entry->url)\r
+                                                                               {\r
+                                                                                       entry->url = CUnicodeUtils::GetUnicode(CPathUtils::PathUnescape(s->entry->url));\r
+                                                                               }\r
+                                                                       }\r
+                                                                       if (s->entry && s->entry->present_props)\r
+                                                                       {\r
+                                                                               entry->present_props = s->entry->present_props;\r
+                                                                       }\r
+                                                                       m_arStatusArray.push_back(entry);\r
+                                                                       m_arListArray.push_back(m_arStatusArray.size()-1);\r
+                                                                       AddEntry(entry, langID, GetItemCount());\r
                                                                }\r
-                                                               else\r
-                                                                       bSuccess = true;\r
                                                        }\r
                                                }\r
-                                               else\r
-                                                       CMessageBox::Show(m_hWnd, git.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
                                        }\r
-                                       if (bSuccess)\r
+                                       for (std::vector<CString>::iterator it = toremove.begin(); it != toremove.end(); ++it)\r
                                        {\r
-                                               // The remove went ok, but we now need to run through the selected items again\r
-                                               // and update their status\r
-                                               POSITION pos = GetFirstSelectedItemPosition();\r
-                                               int index;\r
-                                               std::vector<int> entriesToRemove;\r
-                                               while ((index = GetNextSelectedItem(pos)) >= 0)\r
+                                               int nListboxEntries = GetItemCount();\r
+                                               for (int i=0; i<nListboxEntries; ++i)\r
                                                {\r
-                                                       FileEntry * e = GetListEntry(index);\r
-                                                       if (!bShift &&\r
-                                                               ((e->textstatus == git_wc_status_unversioned)||\r
-                                                               (e->textstatus == git_wc_status_none)||\r
-                                                               (e->textstatus == git_wc_status_ignored)))\r
-                                                       {\r
-                                                               if (GetCheck(index))\r
-                                                                       m_nSelected--;\r
-                                                               m_nTotal--;\r
-                                                               entriesToRemove.push_back(index);\r
-                                                       }\r
-                                                       else\r
+                                                       if (GetListEntry(i)->path.GetSVNPathString().Compare(*it)==0)\r
                                                        {\r
-                                                               e->textstatus = git_wc_status_deleted;\r
-                                                               e->status = git_wc_status_deleted;\r
-                                                               SetEntryCheck(e,index,true);\r
+                                                               RemoveListEntry(i);\r
+                                                               break;\r
                                                        }\r
                                                }\r
-                                               for (std::vector<int>::reverse_iterator it = entriesToRemove.rbegin(); it != entriesToRemove.rend(); ++it)\r
-                                               {\r
-                                                       RemoveListEntry(*it);\r
-                                               }\r
                                        }\r
-                                       SaveColumnWidths();\r
-                                       Show(m_dwShow, 0, m_bShowFolders);\r
-                                       NotifyCheck();\r
+                                       SetRedraw(TRUE);\r
                                }\r
+#endif\r
                                break;\r
-                       case IDSVNLC_DELETE:\r
+                       case IDSVNLC_IGNOREMASK:\r
                                {\r
-                                       CTSVNPathList pathlist;\r
-                                       FillListOfSelectedItemPaths(pathlist);\r
-                                       pathlist.RemoveChildren();\r
-                                       CString filelist;\r
-                                       for (INT_PTR i=0; i<pathlist.GetCount(); ++i)\r
-                                       {\r
-                                               filelist += pathlist[i].GetWinPathString();\r
-                                               filelist += _T("|");\r
-                                       }\r
-                                       filelist += _T("|");\r
-                                       int len = filelist.GetLength();\r
-                                       TCHAR * buf = new TCHAR[len+2];\r
-                                       _tcscpy_s(buf, len+2, filelist);\r
-                                       for (int i=0; i<len; ++i)\r
-                                               if (buf[i] == '|')\r
-                                                       buf[i] = 0;\r
-                                       SHFILEOPSTRUCT fileop;\r
-                                       fileop.hwnd = this->m_hWnd;\r
-                                       fileop.wFunc = FO_DELETE;\r
-                                       fileop.pFrom = buf;\r
-                                       fileop.pTo = NULL;\r
-                                       fileop.fFlags = FOF_NO_CONNECTED_ELEMENTS | ((GetAsyncKeyState(VK_SHIFT) & 0x8000) ? 0 : FOF_ALLOWUNDO);\r
-                                       fileop.lpszProgressTitle = _T("deleting file");\r
-                                       int result = SHFileOperation(&fileop);\r
-                                       delete [] buf;\r
+                                       CString common;\r
+                                       CString ext=filepath->GetFileExtension();\r
+                                       CTGitPathList ignorelist;\r
+                                       FillListOfSelectedItemPaths(ignorelist, true);\r
+                                       SetRedraw(FALSE);\r
 \r
-                                       if ( (result==0) && (!fileop.fAnyOperationsAborted) )\r
+                                       CAppUtils::IgnoreFile(ignorelist,true);\r
+                                       common=ignorelist.GetCommonRoot().GetGitPathString();\r
+\r
+                                       for (int i=0; i< GetItemCount(); ++i)\r
                                        {\r
-                                               SetRedraw(FALSE);\r
-                                               POSITION pos = NULL;\r
-                                               CTSVNPathList deletedlist;      // to store list of deleted folders\r
-                                               while ((pos = GetFirstSelectedItemPosition()) != 0)\r
-                                               {\r
-                                                       int index = GetNextSelectedItem(pos);\r
-                                                       if (GetCheck(index))\r
-                                                               m_nSelected--;\r
-                                                       m_nTotal--;\r
-                                                       FileEntry * fentry = GetListEntry(index);\r
-                                                       if ((fentry)&&(fentry->isfolder))\r
-                                                               deletedlist.AddPath(fentry->path);\r
-                                                       RemoveListEntry(index);\r
-                                               }\r
-                                               // now go through the list of deleted folders\r
-                                               // and remove all their children from the list too!\r
-                                               int nListboxEntries = GetItemCount();\r
-                                               for (int folderindex = 0; folderindex < deletedlist.GetCount(); ++folderindex)\r
+                                               CTGitPath *path=(CTGitPath*)GetItemData(i);\r
+                                               if(!( path->m_Action & CTGitPath::LOGACTIONS_UNVER))\r
+                                                       continue;\r
+                                               if( path->GetGitPathString().Left(common.GetLength()) == common )\r
                                                {\r
-                                                       CTSVNPath folderpath = deletedlist[folderindex];\r
-                                                       for (int i=0; i<nListboxEntries; ++i)\r
+                                                       if (path->GetFileExtension()==ext)\r
                                                        {\r
-                                                               FileEntry * entry = GetListEntry(i);\r
-                                                               if (folderpath.IsAncestorOf(entry->path))\r
-                                                               {\r
-                                                                       RemoveListEntry(i--);\r
-                                                                       nListboxEntries--;\r
-                                                               }\r
+                                                               RemoveListEntry(i);\r
+                                                               i--; // remove index i at item, new one will replace. \r
                                                        }\r
                                                }\r
-                                               SetRedraw(TRUE);\r
                                        }\r
+                                       \r
+                                       SetRedraw(TRUE);\r
                                }\r
-                               break;\r
-                       case IDSVNLC_IGNOREMASK:\r
-                               {\r
-                                       CString name = _T("*")+filepath.GetFileExtension();\r
-                                       CTSVNPathList ignorelist;\r
-                                       FillListOfSelectedItemPaths(ignorelist, true);\r
+#if 0\r
                                        std::set<CTSVNPath> parentlist;\r
                                        for (int i=0; i<ignorelist.GetCount(); ++i)\r
                                        {\r
@@ -3219,7 +2995,7 @@ void CGitStatusListCtrl::OnContextMenuList(CWnd * pWnd, CPoint point)
                                        }\r
                                        std::set<CTSVNPath>::iterator it;\r
                                        std::vector<CString> toremove;\r
-                                       SetRedraw(FALSE);\r
+                                       \r
                                        for (it = parentlist.begin(); it != parentlist.end(); ++it)\r
                                        {\r
                                                CTSVNPath parentFolder = (*it).GetDirectory();\r
@@ -3353,200 +3129,336 @@ void CGitStatusListCtrl::OnContextMenuList(CWnd * pWnd, CPoint point)
                                        }\r
                                        SetRedraw(TRUE);\r
                                }\r
+#endif\r
                                break;\r
-                       case IDSVNLC_IGNORE:\r
+                       \r
+                               case IDSVNLC_REVERT:\r
                                {\r
-                                       CTSVNPathList ignorelist;\r
-                                       std::vector<CString> toremove;\r
-                                       FillListOfSelectedItemPaths(ignorelist, true);\r
-                                       SetRedraw(FALSE);\r
-                                       for (int j=0; j<ignorelist.GetCount(); ++j)\r
+                                       // If at least one item is not in the status "added"\r
+                                       // we ask for a confirmation\r
+                                       BOOL bConfirm = FALSE;\r
+                                       POSITION pos = GetFirstSelectedItemPosition();\r
+                                       int index;\r
+                                       while ((index = GetNextSelectedItem(pos)) >= 0)\r
                                        {\r
-                                               int nListboxEntries = GetItemCount();\r
-                                               for (int i=0; i<nListboxEntries; ++i)\r
-                                               {\r
-                                                       if (GetListEntry(i)->GetPath().IsEquivalentTo(ignorelist[j]))\r
-                                                       {\r
-                                                               selIndex = i;\r
-                                                               break;\r
-                                                       }\r
-                                               }\r
-                                               CString name = CPathUtils::PathPatternEscape(ignorelist[j].GetFileOrDirectoryName());\r
-                                               CTSVNPath parentfolder = ignorelist[j].GetContainingDirectory();\r
-                                               SVNProperties props(parentfolder, SVNRev::REV_WC, false);\r
-                                               CStringA value;\r
-                                               for (int i=0; i<props.GetCount(); i++)\r
+                                               //FileEntry * fentry = GetListEntry(index);\r
+                                               CTGitPath *fentry=(CTGitPath*)GetItemData(index);\r
+                                               if(fentry && fentry->m_Action &CTGitPath::LOGACTIONS_MODIFIED )\r
                                                {\r
-                                                       CString propname(props.GetItemName(i).c_str());\r
-                                                       if (propname.CompareNoCase(_T("git:ignore"))==0)\r
-                                                       {\r
-                                                               stdstring stemp;\r
-                                                               // treat values as normal text even if they're not\r
-                                                               value = (char *)props.GetItemValue(i).c_str();\r
-                                                       }\r
+                                                       bConfirm = TRUE;\r
+                                                       break;\r
                                                }\r
-                                               if (value.IsEmpty())\r
-                                                       value = name;\r
-                                               else\r
+                                       }       \r
+\r
+                                       CString str;\r
+                                       str.Format(IDS_PROC_WARNREVERT,GetSelectedCount());\r
+\r
+                                       if (!bConfirm || CMessageBox::Show(this->m_hWnd, str, _T("TortoiseSVN"), MB_YESNO | MB_ICONQUESTION)==IDYES)\r
+                                       {\r
+                                               CTGitPathList targetList;\r
+                                               FillListOfSelectedItemPaths(targetList);\r
+\r
+                                               // make sure that the list is reverse sorted, so that\r
+                                               // children are removed before any parents\r
+                                               targetList.SortByPathname(true);\r
+\r
+                                               // put all reverted files in the trashbin, except the ones with 'added'\r
+                                               // status because they are not restored by the revert.\r
+                                               CTGitPathList delList;\r
+                                               POSITION pos = GetFirstSelectedItemPosition();\r
+                                               int index;\r
+                                               while ((index = GetNextSelectedItem(pos)) >= 0)\r
                                                {\r
-                                                       value = value.Trim("\n\r");\r
-                                                       value += "\n";\r
-                                                       value += name;\r
-                                                       value.Remove('\r');\r
+                                                       CTGitPath *entry=(CTGitPath *)GetItemData(index);\r
+                                                       if (entry&&(!(entry->m_Action& CTGitPath::LOGACTIONS_ADDED)))\r
+                                                               delList.AddPath(*entry);\r
                                                }\r
-                                               if (!props.Add(_T("git:ignore"), (LPCSTR)value))\r
+                                               if (DWORD(CRegDWORD(_T("Software\\TortoiseGit\\RevertWithRecycleBin"), TRUE)))\r
+                                                       delList.DeleteAllFiles(true);\r
+\r
+                                               if (g_Git.Revert(targetList))\r
                                                {\r
-                                                       CString temp;\r
-                                                       temp.Format(IDS_ERR_FAILEDIGNOREPROPERTY, (LPCTSTR)name);\r
-                                                       CMessageBox::Show(this->m_hWnd, temp, _T("TortoiseSVN"), MB_ICONERROR);\r
-                                                       break;\r
+                                                       CMessageBox::Show(this->m_hWnd, _T("Revert Fail"), _T("TortoiseSVN"), MB_ICONERROR);\r
                                                }\r
-                                               if (GetCheck(selIndex))\r
-                                                       m_nSelected--;\r
-                                               m_nTotal--;\r
-\r
-                                               // now, if we ignored a folder, remove all its children\r
-                                               if (ignorelist[j].IsDirectory())\r
+                                               else\r
                                                {\r
-                                                       for (int i=0; i<(int)m_arListArray.size(); ++i)\r
-                                                       {\r
-                                                               FileEntry * entry = GetListEntry(i);\r
-                                                               if (entry->status == git_wc_status_unversioned)\r
+                                                       for(int i=0;i<targetList.GetCount();i++)\r
+                                                       {       \r
+                                                               int nListboxEntries = GetItemCount();\r
+                                                               for (int nItem=0; nItem<nListboxEntries; ++nItem)\r
                                                                {\r
-                                                                       if (!ignorelist[j].IsEquivalentTo(entry->GetPath())&&(ignorelist[j].IsAncestorOf(entry->GetPath())))\r
+                                                                       CTGitPath *path=(CTGitPath*)GetItemData(nItem);\r
+                                                                       if (path->GetGitPathString()==targetList[i].GetGitPathString())\r
                                                                        {\r
-                                                                               entry->status = git_wc_status_ignored;\r
-                                                                               entry->textstatus = git_wc_status_ignored;\r
-                                                                               if (GetCheck(i))\r
-                                                                                       m_nSelected--;\r
-                                                                               toremove.push_back(entry->GetPath().GetSVNPathString());\r
+                                                                               RemoveListEntry(nItem);\r
+                                                                               break;\r
                                                                        }\r
                                                                }\r
                                                        }\r
+                                                       SetRedraw(TRUE);\r
+                                                       SaveColumnWidths();\r
+                                                       Show(m_dwShow, 0, m_bShowFolders);\r
+                                                       NotifyCheck();\r
                                                }\r
+                                       }\r
+                               }\r
+                               break;\r
 \r
-                                               CTSVNPath basepath = m_arStatusArray[m_arListArray[selIndex]]->basepath;\r
+                       case IDSVNLC_COPY:\r
+                               CopySelectedEntriesToClipboard(0);\r
+                               break;\r
+                       case IDSVNLC_COPYEXT:\r
+                               CopySelectedEntriesToClipboard((DWORD)-1);\r
+                               break;\r
 \r
-                                               FileEntry * entry = m_arStatusArray[m_arListArray[selIndex]];\r
-                                               if ( entry->status == git_wc_status_unversioned ) // keep "deleted" items\r
-                                                       toremove.push_back(entry->GetPath().GetSVNPathString());\r
+                       case IDSVNLC_SAVEAS:\r
+                               FileSaveAs(filepath);\r
+                               break;\r
 \r
-                                               if (!m_bIgnoreRemoveOnly)\r
+                       case IDSVNLC_REVERTTOREV:\r
+                               RevertSelectedItemToVersion();\r
+                               break;\r
+#if 0\r
+                       case IDSVNLC_PROPERTIES:\r
+                               {\r
+                                       CTSVNPathList targetList;\r
+                                       FillListOfSelectedItemPaths(targetList);\r
+                                       CEditPropertiesDlg dlg;\r
+                                       dlg.SetPathList(targetList);\r
+                                       dlg.DoModal();\r
+                                       if (dlg.HasChanged())\r
+                                       {\r
+                                               // since the user might have changed/removed/added\r
+                                               // properties recursively, we don't really know\r
+                                               // which items have changed their status.\r
+                                               // So tell the parent to do a refresh.\r
+                                               CWnd* pParent = GetParent();\r
+                                               if (NULL != pParent && NULL != pParent->GetSafeHwnd())\r
                                                {\r
-                                                       SVNStatus status;\r
-                                                       git_wc_status2_t * s;\r
-                                                       CTSVNPath gitPath;\r
-                                                       s = status.GetFirstFileStatus(parentfolder, gitPath, false, git_depth_empty);\r
-                                                       // first check if the folder isn't already present in the list\r
-                                                       bool bFound = false;\r
-                                                       nListboxEntries = GetItemCount();\r
-                                                       for (int i=0; i<nListboxEntries; ++i)\r
-                                                       {\r
-                                                               FileEntry * entry = GetListEntry(i);\r
-                                                               if (entry->path.IsEquivalentTo(gitPath))\r
-                                                               {\r
-                                                                       bFound = true;\r
-                                                                       break;\r
-                                                               }\r
-                                                       }\r
-                                                       if (!bFound)\r
-                                                       {\r
-                                                               if (s!=0)\r
-                                                               {\r
-                                                                       FileEntry * entry = new FileEntry();\r
-                                                                       entry->path = gitPath;\r
-                                                                       entry->basepath = basepath;\r
-                                                                       entry->status = SVNStatus::GetMoreImportant(s->text_status, s->prop_status);\r
-                                                                       entry->textstatus = s->text_status;\r
-                                                                       entry->propstatus = s->prop_status;\r
-                                                                       entry->remotestatus = SVNStatus::GetMoreImportant(s->repos_text_status, s->repos_prop_status);\r
-                                                                       entry->remotetextstatus = s->repos_text_status;\r
-                                                                       entry->remotepropstatus = s->repos_prop_status;\r
-                                                                       entry->inunversionedfolder = FALSE;\r
-                                                                       entry->checked = true;\r
-                                                                       entry->inexternal = false;\r
-                                                                       entry->direct = false;\r
-                                                                       entry->isfolder = true;\r
-                                                                       entry->last_commit_date = 0;\r
-                                                                       entry->last_commit_rev = 0;\r
-                                                                       entry->remoterev = 0;\r
-                                                                       if (s->entry)\r
-                                                                       {\r
-                                                                               if (s->entry->url)\r
-                                                                               {\r
-                                                                                       entry->url = CUnicodeUtils::GetUnicode(CPathUtils::PathUnescape(s->entry->url));\r
-                                                                               }\r
-                                                                       }\r
-                                                                       if (s->entry && s->entry->present_props)\r
-                                                                       {\r
-                                                                               entry->present_props = s->entry->present_props;\r
-                                                                       }\r
-                                                                       m_arStatusArray.push_back(entry);\r
-                                                                       m_arListArray.push_back(m_arStatusArray.size()-1);\r
-                                                                       AddEntry(entry, langID, GetItemCount());\r
+                                                       pParent->SendMessage(SVNSLNM_NEEDSREFRESH);\r
+                                               }\r
+                                       }\r
+                               }\r
+                               break;\r
+                       case IDSVNLC_COMMIT:\r
+                               {\r
+                                       CTSVNPathList targetList;\r
+                                       FillListOfSelectedItemPaths(targetList);\r
+                                       CTSVNPath tempFile = CTempFiles::Instance().GetTempFilePath(false);\r
+                                       VERIFY(targetList.WriteToFile(tempFile.GetWinPathString()));\r
+                                       CString commandline = CPathUtils::GetAppDirectory();\r
+                                       commandline += _T("TortoiseProc.exe /command:commit /pathfile:\"");\r
+                                       commandline += tempFile.GetWinPathString();\r
+                                       commandline += _T("\"");\r
+                                       commandline += _T(" /deletepathfile");\r
+                                       CAppUtils::LaunchApplication(commandline, NULL, false);\r
+                               }\r
+                               break;\r
+               \r
+               case IDSVNLC_COMPAREWC:\r
+                               {\r
+                                       POSITION pos = GetFirstSelectedItemPosition();\r
+                                       while ( pos )\r
+                                       {\r
+                                               int index = GetNextSelectedItem(pos);\r
+                                               FileEntry * entry = GetListEntry(index);\r
+                                               ASSERT(entry != NULL);\r
+                                               if (entry == NULL)\r
+                                                       continue;\r
+                                               SVNDiff diff(NULL, m_hWnd, true);\r
+                                               diff.SetAlternativeTool(!!(GetAsyncKeyState(VK_SHIFT) & 0x8000));\r
+                                               git_revnum_t baseRev = entry->Revision;\r
+                                               diff.DiffFileAgainstBase(\r
+                                                       entry->path, baseRev, entry->textstatus, entry->propstatus);\r
+                                       }\r
+                               }\r
+                               break;\r
+                       case IDSVNLC_GNUDIFF1:\r
+                               {\r
+                                       SVNDiff diff(NULL, this->m_hWnd, true);\r
+\r
+                                       if (entry->remotestatus <= git_wc_status_normal)\r
+                                               CAppUtils::StartShowUnifiedDiff(m_hWnd, entry->path, SVNRev::REV_BASE, entry->path, SVNRev::REV_WC);\r
+                                       else\r
+                                               CAppUtils::StartShowUnifiedDiff(m_hWnd, entry->path, SVNRev::REV_WC, entry->path, SVNRev::REV_HEAD);\r
+                               }\r
+                               break;\r
+                       case IDSVNLC_UPDATE:\r
+                               {\r
+                                       CTSVNPathList targetList;\r
+                                       FillListOfSelectedItemPaths(targetList);\r
+                                       bool bAllExist = true;\r
+                                       for (int i=0; i<targetList.GetCount(); ++i)\r
+                                       {\r
+                                               if (!targetList[i].Exists())\r
+                                               {\r
+                                                       bAllExist = false;\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       if (bAllExist)\r
+                                       {\r
+                                               CSVNProgressDlg dlg;\r
+                                               dlg.SetCommand(CSVNProgressDlg::SVNProgress_Update);\r
+                                               dlg.SetPathList(targetList);\r
+                                               dlg.SetRevision(SVNRev::REV_HEAD);\r
+                                               dlg.DoModal();\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               CString sTempFile = CTempFiles::Instance().GetTempFilePath(false).GetWinPathString();\r
+                                               targetList.WriteToFile(sTempFile, false);\r
+                                               CString sCmd;\r
+                                               sCmd.Format(_T("\"%s\" /command:update /rev /pathfile:\"%s\" /deletepathfile"),\r
+                                                       (LPCTSTR)(CPathUtils::GetAppDirectory()+_T("TortoiseProc.exe")), (LPCTSTR)sTempFile);\r
+\r
+                                               CAppUtils::LaunchApplication(sCmd, NULL, false);\r
+                                       }\r
+                               }\r
+                               break;\r
+       \r
+                       case IDSVNLC_REMOVE:\r
+                               {\r
+                                       SVN git;\r
+                                       CTSVNPathList itemsToRemove;\r
+                                       FillListOfSelectedItemPaths(itemsToRemove);\r
+\r
+                                       // We must sort items before removing, so that files are always removed\r
+                                       // *before* their parents\r
+                                       itemsToRemove.SortByPathname(true);\r
+\r
+                                       bool bSuccess = false;\r
+                                       if (git.Remove(itemsToRemove, FALSE, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000)))\r
+                                       {\r
+                                               bSuccess = true;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               if ((git.Err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE) ||\r
+                                                       (git.Err->apr_err == SVN_ERR_CLIENT_MODIFIED))\r
+                                               {\r
+                                                       CString msg, yes, no, yestoall;\r
+                                                       msg.Format(IDS_PROC_REMOVEFORCE, (LPCTSTR)git.GetLastErrorMessage());\r
+                                                       yes.LoadString(IDS_MSGBOX_YES);\r
+                                                       no.LoadString(IDS_MSGBOX_NO);\r
+                                                       yestoall.LoadString(IDS_PROC_YESTOALL);\r
+                                                       UINT ret = CMessageBox::Show(m_hWnd, msg, _T("TortoiseSVN"), 2, IDI_ERROR, yes, no, yestoall);\r
+                                                       if ((ret == 1)||(ret==3))\r
+                                                       {\r
+                                                               if (!git.Remove(itemsToRemove, TRUE, !!(GetAsyncKeyState(VK_SHIFT) & 0x8000)))\r
+                                                               {\r
+                                                                       CMessageBox::Show(m_hWnd, git.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
                                                                }\r
+                                                               else\r
+                                                                       bSuccess = true;\r
                                                        }\r
                                                }\r
+                                               else\r
+                                                       CMessageBox::Show(m_hWnd, git.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
                                        }\r
-                                       for (std::vector<CString>::iterator it = toremove.begin(); it != toremove.end(); ++it)\r
+                                       if (bSuccess)\r
                                        {\r
-                                               int nListboxEntries = GetItemCount();\r
-                                               for (int i=0; i<nListboxEntries; ++i)\r
+                                               // The remove went ok, but we now need to run through the selected items again\r
+                                               // and update their status\r
+                                               POSITION pos = GetFirstSelectedItemPosition();\r
+                                               int index;\r
+                                               std::vector<int> entriesToRemove;\r
+                                               while ((index = GetNextSelectedItem(pos)) >= 0)\r
                                                {\r
-                                                       if (GetListEntry(i)->path.GetSVNPathString().Compare(*it)==0)\r
+                                                       FileEntry * e = GetListEntry(index);\r
+                                                       if (!bShift &&\r
+                                                               ((e->textstatus == git_wc_status_unversioned)||\r
+                                                               (e->textstatus == git_wc_status_none)||\r
+                                                               (e->textstatus == git_wc_status_ignored)))\r
                                                        {\r
-                                                               RemoveListEntry(i);\r
-                                                               break;\r
+                                                               if (GetCheck(index))\r
+                                                                       m_nSelected--;\r
+                                                               m_nTotal--;\r
+                                                               entriesToRemove.push_back(index);\r
+                                                       }\r
+                                                       else\r
+                                                       {\r
+                                                               e->textstatus = git_wc_status_deleted;\r
+                                                               e->status = git_wc_status_deleted;\r
+                                                               SetEntryCheck(e,index,true);\r
                                                        }\r
                                                }\r
+                                               for (std::vector<int>::reverse_iterator it = entriesToRemove.rbegin(); it != entriesToRemove.rend(); ++it)\r
+                                               {\r
+                                                       RemoveListEntry(*it);\r
+                                               }\r
                                        }\r
-                                       SetRedraw(TRUE);\r
+                                       SaveColumnWidths();\r
+                                       Show(m_dwShow, 0, m_bShowFolders);\r
+                                       NotifyCheck();\r
                                }\r
                                break;\r
-                       case IDSVNLC_EDITCONFLICT:\r
-                               SVNDiff::StartConflictEditor(filepath);\r
-                               break;\r
-                       case IDSVNLC_RESOLVECONFLICT:\r
-                       case IDSVNLC_RESOLVEMINE:\r
-                       case IDSVNLC_RESOLVETHEIRS:\r
+                       case IDSVNLC_DELETE:\r
                                {\r
-                                       git_wc_conflict_choice_t result = git_wc_conflict_choose_merged;\r
-                                       switch (cmd)\r
+                                       CTSVNPathList pathlist;\r
+                                       FillListOfSelectedItemPaths(pathlist);\r
+                                       pathlist.RemoveChildren();\r
+                                       CString filelist;\r
+                                       for (INT_PTR i=0; i<pathlist.GetCount(); ++i)\r
                                        {\r
-                                       case IDSVNLC_RESOLVETHEIRS:\r
-                                               result = git_wc_conflict_choose_theirs_full;\r
-                                               break;\r
-                                       case IDSVNLC_RESOLVEMINE:\r
-                                               result = git_wc_conflict_choose_mine_full;\r
-                                               break;\r
-                                       case IDSVNLC_RESOLVECONFLICT:\r
-                                               result = git_wc_conflict_choose_merged;\r
-                                               break;\r
+                                               filelist += pathlist[i].GetWinPathString();\r
+                                               filelist += _T("|");\r
                                        }\r
-                                       if (CMessageBox::Show(m_hWnd, IDS_PROC_RESOLVE, IDS_APPNAME, MB_ICONQUESTION | MB_YESNO)==IDYES)\r
+                                       filelist += _T("|");\r
+                                       int len = filelist.GetLength();\r
+                                       TCHAR * buf = new TCHAR[len+2];\r
+                                       _tcscpy_s(buf, len+2, filelist);\r
+                                       for (int i=0; i<len; ++i)\r
+                                               if (buf[i] == '|')\r
+                                                       buf[i] = 0;\r
+                                       SHFILEOPSTRUCT fileop;\r
+                                       fileop.hwnd = this->m_hWnd;\r
+                                       fileop.wFunc = FO_DELETE;\r
+                                       fileop.pFrom = buf;\r
+                                       fileop.pTo = NULL;\r
+                                       fileop.fFlags = FOF_NO_CONNECTED_ELEMENTS | ((GetAsyncKeyState(VK_SHIFT) & 0x8000) ? 0 : FOF_ALLOWUNDO);\r
+                                       fileop.lpszProgressTitle = _T("deleting file");\r
+                                       int result = SHFileOperation(&fileop);\r
+                                       delete [] buf;\r
+\r
+                                       if ( (result==0) && (!fileop.fAnyOperationsAborted) )\r
                                        {\r
-                                               SVN git;\r
-                                               POSITION pos = GetFirstSelectedItemPosition();\r
-                                               while (pos != 0)\r
+                                               SetRedraw(FALSE);\r
+                                               POSITION pos = NULL;\r
+                                               CTSVNPathList deletedlist;      // to store list of deleted folders\r
+                                               while ((pos = GetFirstSelectedItemPosition()) != 0)\r
                                                {\r
-                                                       int index;\r
-                                                       index = GetNextSelectedItem(pos);\r
-                                                       FileEntry * fentry = m_arStatusArray[m_arListArray[index]];\r
-                                                       if (!git.Resolve(fentry->GetPath(), result, FALSE))\r
-                                                       {\r
-                                                               CMessageBox::Show(m_hWnd, git.GetLastErrorMessage(), _T("TortoiseSVN"), MB_ICONERROR);\r
-                                                       }\r
-                                                       else\r
+                                                       int index = GetNextSelectedItem(pos);\r
+                                                       if (GetCheck(index))\r
+                                                               m_nSelected--;\r
+                                                       m_nTotal--;\r
+                                                       FileEntry * fentry = GetListEntry(index);\r
+                                                       if ((fentry)&&(fentry->isfolder))\r
+                                                               deletedlist.AddPath(fentry->path);\r
+                                                       RemoveListEntry(index);\r
+                                               }\r
+                                               // now go through the list of deleted folders\r
+                                               // and remove all their children from the list too!\r
+                                               int nListboxEntries = GetItemCount();\r
+                                               for (int folderindex = 0; folderindex < deletedlist.GetCount(); ++folderindex)\r
+                                               {\r
+                                                       CTSVNPath folderpath = deletedlist[folderindex];\r
+                                                       for (int i=0; i<nListboxEntries; ++i)\r
                                                        {\r
-                                                               fentry->status = git_wc_status_modified;\r
-                                                               fentry->textstatus = git_wc_status_modified;\r
-                                                               fentry->isConflicted = false;\r
+                                                               FileEntry * entry = GetListEntry(i);\r
+                                                               if (folderpath.IsAncestorOf(entry->path))\r
+                                                               {\r
+                                                                       RemoveListEntry(i--);\r
+                                                                       nListboxEntries--;\r
+                                                               }\r
                                                        }\r
                                                }\r
-                                               Show(m_dwShow, 0, m_bShowFolders);\r
+                                               SetRedraw(TRUE);\r
                                        }\r
                                }\r
                                break;\r
+\r
+\r
                        case IDSVNLC_ADD:\r
                                {\r
                                        SVN git;\r
@@ -3612,55 +3524,7 @@ void CGitStatusListCtrl::OnContextMenuList(CWnd * pWnd, CPoint point)
                                        }\r
                                }\r
                                break;\r
-                       case IDSVNLC_LOCK:\r
-                               {\r
-                                       CTSVNPathList itemsToLock;\r
-                                       FillListOfSelectedItemPaths(itemsToLock);\r
-                                       CInputDlg inpDlg;\r
-                                       inpDlg.m_sTitle.LoadString(IDS_MENU_LOCK);\r
-                                       CStringUtils::RemoveAccelerators(inpDlg.m_sTitle);\r
-                                       inpDlg.m_sHintText.LoadString(IDS_LOCK_MESSAGEHINT);\r
-                                       inpDlg.m_sCheckText.LoadString(IDS_LOCK_STEALCHECK);\r
-                                       ProjectProperties props;\r
-                                       props.ReadPropsPathList(itemsToLock);\r
-                                       props.nMinLogSize = 0;          // the lock message is optional, so no minimum!\r
-                                       inpDlg.m_pProjectProperties = &props;\r
-                                       if (inpDlg.DoModal()==IDOK)\r
-                                       {\r
-                                               CSVNProgressDlg progDlg;\r
-                                               progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Lock);\r
-                                               progDlg.SetOptions(inpDlg.m_iCheck ? ProgOptLockForce : ProgOptNone);\r
-                                               progDlg.SetPathList(itemsToLock);\r
-                                               progDlg.SetCommitMessage(inpDlg.m_sInputText);\r
-                                               progDlg.DoModal();\r
-                                               // refresh!\r
-                                               CWnd* pParent = GetParent();\r
-                                               if (NULL != pParent && NULL != pParent->GetSafeHwnd())\r
-                                               {\r
-                                                       pParent->SendMessage(SVNSLNM_NEEDSREFRESH);\r
-                                               }\r
-                                       }\r
-                               }\r
-                               break;\r
-                       case IDSVNLC_UNLOCKFORCE:\r
-                               bForce = true;\r
-                       case IDSVNLC_UNLOCK:\r
-                               {\r
-                                       CTSVNPathList itemsToUnlock;\r
-                                       FillListOfSelectedItemPaths(itemsToUnlock);\r
-                                       CSVNProgressDlg progDlg;\r
-                                       progDlg.SetCommand(CSVNProgressDlg::SVNProgress_Unlock);\r
-                                       progDlg.SetOptions(bForce ? ProgOptLockForce : ProgOptNone);\r
-                                       progDlg.SetPathList(itemsToUnlock);\r
-                                       progDlg.DoModal();\r
-                                       // refresh!\r
-                                       CWnd* pParent = GetParent();\r
-                                       if (NULL != pParent && NULL != pParent->GetSafeHwnd())\r
-                                       {\r
-                                               pParent->SendMessage(SVNSLNM_NEEDSREFRESH);\r
-                                       }\r
-                               }\r
-                               break;\r
+\r
                        case IDSVNLC_REPAIRMOVE:\r
                                {\r
                                        POSITION pos = GetFirstSelectedItemPosition();\r
@@ -4106,10 +3970,21 @@ void CGitStatusListCtrl::StartDiff(int fileindex)
 {\r
        if(fileindex<0)\r
                return;\r
+\r
+       CTGitPath file1=*(CTGitPath*)GetItemData(fileindex);\r
+       CTGitPath file2;\r
+       if(file1.m_Action & (CTGitPath::LOGACTIONS_REPLACED|CTGitPath::LOGACTIONS_COPY))\r
+       {\r
+               file2.SetFromGit(file1.GetGitOldPathString());\r
+       }else\r
+       {\r
+               file2=file1;\r
+       }\r
+\r
        if(this->m_CurrentVersion.IsEmpty() || m_CurrentVersion== GIT_REV_ZERO)\r
        {\r
                if(!g_Git.IsInitRepos())\r
-                       CGitDiff::Diff((CTGitPath*)GetItemData(fileindex),\r
+                       CGitDiff::Diff(&file1,&file2,\r
                                CString(GIT_REV_ZERO),\r
                                        GitRev::GetHead());\r
                else\r
@@ -4117,7 +3992,7 @@ void CGitStatusListCtrl::StartDiff(int fileindex)
                                CString(GIT_REV_ZERO));\r
        }else\r
        {\r
-               CGitDiff::Diff((CTGitPath*)GetItemData(fileindex),\r
+               CGitDiff::Diff(&file1,&file2,\r
                                m_CurrentVersion,\r
                                        m_CurrentVersion+_T("~1"));\r
        }\r
@@ -4203,20 +4078,25 @@ CString CGitStatusListCtrl::GetStatisticsString()
 \r
 }\r
 \r
-CTGitPath CGitStatusListCtrl::GetCommonDirectory(bool bStrict)\r
+CString CGitStatusListCtrl::GetCommonDirectory(bool bStrict)\r
 {\r
        if (!bStrict)\r
        {\r
                // not strict means that the selected folder has priority\r
                if (!m_StatusFileList.GetCommonDirectory().IsEmpty())\r
-                       return m_StatusFileList.GetCommonDirectory();\r
+                       return m_StatusFileList.GetCommonDirectory().GetWinPath();\r
        }\r
 \r
        CTGitPath commonBaseDirectory;\r
        int nListItems = GetItemCount();\r
        for (int i=0; i<nListItems; ++i)\r
        {\r
-               CTGitPath& baseDirectory = *(CTGitPath*)this->GetItemData(i);\r
+               CTGitPath baseDirectory,*p= (CTGitPath*)this->GetItemData(i);\r
+               ASSERT(p);\r
+               if(p==NULL)\r
+                       continue;\r
+               baseDirectory = p->GetDirectory();\r
+\r
                if(commonBaseDirectory.IsEmpty())\r
                {\r
                        commonBaseDirectory = baseDirectory;\r
@@ -4230,7 +4110,7 @@ CTGitPath CGitStatusListCtrl::GetCommonDirectory(bool bStrict)
                        }\r
                }\r
        }\r
-       return commonBaseDirectory;\r
+       return g_Git.m_CurrentDir+CString(_T("\\"))+commonBaseDirectory.GetWinPath();\r
 }\r
 \r
 CTGitPath CGitStatusListCtrl::GetCommonURL(bool bStrict)\r
@@ -4363,15 +4243,19 @@ void CGitStatusListCtrl::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
                                // brown  : missing, deleted, replaced\r
                                // green  : merged (or potential merges)\r
                                // red    : conflicts or sure conflicts\r
-                               if(entry->m_Action & CTGitPath::LOGACTIONS_CONFLICT)\r
+                               if(entry->m_Action & CTGitPath::LOGACTIONS_GRAY)\r
+                               {\r
+                                       crText = RGB(128,128,128);\r
+\r
+                               }else if(entry->m_Action & CTGitPath::LOGACTIONS_UNMERGED)\r
                                {\r
                                        crText = m_Colors.GetColor(CColors::Conflict);\r
 \r
-                               }else if(entry->m_Action & CTGitPath::LOGACTIONS_MODIFIED)\r
+                               }else if(entry->m_Action & (CTGitPath::LOGACTIONS_MODIFIED))\r
                                {\r
                                        crText = m_Colors.GetColor(CColors::Modified);\r
 \r
-                               }else if(entry->m_Action & CTGitPath::LOGACTIONS_ADDED)\r
+                               }else if(entry->m_Action & (CTGitPath::LOGACTIONS_ADDED|CTGitPath::LOGACTIONS_COPY))\r
                                {\r
                                        crText = m_Colors.GetColor(CColors::Added);\r
                                }\r
@@ -4411,9 +4295,13 @@ BOOL CGitStatusListCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
 \r
 void CGitStatusListCtrl::RemoveListEntry(int index)\r
 {\r
-#if 0\r
+\r
        Locker lock(m_critSec);\r
        DeleteItem(index);\r
+\r
+       m_arStatusArray.erase(m_arStatusArray.begin()+index);\r
+\r
+#if 0\r
        delete m_arStatusArray[m_arListArray[index]];\r
        m_arStatusArray.erase(m_arStatusArray.begin()+m_arListArray[index]);\r
        m_arListArray.erase(m_arListArray.begin()+index);\r
@@ -4465,20 +4353,20 @@ void CGitStatusListCtrl::SetCheckOnAllDescendentsOf(const FileEntry* parentEntry
 \r
 void CGitStatusListCtrl::WriteCheckedNamesToPathList(CTGitPathList& pathList)\r
 {\r
-#if 0\r
+\r
        pathList.Clear();\r
        int nListItems = GetItemCount();\r
        for (int i=0; i< nListItems; i++)\r
        {\r
-               const FileEntry* entry = GetListEntry(i);\r
+               CTGitPath * entry = (CTGitPath*)GetItemData(i);\r
                ASSERT(entry != NULL);\r
-               if (entry->IsChecked())\r
+               if (entry->m_Checked)\r
                {\r
-                       pathList.AddPath(entry->path);\r
+                       pathList.AddPath(*entry);\r
                }\r
        }\r
        pathList.SortByPathname();\r
-#endif\r
+\r
 }\r
 \r
 \r
@@ -5183,7 +5071,7 @@ bool CGitStatusListCtrl::PrepareGroups(bool bForce /* = false */)
        TCHAR groupname[1024];\r
        int groupindex = 0;\r
 \r
-       if(bHasGroups);\r
+       if(bHasGroups)\r
        {\r
                LVGROUP grp = {0};\r
                grp.cbSize = sizeof(LVGROUP);\r
@@ -5215,7 +5103,7 @@ bool CGitStatusListCtrl::PrepareGroups(bool bForce /* = false */)
 \r
        }\r
 \r
-\r
+#if 0\r
        m_bHasIgnoreGroup = false;\r
 \r
        // now add the items which don't belong to a group\r
@@ -5261,7 +5149,7 @@ bool CGitStatusListCtrl::PrepareGroups(bool bForce /* = false */)
                        it->second = InsertGroup(groupindex, &grp);\r
                }\r
        }\r
-\r
+#endif\r
        return bHasGroups;\r
 }\r
 \r
@@ -5276,48 +5164,103 @@ void CGitStatusListCtrl::NotifyCheck()
 \r
 int CGitStatusListCtrl::UpdateFileList(git_revnum_t hash,CTGitPathList *list)\r
 {\r
-       CString out;\r
+       BYTE_VECTOR out;\r
        this->m_bBusy=TRUE;\r
        m_CurrentVersion=hash;\r
 \r
+       int count = 0;\r
+       if(list == NULL)\r
+               count = 1;\r
+       else\r
+               count = list->GetCount();\r
+\r
        if(hash == GIT_REV_ZERO)\r
        {\r
-               int count = 0;\r
-               if(list == NULL)\r
-                       count = 1;\r
-               else\r
-                       count = list->GetCount();\r
-\r
                for(int i=0;i<count;i++)\r
                {       \r
-                       CString cmdout;\r
+                       BYTE_VECTOR cmdout;\r
+                       cmdout.clear();\r
                        CString cmd;\r
-                       if(list == NULL)\r
-                               cmd=(_T("git.exe diff-index --raw HEAD --numstat -C -M"));\r
-                       else\r
-                               cmd.Format(_T("git.exe diff-index --raw HEAD --numstat -C -M -- \"%s\""),(*list)[i].GetGitPathString());\r
-\r
-                       if(g_Git.Run(cmd,&cmdout))\r
+                       if(!g_Git.IsInitRepos())\r
                        {\r
-                               cmdout.Empty();\r
-                               if(g_Git.Run(_T("git.exe rev-parse --revs-only HEAD"),&cmdout))\r
+                               if(list == NULL)\r
+                                       cmd=(_T("git.exe diff-index --raw HEAD --numstat -C -M -z"));\r
+                               else\r
+                                       cmd.Format(_T("git.exe diff-index  --raw HEAD --numstat -C -M -z -- \"%s\""),(*list)[i].GetGitPathString());\r
+       \r
+                               if(g_Git.Run(cmd,&cmdout))\r
                                {\r
-                                       CMessageBox::Show(NULL,cmdout,_T("TortoiseGit"),MB_OK);\r
+                                       cmdout.clear();\r
+                                       CString strout;\r
+                                       if(g_Git.Run(_T("git.exe rev-parse --revs-only HEAD"),&strout,CP_UTF8))\r
+                                       {\r
+                                               CMessageBox::Show(NULL,strout,_T("TortoiseGit"),MB_OK);\r
+                                               return -1;\r
+                                       }\r
+                                       if(strout.IsEmpty())\r
+                                               break; //this is initial repositoyr, there are no any history\r
+\r
+                                       CMessageBox::Show(NULL,strout,_T("TortoiseGit"),MB_OK);\r
                                        return -1;\r
+\r
                                }\r
-                               if(cmdout.IsEmpty())\r
-                                       break; //this is initial repositoyr, there are no any history\r
+                               \r
+                               if(list == NULL)\r
+                                       cmd=(_T("git.exe diff-index --cached --raw HEAD --numstat -C -M -z"));\r
+                               else\r
+                                       cmd.Format(_T("git.exe diff-index  --cached --raw HEAD --numstat -C -M -z -- \"%s\""),(*list)[i].GetGitPathString());\r
 \r
-                               CMessageBox::Show(NULL,cmdout,_T("TortoiseGit"),MB_OK);\r
-                               return -1;\r
+                               g_Git.Run(cmd,&cmdout);\r
+                               //out+=cmdout;\r
+                               out.append(cmdout,0);\r
+                       }\r
+                       else // Init Repository\r
+                       {\r
+                               if(list == NULL)\r
+                                       cmd=_T("git.exe ls-files -s -t -z");\r
+                               else\r
+                                       cmd.Format(_T("git.exe ls-files -s -t -z -- \"%s\""),(*list)[i].GetGitPathString());\r
 \r
+                               g_Git.Run(cmd,&cmdout);\r
+                               //out+=cmdout;\r
+                               out.append(cmdout,0);\r
                        }\r
+               }\r
 \r
-                       out+=cmdout;\r
+               if(g_Git.IsInitRepos())\r
+               {\r
+                       m_StatusFileList.ParserFromLsFile(out);\r
+                       for(int i=0;i<m_StatusFileList.GetCount();i++)\r
+                               ((CTGitPath&)(m_StatusFileList[i])).m_Action=CTGitPath::LOGACTIONS_ADDED;\r
                }\r
+               else\r
+                       this->m_StatusFileList.ParserFromLog(out);\r
+\r
+               //handle delete conflict case, when remote : modified, local : deleted. \r
+               for(int i=0;i<count;i++)\r
+               {       \r
+                       BYTE_VECTOR cmdout;\r
+                       CString cmd;\r
 \r
+                       if(list == NULL)\r
+                               cmd=_T("git.exe ls-files -u -t -z");\r
+                       else\r
+                               cmd.Format(_T("git.exe ls-files -u -t -z -- \"%s\""),(*list)[i].GetGitPathString());\r
+\r
+                       g_Git.Run(cmd,&cmdout);\r
+\r
+                       CTGitPathList conflictlist;\r
+                       conflictlist.ParserFromLog(cmdout);\r
+                       for(int i=0;i<conflictlist.GetCount();i++)\r
+                       {\r
+                               CTGitPath *p=m_StatusFileList.LookForGitPath(conflictlist[i].GetGitPathString());\r
+                               if(p)\r
+                                       p->m_Action|=CTGitPath::LOGACTIONS_UNMERGED;\r
+                               else\r
+                                       m_StatusFileList.AddPath(conflictlist[i]);\r
+                       }       \r
+               }\r
 \r
-               this->m_StatusFileList.ParserFromLog(out);\r
        }else\r
        {\r
                int count = 0;\r
@@ -5328,26 +5271,28 @@ int CGitStatusListCtrl::UpdateFileList(git_revnum_t hash,CTGitPathList *list)
 \r
                for(int i=0;i<count;i++)\r
                {       \r
-                       CString cmdout;\r
+                       BYTE_VECTOR cmdout;\r
                        CString cmd;\r
                        if(list == NULL)\r
-                               cmd.Format(_T("git.exe diff-tree --raw --numstat -C -M %s"),hash);\r
+                               cmd.Format(_T("git.exe diff-tree --raw --numstat -C -M -z %s"),hash);\r
                        else\r
-                               cmd.Format(_T("git.exe diff-tree --raw  --numstat -C -M %s -- \"%s\""),hash,(*list)[i].GetGitPathString());\r
+                               cmd.Format(_T("git.exe diff-tree --raw  --numstat -C -M %s -z -- \"%s\""),hash,(*list)[i].GetGitPathString());\r
 \r
                        g_Git.Run(cmd,&cmdout);\r
 \r
-                       out+=cmdout;\r
+                       out.append(cmdout);\r
                }\r
                this->m_StatusFileList.ParserFromLog(out);\r
 \r
        }\r
+       \r
        for(int i=0;i<m_StatusFileList.GetCount();i++)\r
        {\r
                CTGitPath * gitpatch=(CTGitPath*)&m_StatusFileList[i];\r
                gitpatch->m_Checked = TRUE;\r
                m_arStatusArray.push_back((CTGitPath*)&m_StatusFileList[i]);\r
        }\r
+\r
        this->m_bBusy=FALSE;\r
        return 0;\r
 }\r
@@ -5357,8 +5302,12 @@ int CGitStatusListCtrl::UpdateWithGitPathList(CTGitPathList &list)
        m_arStatusArray.clear();\r
        for(int i=0;i<list.GetCount();i++)\r
        {\r
-               CTGitPath * gitpatch=(CTGitPath*)&list[i];\r
-               gitpatch->m_Checked = TRUE;\r
+               CTGitPath * gitpath=(CTGitPath*)&list[i];\r
+               \r
+               if(gitpath ->m_Action & CTGitPath::LOGACTIONS_HIDE)\r
+                       continue;\r
+\r
+               gitpath->m_Checked = TRUE;\r
                m_arStatusArray.push_back((CTGitPath*)&list[i]);\r
        }\r
        return 0;\r
@@ -5407,6 +5356,15 @@ int CGitStatusListCtrl::UpdateFileList(int mask,bool once,CTGitPathList *List)
        }\r
        return 0;\r
 }\r
+\r
+void CGitStatusListCtrl::Clear()\r
+{\r
+       m_FileLoaded=0;\r
+       this->DeleteAllItems();\r
+       this->m_arListArray.clear();\r
+       this->m_arStatusArray.clear();\r
+       this->m_changelists.clear();\r
+}\r
 //////////////////////////////////////////////////////////////////////////\r
 #if 0\r
 bool CGitStatusListCtrlDropTarget::OnDrop(FORMATETC* pFmtEtc, STGMEDIUM& medium, DWORD * /*pdwEffect*/, POINTL pt)\r
@@ -5542,4 +5500,66 @@ HRESULT STDMETHODCALLTYPE CSVNStatusListCtrlDropTarget::DragOver(DWORD grfKeySta
        return S_OK;\r
 }f\r
 \r
-#endif
\ No newline at end of file
+#endif\r
+\r
+void CGitStatusListCtrl::FileSaveAs(CTGitPath *path)\r
+{\r
+       CString filename;\r
+       filename.Format(_T("%s-%s%s"),path->GetBaseFilename(),this->m_CurrentVersion.Left(6),path->GetFileExtension());\r
+       CFileDialog dlg(FALSE,NULL,\r
+                                       filename,               \r
+                                       OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,\r
+                                       NULL);\r
+       CString currentpath;\r
+       currentpath=g_Git.m_CurrentDir+_T("\\");\r
+       currentpath+=path->GetWinPathString();\r
+\r
+       dlg.m_ofn.lpstrInitialDir=currentpath.GetBuffer();\r
+\r
+       CString cmd,out;                \r
+       if(dlg.DoModal()==IDOK)\r
+       {\r
+               filename = dlg.GetFileName();\r
+               if(m_CurrentVersion == GIT_REV_ZERO)\r
+               {\r
+                       cmd.Format(_T("copy /Y \"%s\" \"%s\""),path->GetWinPath(),filename);\r
+                       if(g_Git.Run(cmd,&out,CP_ACP))\r
+                       {\r
+                               CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK);\r
+                               return;\r
+                       }\r
+\r
+               }else\r
+               {\r
+                       cmd.Format(_T("git.exe cat-file -p %s:\"%s\""),m_CurrentVersion,path->GetGitPathString());\r
+                       if(g_Git.RunLogFile(cmd,filename))\r
+                       {\r
+                               CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK);\r
+                               return;\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
+\r
+int CGitStatusListCtrl::RevertSelectedItemToVersion()\r
+{\r
+       if(this->m_CurrentVersion.IsEmpty())\r
+               return 0;\r
+       if(this->m_CurrentVersion == GIT_REV_ZERO)\r
+               return 0;\r
+\r
+       POSITION pos = GetFirstSelectedItemPosition();\r
+       int index;\r
+       CString cmd,out;\r
+       while ((index = GetNextSelectedItem(pos)) >= 0)\r
+       {\r
+               CTGitPath *fentry=(CTGitPath*)GetItemData(index);\r
+               cmd.Format(_T("git.exe checkout %s -- \"%s\""),m_CurrentVersion,fentry->GetGitPathString());\r
+               out.Empty();\r
+               if(g_Git.Run(cmd,&out,CP_ACP))\r
+               {\r
+                       CMessageBox::Show(NULL,out,_T("TortoiseGit"),MB_OK);\r
+               }\r
+       }       \r
+}
\ No newline at end of file