}\r
}\r
\r
-bool CBrowseRefsDlg::ConfirmDeleteRef(CString completeRefName)\r
+bool CBrowseRefsDlg::ConfirmDeleteRef(VectorPShadowTree& leafs)\r
{\r
+ ASSERT(!leafs.empty());\r
+\r
CString csMessage;\r
CString csTitle;\r
\r
UINT mbIcon=MB_ICONQUESTION;\r
- csMessage = L"Are you sure you want to delete the ";\r
+ csMessage = L"Are you sure you want to delete ";\r
\r
bool bIsRemoteBranch = false;\r
bool bIsBranch = false;\r
- if (wcsncmp(completeRefName, L"refs/remotes",12)==0) {bIsBranch = true; bIsRemoteBranch = true;}\r
- else if (wcsncmp(completeRefName, L"refs/heads",10)==0) {bIsBranch = true;}\r
+ if (leafs[0]->IsFrom(L"refs/remotes")) {bIsBranch = true; bIsRemoteBranch = true;}\r
+ else if (leafs[0]->IsFrom(L"refs/heads")) {bIsBranch = true;}\r
\r
if(bIsBranch)\r
{\r
- CString branchToDelete = completeRefName.Mid(bIsRemoteBranch ? 13 : 11);\r
- csTitle.Format(L"Confirm deletion of %sbranch %s", \r
- bIsRemoteBranch? L"remote ": L"", \r
- branchToDelete);\r
- if(bIsRemoteBranch)\r
- csMessage += L"<ct=0x0000FF><i>remote</i></ct> "; \r
- csMessage += L"branch:\r\n\r\n<b>";\r
- csMessage += branchToDelete;\r
- csMessage += L"</b>";\r
-\r
- //Check if branch is fully merged in HEAD\r
- CString branchHash = g_Git.GetHash(completeRefName);\r
- CString commonAncestor;\r
- CString cmd;\r
- cmd.Format(L"git.exe merge-base HEAD %s",completeRefName);\r
- g_Git.Run(cmd,&commonAncestor,CP_UTF8);\r
-\r
- branchHash=branchHash.Left(40);\r
- commonAncestor=commonAncestor.Left(40);\r
- \r
- if(commonAncestor != branchHash)\r
+ if(leafs.size() == 1)\r
{\r
- csMessage += L"\r\n\r\n<b>Warning:\r\nThis branch is not fully merged into HEAD.</b>";\r
- mbIcon = MB_ICONWARNING;\r
+ CString branchToDelete = leafs[0]->GetRefName().Mid(bIsRemoteBranch ? 13 : 11);\r
+ csTitle.Format(L"Confirm deletion of %sbranch %s", \r
+ bIsRemoteBranch? L"remote ": L"", \r
+ branchToDelete);\r
+\r
+ csMessage += "the ";\r
+ if(bIsRemoteBranch)\r
+ csMessage += L"<ct=0x0000FF><i>remote</i></ct> "; \r
+ csMessage += L"branch:\r\n\r\n<b>";\r
+ csMessage += branchToDelete;\r
+ csMessage += L"</b>";\r
+\r
+ //Check if branch is fully merged in HEAD\r
+ CString branchHash = g_Git.GetHash(leafs[0]->GetRefName());\r
+ CString commonAncestor;\r
+ CString cmd;\r
+ cmd.Format(L"git.exe merge-base HEAD %s", leafs[0]->GetRefName());\r
+ g_Git.Run(cmd,&commonAncestor,CP_UTF8);\r
+\r
+ branchHash=branchHash.Left(40);\r
+ commonAncestor=commonAncestor.Left(40);\r
+ \r
+ if(commonAncestor != branchHash)\r
+ {\r
+ csMessage += L"\r\n\r\n<b>Warning:\r\nThis branch is not fully merged into HEAD.</b>";\r
+ mbIcon = MB_ICONWARNING;\r
+ }\r
+ if(bIsRemoteBranch)\r
+ {\r
+ csMessage += L"\r\n\r\n<b>Warning:\r\nThis action will remove the branch on the remote.</b>";\r
+ mbIcon = MB_ICONWARNING;\r
+ }\r
}\r
- if(bIsRemoteBranch)\r
+ else\r
{\r
- csMessage += L"\r\n\r\n<b>Warning:\r\nThis action will remove the branch on the remote.</b>";\r
+ csTitle.Format(L"Confirm deletion of %d %sbranches",\r
+ leafs.size(),\r
+ bIsRemoteBranch? L"remote ": L"");\r
+\r
+ CString csMoreMsgText;\r
+ csMoreMsgText.Format(L"<b>%d</b> ", leafs.size());\r
+ csMessage += csMoreMsgText;\r
+ if(bIsRemoteBranch)\r
+ csMessage += L"<ct=0x0000FF><i>remote</i></ct> "; \r
+ csMessage += L"branches";\r
+\r
+ csMessage += L"\r\n\r\n<b>Warning:\r\nIt has not been checked if these branches have been fully merged into HEAD.</b>";\r
mbIcon = MB_ICONWARNING;\r
+\r
+ if(bIsRemoteBranch)\r
+ {\r
+ csMessage += L"\r\n\r\n<b>Warning:\r\nThis action will remove the branches on the remote.</b>";\r
+ mbIcon = MB_ICONWARNING;\r
+ }\r
}\r
+\r
}\r
- else if(wcsncmp(completeRefName,L"refs/tags",9)==0)\r
+ else if(leafs[0]->IsFrom(L"refs/tags"))\r
{\r
- CString tagToDelete = completeRefName.Mid(10);\r
- csTitle.Format(L"Confirm deletion of tag %s", tagToDelete);\r
- csMessage += "tag:\r\n\r\n<b>";\r
- csMessage += tagToDelete;\r
- csMessage += "</b>";\r
+ if(leafs.size() == 1)\r
+ {\r
+ CString tagToDelete = leafs[0]->GetRefName().Mid(10);\r
+ csTitle.Format(L"Confirm deletion of tag %s", tagToDelete);\r
+ csMessage += "the tag:\r\n\r\n<b>";\r
+ csMessage += tagToDelete;\r
+ csMessage += "</b>";\r
+ }\r
+ else\r
+ {\r
+ CString tagToDelete = leafs[0]->GetRefName().Mid(10);\r
+ csTitle.Format(L"Confirm deletion of %d tags", leafs.size());\r
+ CString csMoreMsgText;\r
+ csMoreMsgText.Format(L"<b>%d</b> ", leafs.size());\r
+ csMessage += csMoreMsgText;\r
+ csMessage += L"tags";\r
+ }\r
}\r
\r
return CMessageBox::Show(m_hWnd,csMessage,csTitle,MB_YESNO|mbIcon)==IDYES;\r
\r
}\r
\r
+bool CBrowseRefsDlg::DoDeleteRefs(VectorPShadowTree& leafs, bool bForce)\r
+{\r
+ for(VectorPShadowTree::iterator i = leafs.begin(); i != leafs.end(); ++i)\r
+ if(!DoDeleteRef((*i)->GetRefName(), bForce))\r
+ return false;\r
+ return true;\r
+}\r
\r
bool CBrowseRefsDlg::DoDeleteRef(CString completeRefName, bool bForce)\r
{\r
bAddSeparator = true;\r
\r
bool bShowReflogOption = false;\r
- bool bShowDeleteBranchOption = false;\r
- bool bShowDeleteTagOption = false;\r
- bool bShowDeleteRemoteBranchOption = false;\r
bool bShowFetchOption = false;\r
bool bShowSwitchOption = false;\r
\r
if(selectedLeafs[0]->IsFrom(L"refs/heads"))\r
{\r
bShowReflogOption = true;\r
- bShowDeleteBranchOption = true;\r
bShowSwitchOption = true;\r
}\r
else if(selectedLeafs[0]->IsFrom(L"refs/remotes"))\r
{\r
bShowReflogOption = true;\r
- bShowDeleteRemoteBranchOption = true;\r
bShowFetchOption = true;\r
\r
int dummy = 0;//Needed for tokenize\r
}\r
else if(selectedLeafs[0]->IsFrom(L"refs/tags"))\r
{\r
- bShowDeleteTagOption = true;\r
}\r
\r
popupMenu.AppendMenuIcon(eCmd_ViewLog, L"Show Log", IDI_LOG);\r
if(bShowReflogOption) popupMenu.AppendMenuIcon(eCmd_ShowReflog, L"Show Reflog", IDI_LOG);\r
if(bShowFetchOption) popupMenu.AppendMenuIcon(eCmd_Fetch, fetchFromCmd, IDI_PULL);\r
if(bShowSwitchOption) popupMenu.AppendMenuIcon(eCmd_Switch, L"Switch to this Ref", IDI_SWITCH);\r
- if(bShowDeleteTagOption) popupMenu.AppendMenuIcon(eCmd_DeleteTag, L"Delete Tag", IDI_DELETE);\r
- if(bShowDeleteBranchOption) popupMenu.AppendMenuIcon(eCmd_DeleteBranch, L"Delete Branch", IDI_DELETE);\r
- if(bShowDeleteRemoteBranchOption) popupMenu.AppendMenuIcon(eCmd_DeleteRemoteBranch, L"Delete Remote Branch", IDI_DELETE);\r
-\r
-\r
-\r
-// CShadowTree* pTree = (CShadowTree*)m_ListRefLeafs.GetItemData(pNMHDR->idFrom);\r
-// if(pTree==NULL)\r
-// return;\r
}\r
+\r
else if(selectedLeafs.size() == 2)\r
{\r
bAddSeparator = true;\r
popupMenu.AppendMenuIcon(eCmd_Diff, L"Compare These Refs", IDI_DIFF);\r
}\r
\r
+ if(!selectedLeafs.empty())\r
+ {\r
+ if(AreAllFrom(selectedLeafs, L"refs/remotes/"))\r
+ {\r
+ CString menuItemName;\r
+ if(selectedLeafs.size() == 1)\r
+ menuItemName = L"Delete Remote Branch";\r
+ else\r
+ menuItemName.Format(L"Delete %d Remote Branches", selectedLeafs.size());\r
+\r
+ popupMenu.AppendMenuIcon(eCmd_DeleteRemoteBranch, menuItemName, IDI_DELETE);\r
+ }\r
+\r
+ if(AreAllFrom(selectedLeafs, L"refs/heads/"))\r
+ {\r
+ CString menuItemName;\r
+ if(selectedLeafs.size() == 1)\r
+ menuItemName = L"Delete Branch";\r
+ else\r
+ menuItemName.Format(L"Delete %d Branches", selectedLeafs.size());\r
+\r
+ popupMenu.AppendMenuIcon(eCmd_DeleteBranch, menuItemName, IDI_DELETE);\r
+ }\r
+\r
+ if(AreAllFrom(selectedLeafs, L"refs/tags/"))\r
+ {\r
+ CString menuItemName;\r
+ if(selectedLeafs.size() == 1)\r
+ menuItemName = L"Delete Tag";\r
+ else\r
+ menuItemName.Format(L"Delete %d Tags", selectedLeafs.size());\r
+\r
+ popupMenu.AppendMenuIcon(eCmd_DeleteTag, menuItemName, IDI_DELETE);\r
+ }\r
+ }\r
+\r
if(bAddSeparator) popupMenu.AppendMenu(MF_SEPARATOR);\r
\r
if(hTreePos!=NULL)\r
case eCmd_DeleteBranch:\r
case eCmd_DeleteRemoteBranch:\r
{\r
- if(ConfirmDeleteRef(selectedLeafs[0]->GetRefName()))\r
- DoDeleteRef(selectedLeafs[0]->GetRefName(), true);\r
+ if(ConfirmDeleteRef(selectedLeafs))\r
+ DoDeleteRefs(selectedLeafs, true);\r
Refresh();\r
}\r
break;\r
case eCmd_DeleteTag:\r
{\r
- if(ConfirmDeleteRef(selectedLeafs[0]->GetRefName()))\r
- DoDeleteRef(selectedLeafs[0]->GetRefName(), true);\r
+ if(ConfirmDeleteRef(selectedLeafs))\r
+ DoDeleteRefs(selectedLeafs, true);\r
Refresh();\r
}\r
break;\r
}\r
}\r
\r
+bool CBrowseRefsDlg::AreAllFrom(VectorPShadowTree& leafs, const wchar_t* from)\r
+{\r
+ for(VectorPShadowTree::iterator i = leafs.begin(); i != leafs.end(); ++i)\r
+ if(!(*i)->IsFrom(from))\r
+ return false;\r
+ return true;\r
+}\r
+\r
BOOL CBrowseRefsDlg::PreTranslateMessage(MSG* pMsg)\r
{\r
if (pMsg->message == WM_KEYDOWN)\r