PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/GitUI/GitUICommands.cs

https://github.com/vbjay/gitextensions
C# | 2211 lines | 1756 code | 399 blank | 56 comment | 132 complexity | 96f731809eed289d5d9ef63ea502baf5 MD5 | raw file
Possible License(s): GPL-3.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Windows.Forms;
  7. using GitCommands;
  8. using GitUI.CommandsDialogs;
  9. using GitUI.CommandsDialogs.RepoHosting;
  10. using GitUI.CommandsDialogs.SettingsDialog;
  11. using GitUIPluginInterfaces;
  12. using GitUIPluginInterfaces.RepositoryHosts;
  13. using Gravatar;
  14. using Settings = GitCommands.AppSettings;
  15. namespace GitUI
  16. {
  17. /// <summary>Contains methods to invoke GitEx forms, dialogs, etc.</summary>
  18. public sealed class GitUICommands : IGitUICommands
  19. {
  20. public GitUICommands(GitModule module)
  21. {
  22. Module = module;
  23. RepoChangedNotifier = new ActionNotifier(
  24. () => InvokeEvent(null, PostRepositoryChanged));
  25. }
  26. public GitUICommands(string workingDir)
  27. : this(new GitModule(workingDir)) { }
  28. #region IGitUICommands Members
  29. public event GitUIEventHandler PreBrowse;
  30. public event GitUIEventHandler PostBrowse;
  31. public event GitUIEventHandler PreDeleteBranch;
  32. public event GitUIPostActionEventHandler PostDeleteBranch;
  33. public event GitUIEventHandler PreCheckoutRevision;
  34. public event GitUIPostActionEventHandler PostCheckoutRevision;
  35. public event GitUIEventHandler PreCheckoutBranch;
  36. public event GitUIPostActionEventHandler PostCheckoutBranch;
  37. public event GitUIEventHandler PreFileHistory;
  38. public event GitUIPostActionEventHandler PostFileHistory;
  39. public event GitUIEventHandler PreCompareRevisions;
  40. public event GitUIPostActionEventHandler PostCompareRevisions;
  41. public event GitUIEventHandler PreAddFiles;
  42. public event GitUIPostActionEventHandler PostAddFiles;
  43. public event GitUIEventHandler PreCreateBranch;
  44. public event GitUIPostActionEventHandler PostCreateBranch;
  45. public event GitUIEventHandler PreClone;
  46. public event GitUIPostActionEventHandler PostClone;
  47. public event GitUIEventHandler PreSvnClone;
  48. public event GitUIPostActionEventHandler PostSvnClone;
  49. public event GitUIEventHandler PreCommit;
  50. public event GitUIPostActionEventHandler PostCommit;
  51. public event GitUIEventHandler PreSvnDcommit;
  52. public event GitUIPostActionEventHandler PostSvnDcommit;
  53. public event GitUIEventHandler PreSvnRebase;
  54. public event GitUIPostActionEventHandler PostSvnRebase;
  55. public event GitUIEventHandler PreSvnFetch;
  56. public event GitUIPostActionEventHandler PostSvnFetch;
  57. public event GitUIEventHandler PreInitialize;
  58. public event GitUIPostActionEventHandler PostInitialize;
  59. public event GitUIEventHandler PrePush;
  60. public event GitUIPostActionEventHandler PostPush;
  61. public event GitUIEventHandler PrePull;
  62. public event GitUIPostActionEventHandler PostPull;
  63. public event GitUIEventHandler PreViewPatch;
  64. public event GitUIPostActionEventHandler PostViewPatch;
  65. public event GitUIEventHandler PreApplyPatch;
  66. public event GitUIPostActionEventHandler PostApplyPatch;
  67. public event GitUIEventHandler PreFormatPatch;
  68. public event GitUIPostActionEventHandler PostFormatPatch;
  69. public event GitUIEventHandler PreStash;
  70. public event GitUIPostActionEventHandler PostStash;
  71. public event GitUIEventHandler PreResolveConflicts;
  72. public event GitUIPostActionEventHandler PostResolveConflicts;
  73. public event GitUIEventHandler PreCherryPick;
  74. public event GitUIPostActionEventHandler PostCherryPick;
  75. public event GitUIEventHandler PreRevertCommit;
  76. public event GitUIPostActionEventHandler PostRevertCommit;
  77. public event GitUIEventHandler PreMergeBranch;
  78. public event GitUIPostActionEventHandler PostMergeBranch;
  79. public event GitUIEventHandler PreCreateTag;
  80. public event GitUIPostActionEventHandler PostCreateTag;
  81. public event GitUIEventHandler PreDeleteTag;
  82. public event GitUIPostActionEventHandler PostDeleteTag;
  83. public event GitUIEventHandler PreEditGitIgnore;
  84. public event GitUIPostActionEventHandler PostEditGitIgnore;
  85. public event GitUIEventHandler PreSettings;
  86. public event GitUIPostActionEventHandler PostSettings;
  87. public event GitUIEventHandler PreArchive;
  88. public event GitUIPostActionEventHandler PostArchive;
  89. public event GitUIEventHandler PreMailMap;
  90. public event GitUIPostActionEventHandler PostMailMap;
  91. public event GitUIEventHandler PreVerifyDatabase;
  92. public event GitUIPostActionEventHandler PostVerifyDatabase;
  93. public event GitUIEventHandler PreRemotes;
  94. public event GitUIPostActionEventHandler PostRemotes;
  95. public event GitUIEventHandler PreRebase;
  96. public event GitUIPostActionEventHandler PostRebase;
  97. public event GitUIEventHandler PreRename;
  98. public event GitUIPostActionEventHandler PostRename;
  99. public event GitUIEventHandler PreSubmodulesEdit;
  100. public event GitUIPostActionEventHandler PostSubmodulesEdit;
  101. public event GitUIEventHandler PreUpdateSubmodules;
  102. public event GitUIPostActionEventHandler PostUpdateSubmodules;
  103. public event GitUIEventHandler PreSyncSubmodules;
  104. public event GitUIPostActionEventHandler PostSyncSubmodules;
  105. public event GitUIEventHandler PreBlame;
  106. public event GitUIPostActionEventHandler PostBlame;
  107. public event GitUIEventHandler PreEditGitAttributes;
  108. public event GitUIPostActionEventHandler PostEditGitAttributes;
  109. public event GitUIEventHandler PreBrowseInitialize;
  110. public event GitUIEventHandler PostBrowseInitialize;
  111. /// <summary>
  112. /// listeners for changes being made to repository
  113. /// </summary>
  114. public event GitUIEventHandler PostRepositoryChanged;
  115. public event GitUIEventHandler PostRegisterPlugin;
  116. public ILockableNotifier RepoChangedNotifier { get; private set; }
  117. public IBrowseRepo BrowseRepo { get; set; }
  118. #endregion
  119. public string GitCommand(string arguments)
  120. {
  121. return Module.RunGitCmd(arguments);
  122. }
  123. public string CommandLineCommand(string cmd, string arguments)
  124. {
  125. return Module.RunCmd(cmd, arguments);
  126. }
  127. private bool RequiresValidWorkingDir(object owner)
  128. {
  129. if (!Module.IsValidGitWorkingDir())
  130. {
  131. MessageBoxes.NotValidGitDirectory(owner as IWin32Window);
  132. return false;
  133. }
  134. return true;
  135. }
  136. private bool RequiredValidGitSvnWorikingDir(object owner)
  137. {
  138. if (!RequiresValidWorkingDir(owner))
  139. return false;
  140. if (!GitSvnCommandHelpers.ValidSvnWorkingDir(Module))
  141. {
  142. MessageBoxes.NotValidGitSVNDirectory(owner as IWin32Window);
  143. return false;
  144. }
  145. if (!GitSvnCommandHelpers.CheckRefsRemoteSvn(Module))
  146. {
  147. MessageBoxes.UnableGetSVNInformation(owner as IWin32Window);
  148. return false;
  149. }
  150. return true;
  151. }
  152. public void CacheAvatar(string email)
  153. {
  154. FallBackService gravatarFallBack = FallBackService.Identicon;
  155. try
  156. {
  157. gravatarFallBack =
  158. (FallBackService)Enum.Parse(typeof(FallBackService), Settings.GravatarFallbackService);
  159. }
  160. catch
  161. {
  162. Settings.GravatarFallbackService = gravatarFallBack.ToString();
  163. }
  164. GravatarService.CacheImage(email + ".png", email, Settings.AuthorImageSize,
  165. gravatarFallBack);
  166. }
  167. public Icon FormIcon { get { return GitExtensionsForm.ApplicationIcon; } }
  168. public bool StartBatchFileProcessDialog(object owner, string batchFile)
  169. {
  170. string tempFileName = Path.ChangeExtension(Path.GetTempFileName(), ".cmd");
  171. using (var writer = new StreamWriter(tempFileName))
  172. {
  173. writer.WriteLine("@prompt $G");
  174. writer.Write(batchFile);
  175. }
  176. FormProcess.ShowDialog(owner as IWin32Window, Module, "cmd.exe", "/C \"" + tempFileName + "\"");
  177. File.Delete(tempFileName);
  178. return true;
  179. }
  180. public bool StartBatchFileProcessDialog(string batchFile)
  181. {
  182. return StartBatchFileProcessDialog(null, batchFile);
  183. }
  184. public bool StartCommandLineProcessDialog(GitCommand cmd, IWin32Window parentForm)
  185. {
  186. bool executed;
  187. if (cmd.AccessesRemote())
  188. executed = FormRemoteProcess.ShowDialog(parentForm, Module, cmd.ToLine());
  189. else
  190. executed = FormProcess.ShowDialog(parentForm, Module, cmd.ToLine());
  191. if (executed && cmd.ChangesRepoState())
  192. RepoChangedNotifier.Notify();
  193. return executed;
  194. }
  195. public bool StartCommandLineProcessDialog(object owner, string command, string arguments)
  196. {
  197. FormProcess.ShowDialog(owner as IWin32Window, Module, command, arguments);
  198. return true;
  199. }
  200. public bool StartCommandLineProcessDialog(string command, string arguments)
  201. {
  202. return StartCommandLineProcessDialog(null, command, arguments);
  203. }
  204. public bool StartGitCommandProcessDialog(IWin32Window owner, string arguments)
  205. {
  206. FormProcess.ShowDialog(owner, Module, arguments);
  207. return true;
  208. }
  209. public bool StartGitCommandProcessDialog(string arguments)
  210. {
  211. return StartGitCommandProcessDialog(null, arguments);
  212. }
  213. public bool StartBrowseDialog()
  214. {
  215. return StartBrowseDialog("");
  216. }
  217. public bool StartDeleteBranchDialog(IWin32Window owner, string branch)
  218. {
  219. return DoActionOnRepo(owner, true, false, PreDeleteBranch, PostDeleteBranch, () =>
  220. {
  221. using (var form = new FormDeleteBranch(this, branch))
  222. form.ShowDialog(owner);
  223. return true;
  224. }
  225. );
  226. }
  227. public bool StartDeleteBranchDialog(string branch)
  228. {
  229. return StartDeleteBranchDialog(null, branch);
  230. }
  231. public bool StartCheckoutRevisionDialog(IWin32Window owner, string revision = null)
  232. {
  233. return DoActionOnRepo(owner, true, true, PreCheckoutRevision, PostCheckoutRevision, () =>
  234. {
  235. using (var form = new FormCheckoutRevision(this))
  236. {
  237. form.SetRevision(revision);
  238. return form.ShowDialog(owner) == DialogResult.OK;
  239. }
  240. }
  241. );
  242. }
  243. public bool StartCheckoutRevisionDialog()
  244. {
  245. return StartCheckoutRevisionDialog(null);
  246. }
  247. public bool StashSave(IWin32Window owner, bool includeUntrackedFiles, bool keepIndex = false, string message = "")
  248. {
  249. Func<bool> action = () =>
  250. {
  251. var arguments = GitCommandHelpers.StashSaveCmd(includeUntrackedFiles, keepIndex, message);
  252. FormProcess.ShowDialog(owner, Module, arguments);
  253. return true;
  254. };
  255. return DoActionOnRepo(owner, true, true, null, null, action);
  256. }
  257. public bool StashPop(IWin32Window owner)
  258. {
  259. Func<bool> action = () =>
  260. {
  261. FormProcess.ShowDialog(owner, Module, "stash pop");
  262. MergeConflictHandler.HandleMergeConflicts(this, owner, false, false);
  263. return true;
  264. };
  265. return DoActionOnRepo(owner, true, true, null, null, action);
  266. }
  267. /// <summary>Creates and checks out a new branch starting from the commit at which the stash was originally created.
  268. /// Applies the changes recorded in the stash to the new working directory and index.</summary>
  269. public bool StashBranch(IWin32Window owner, string branchName, string stash = null)
  270. {
  271. Func<bool> action = () =>
  272. {
  273. FormProcess.ShowDialog(owner, Module, "stash branch " + branchName.Quote().Combine(" ", stash.QuoteNE()));
  274. return true;
  275. };
  276. return DoActionOnRepo(owner, true, true, null, null, action);
  277. }
  278. public bool StashDrop(IWin32Window owner, string stashName)
  279. {
  280. Func<bool> action = () =>
  281. {
  282. FormProcess.ShowDialog(owner, Module, "stash drop " + stashName.Quote());
  283. return true;
  284. };
  285. return DoActionOnRepo(owner, true, true, null, null, action);
  286. }
  287. public bool StashApply(IWin32Window owner, string stashName)
  288. {
  289. Func<bool> action = () =>
  290. {
  291. FormProcess.ShowDialog(owner, Module, "stash apply " + stashName.Quote());
  292. MergeConflictHandler.HandleMergeConflicts(this, owner, false, false);
  293. return true;
  294. };
  295. return DoActionOnRepo(owner, true, true, null, null, action);
  296. }
  297. public void InvokeEventOnClose(Form form, GitUIEventHandler ev)
  298. {
  299. form.FormClosed += (object o, FormClosedEventArgs ea) =>
  300. {
  301. InvokeEvent(form == null ? null : form.Owner, ev);
  302. };
  303. }
  304. public void ShowModelessForm(IWin32Window owner, bool requiresValidWorkingDir,
  305. GitUIEventHandler preEvent, GitUIPostActionEventHandler postEvent, Func<Form> provideForm)
  306. {
  307. if (requiresValidWorkingDir && !RequiresValidWorkingDir(owner))
  308. return;
  309. if (!InvokeEvent(owner, preEvent))
  310. return;
  311. Form form = provideForm();
  312. FormClosedEventHandler formClosed = null;
  313. formClosed = (sender, e) =>
  314. {
  315. form.FormClosed -= formClosed;
  316. InvokePostEvent(owner, true, postEvent);
  317. };
  318. form.FormClosed += formClosed;
  319. form.ShowInTaskbar = true;
  320. if (Application.OpenForms.Count > 0)
  321. form.Show();
  322. else
  323. form.ShowDialog();
  324. }
  325. /// <summary>
  326. ///
  327. /// </summary>
  328. /// <param name="requiresValidWorkingDir">If action requires valid working directory</param>
  329. /// <param name="owner">Owner window</param>
  330. /// <param name="changesRepo">if successfuly done action changes repo state</param>
  331. /// <param name="preEvent">Event invoked before performing action</param>
  332. /// <param name="postEvent">Event invoked after performing action</param>
  333. /// <param name="action">Action to do. Return true to indicate that the action was successfully done.</param>
  334. /// <returns>true if action was successfully done, false otherwise</returns>
  335. public bool DoActionOnRepo(IWin32Window owner, bool requiresValidWorkingDir, bool changesRepo,
  336. GitUIEventHandler preEvent, GitUIPostActionEventHandler postEvent, Func<bool> action)
  337. {
  338. bool actionDone = false;
  339. RepoChangedNotifier.Lock();
  340. try
  341. {
  342. if (requiresValidWorkingDir && !RequiresValidWorkingDir(owner))
  343. return false;
  344. if (!InvokeEvent(owner, preEvent))
  345. return false;
  346. try
  347. {
  348. actionDone = action();
  349. }
  350. finally
  351. {
  352. InvokePostEvent(owner, actionDone, postEvent);
  353. }
  354. }
  355. finally
  356. {
  357. RepoChangedNotifier.UnLock(changesRepo && actionDone);
  358. }
  359. return actionDone;
  360. }
  361. public void DoActionOnRepo(Action action)
  362. {
  363. Func<bool> fnc = () =>
  364. {
  365. action();
  366. return true;
  367. };
  368. DoActionOnRepo(null, false, false, null, null, fnc);
  369. }
  370. public bool DoActionOnRepo(Func<bool> action)
  371. {
  372. return DoActionOnRepo(null, false, true, null, null, action);
  373. }
  374. #region Checkout
  375. public bool StartCheckoutBranch(IWin32Window owner, string branch, bool remote, string[] containRevisons)
  376. {
  377. return DoActionOnRepo(owner, true, true, PreCheckoutBranch, PostCheckoutBranch, () =>
  378. {
  379. using (var form = new FormCheckoutBranch(this, branch, remote, containRevisons))
  380. return form.DoDefaultActionOrShow(owner) != DialogResult.Cancel;
  381. }
  382. );
  383. }
  384. public bool StartCheckoutBranch(IWin32Window owner, string branch, bool remote)
  385. {
  386. return StartCheckoutBranch(owner, branch, remote, null);
  387. }
  388. public bool StartCheckoutBranch(IWin32Window owner, string[] containRevisons)
  389. {
  390. return StartCheckoutBranch(owner, "", false, containRevisons);
  391. }
  392. public bool StartCheckoutBranch(IWin32Window owner)
  393. {
  394. return StartCheckoutBranch(owner, "", false, null);
  395. }
  396. public bool StartCheckoutBranch(string branch, bool remote)
  397. {
  398. return StartCheckoutBranch(null, branch, remote, null);
  399. }
  400. public bool StartCheckoutBranch()
  401. {
  402. return StartCheckoutBranch(null, "", false, null);
  403. }
  404. public bool StartCheckoutRemoteBranch(IWin32Window owner, string branch)
  405. {
  406. return StartCheckoutBranch(owner, branch, true);
  407. }
  408. #endregion Checkout
  409. public bool StartCompareRevisionsDialog(IWin32Window owner)
  410. {
  411. Func<bool> action = () =>
  412. {
  413. using (var form = new FormLog(this))
  414. {
  415. return form.ShowDialog(owner) == DialogResult.OK;
  416. }
  417. };
  418. return DoActionOnRepo(owner, true, true, PreCompareRevisions, PostCompareRevisions, action);
  419. }
  420. public bool StartCompareRevisionsDialog()
  421. {
  422. return StartCompareRevisionsDialog(null);
  423. }
  424. public bool StartAddFilesDialog(IWin32Window owner, string addFiles)
  425. {
  426. return DoActionOnRepo(owner, true, true, PreAddFiles, PostAddFiles, () =>
  427. {
  428. using (var form = new FormAddFiles(this, addFiles))
  429. form.ShowDialog(owner);
  430. return true;
  431. }
  432. );
  433. }
  434. public bool StartAddFilesDialog(IWin32Window owner)
  435. {
  436. return StartAddFilesDialog(owner, null);
  437. }
  438. public bool StartAddFilesDialog(string addFiles)
  439. {
  440. return StartAddFilesDialog(null, addFiles);
  441. }
  442. public bool StartAddFilesDialog()
  443. {
  444. return StartAddFilesDialog(null, null);
  445. }
  446. public bool StartCreateBranchDialog(IWin32Window owner, GitRevision revision)
  447. {
  448. Func<bool> action = () =>
  449. {
  450. using (var form = new FormCreateBranch(this, revision))
  451. {
  452. return form.ShowDialog(owner) == DialogResult.OK;
  453. }
  454. };
  455. return DoActionOnRepo(owner, true, true, PreCreateBranch, PostCreateBranch, action);
  456. }
  457. public bool StartCreateBranchDialog()
  458. {
  459. return StartCreateBranchDialog(null, null);
  460. }
  461. public bool StartCloneDialog(IWin32Window owner, string url, bool openedFromProtocolHandler, GitModuleChangedEventHandler GitModuleChanged)
  462. {
  463. Func<bool> action = () =>
  464. {
  465. using (var form = new FormClone(this, url, openedFromProtocolHandler, GitModuleChanged))
  466. form.ShowDialog(owner);
  467. return true;
  468. };
  469. return DoActionOnRepo(owner, false, false, PreClone, PostClone, action);
  470. }
  471. public bool StartCloneDialog(IWin32Window owner, string url, GitModuleChangedEventHandler GitModuleChanged)
  472. {
  473. return StartCloneDialog(owner, url, false, GitModuleChanged);
  474. }
  475. public bool StartCloneDialog(IWin32Window owner, string url)
  476. {
  477. return StartCloneDialog(owner, url, false, null);
  478. }
  479. public bool StartCloneDialog(IWin32Window owner)
  480. {
  481. return StartCloneDialog(owner, null, false, null);
  482. }
  483. public bool StartCloneDialog(string url)
  484. {
  485. return StartCloneDialog(null, url, false, null);
  486. }
  487. public bool StartCloneDialog()
  488. {
  489. return StartCloneDialog(null, null, false, null);
  490. }
  491. public bool StartSvnCloneDialog(IWin32Window owner, GitModuleChangedEventHandler GitModuleChanged)
  492. {
  493. Func<bool> action = () =>
  494. {
  495. using (var form = new FormSvnClone(this, GitModuleChanged))
  496. form.ShowDialog(owner);
  497. return true;
  498. };
  499. return DoActionOnRepo(owner, false, false, PreSvnClone, PostSvnClone, action);
  500. }
  501. public bool StartSvnCloneDialog()
  502. {
  503. return StartSvnCloneDialog(null, null);
  504. }
  505. public void StartCleanupRepositoryDialog(IWin32Window owner = null, string path = null)
  506. {
  507. using (var form = new FormCleanupRepository(this))
  508. {
  509. form.SetPathArgument(path);
  510. form.ShowDialog(owner);
  511. }
  512. }
  513. public bool StartSquashCommitDialog(IWin32Window owner, GitRevision revision)
  514. {
  515. Func<bool> action = () =>
  516. {
  517. using (var form = new FormCommit(this, CommitKind.Squash, revision))
  518. {
  519. form.ShowDialog(owner);
  520. }
  521. return true;
  522. };
  523. return DoActionOnRepo(action);
  524. }
  525. public bool StartFixupCommitDialog(IWin32Window owner, GitRevision revision)
  526. {
  527. Func<bool> action = () =>
  528. {
  529. using (var form = new FormCommit(this, CommitKind.Fixup, revision))
  530. {
  531. form.ShowDialog(owner);
  532. }
  533. return true;
  534. };
  535. return DoActionOnRepo(action);
  536. }
  537. public bool StartCommitDialog(IWin32Window owner, bool showOnlyWhenChanges)
  538. {
  539. Func<bool> action = () =>
  540. {
  541. using (var form = new FormCommit(this))
  542. {
  543. if (showOnlyWhenChanges)
  544. form.ShowDialogWhenChanges(owner);
  545. else
  546. form.ShowDialog(owner);
  547. }
  548. return true;
  549. };
  550. return DoActionOnRepo(owner, true, false, PreCommit, PostCommit, action);
  551. }
  552. public bool StartCommitDialog(IWin32Window owner)
  553. {
  554. return StartCommitDialog(owner, false);
  555. }
  556. public bool StartCommitDialog(bool showOnlyWhenChanges)
  557. {
  558. return StartCommitDialog(null, showOnlyWhenChanges);
  559. }
  560. public bool StartCommitDialog()
  561. {
  562. return StartCommitDialog(null, false);
  563. }
  564. public bool StartSvnDcommitDialog(IWin32Window owner)
  565. {
  566. Func<bool> action = () =>
  567. {
  568. return FormProcess.ShowDialog(owner, Module, Settings.GitCommand, GitSvnCommandHelpers.DcommitCmd());
  569. };
  570. return DoActionOnRepo(owner, true, true, PreSvnDcommit, PostSvnDcommit, action);
  571. }
  572. public bool StartSvnDcommitDialog()
  573. {
  574. return StartSvnDcommitDialog(null);
  575. }
  576. public bool StartSvnRebaseDialog(IWin32Window owner)
  577. {
  578. Func<bool> action = () =>
  579. {
  580. FormProcess.ShowDialog(owner, Module, Settings.GitCommand, GitSvnCommandHelpers.RebaseCmd());
  581. return true;
  582. };
  583. return DoActionOnRepo(owner, true, true, PreSvnRebase, PostSvnRebase, action);
  584. }
  585. public bool StartSvnRebaseDialog()
  586. {
  587. return StartSvnRebaseDialog(null);
  588. }
  589. public bool StartSvnFetchDialog(IWin32Window owner)
  590. {
  591. Func<bool> action = () =>
  592. {
  593. return FormProcess.ShowDialog(owner, Module, Settings.GitCommand, GitSvnCommandHelpers.FetchCmd());
  594. };
  595. return DoActionOnRepo(owner, true, true, PreSvnFetch, PostSvnFetch, action);
  596. }
  597. public bool StartSvnFetchDialog()
  598. {
  599. return StartSvnFetchDialog(null);
  600. }
  601. public bool StartInitializeDialog(IWin32Window owner, GitModuleChangedEventHandler GitModuleChanged)
  602. {
  603. return StartInitializeDialog(owner, null, GitModuleChanged);
  604. }
  605. public bool StartInitializeDialog()
  606. {
  607. return StartInitializeDialog((IWin32Window)null, null);
  608. }
  609. public bool StartInitializeDialog(IWin32Window owner, string dir, GitModuleChangedEventHandler GitModuleChanged)
  610. {
  611. Func<bool> action = () =>
  612. {
  613. if (dir == null)
  614. dir = Module.IsValidGitWorkingDir() ? Module.WorkingDir : string.Empty;
  615. using (var frm = new FormInit(dir, GitModuleChanged)) frm.ShowDialog(owner);
  616. return true;
  617. };
  618. return DoActionOnRepo(owner, false, true, PreInitialize, PostInitialize, action);
  619. }
  620. public bool StartInitializeDialog(string dir)
  621. {
  622. return StartInitializeDialog(null, dir, null);
  623. }
  624. /// <summary>
  625. /// Starts pull dialog
  626. /// </summary>
  627. /// <param name="owner">An implementation of IWin32Window that will own the modal dialog box.</param>
  628. /// <param name="pullOnShow"></param>
  629. /// <param name="pullCompleted">true if pull completed with no errors</param>
  630. /// <returns>if revision grid should be refreshed</returns>
  631. public bool StartPullDialog(IWin32Window owner, bool pullOnShow, string remoteBranch, string remote, out bool pullCompleted, bool fetchAll)
  632. {
  633. var pulled = false;
  634. Func<bool> action = () =>
  635. {
  636. using (FormPull formPull = new FormPull(this, remoteBranch, remote))
  637. {
  638. if (fetchAll)
  639. formPull.SetForFetchAll();
  640. DialogResult dlgResult;
  641. if (pullOnShow)
  642. dlgResult = formPull.PullAndShowDialogWhenFailed(owner);
  643. else
  644. dlgResult = formPull.ShowDialog(owner);
  645. if (dlgResult == DialogResult.OK)
  646. {
  647. pulled = !formPull.ErrorOccurred;
  648. }
  649. return dlgResult == DialogResult.OK;
  650. }
  651. };
  652. bool done = DoActionOnRepo(owner, true, true, PrePull, PostPull, action);
  653. pullCompleted = pulled;
  654. return done;
  655. }
  656. public bool StartPullDialog(IWin32Window owner, bool pullOnShow, out bool pullCompleted, bool fetchAll)
  657. {
  658. return StartPullDialog(owner, pullOnShow, null, null, out pullCompleted, fetchAll);
  659. }
  660. public bool StartPullDialog(IWin32Window owner, bool pullOnShow, out bool pullCompleted)
  661. {
  662. return StartPullDialog(owner, pullOnShow, out pullCompleted, false);
  663. }
  664. public bool StartPullDialog(IWin32Window owner, bool pullOnShow)
  665. {
  666. bool errorOccurred;
  667. return StartPullDialog(owner, pullOnShow, out errorOccurred, false);
  668. }
  669. public bool StartPullDialog(bool pullOnShow, out bool pullCompleted)
  670. {
  671. return StartPullDialog(null, pullOnShow, out pullCompleted, false);
  672. }
  673. public bool StartPullDialog(bool pullOnShow, string remoteBranch, out bool pullCompleted)
  674. {
  675. return StartPullDialog(null, pullOnShow, remoteBranch, null, out pullCompleted, false);
  676. }
  677. public bool StartPullDialog(bool pullOnShow)
  678. {
  679. return StartPullDialog(pullOnShow, null);
  680. }
  681. public bool StartPullDialog(bool pullOnShow, string remoteBranch)
  682. {
  683. bool errorOccurred;
  684. return StartPullDialog(pullOnShow, remoteBranch, out errorOccurred);
  685. }
  686. public bool StartPullDialog(IWin32Window owner)
  687. {
  688. bool errorOccurred;
  689. return StartPullDialog(owner, false, out errorOccurred, false);
  690. }
  691. public bool StartPullDialog()
  692. {
  693. return StartPullDialog(false);
  694. }
  695. public bool StartViewPatchDialog(IWin32Window owner, string patchFile)
  696. {
  697. Func<bool> action = () =>
  698. {
  699. using (var viewPatch = new FormViewPatch(this))
  700. {
  701. if (!String.IsNullOrEmpty(patchFile))
  702. viewPatch.LoadPatch(patchFile);
  703. viewPatch.ShowDialog(owner);
  704. }
  705. return true;
  706. };
  707. return DoActionOnRepo(owner, false, false, PreViewPatch, PostViewPatch, action);
  708. }
  709. public bool StartViewPatchDialog(string patchFile)
  710. {
  711. return StartViewPatchDialog(null, patchFile);
  712. }
  713. public bool StartViewPatchDialog(IWin32Window owner)
  714. {
  715. return StartViewPatchDialog(owner, null);
  716. }
  717. public bool StartViewPatchDialog()
  718. {
  719. return StartViewPatchDialog(null, null);
  720. }
  721. public bool StartFormatPatchDialog(IWin32Window owner)
  722. {
  723. Func<bool> action = () =>
  724. {
  725. using (var form = new FormFormatPatch(this))
  726. form.ShowDialog(owner);
  727. return true;
  728. };
  729. return DoActionOnRepo(owner, true, false, PreFormatPatch, PostFormatPatch, action);
  730. }
  731. public bool StartFormatPatchDialog()
  732. {
  733. return StartFormatPatchDialog(null);
  734. }
  735. public bool StartStashDialog(IWin32Window owner)
  736. {
  737. Func<bool> action = () =>
  738. {
  739. using (var form = new FormStash(this))
  740. form.ShowDialog(owner);
  741. return true;
  742. };
  743. return DoActionOnRepo(owner, true, false, PreStash, PostStash, action);
  744. }
  745. public bool StartStashDialog()
  746. {
  747. return StartStashDialog(null);
  748. }
  749. public bool StartResetChangesDialog(IWin32Window owner)
  750. {
  751. var unstagedFiles = Module.GetUnstagedFiles();
  752. return StartResetChangesDialog(owner, unstagedFiles, false);
  753. }
  754. public bool StartResetChangesDialog(IWin32Window owner, IEnumerable<GitItemStatus> unstagedFiles, bool onlyUnstaged)
  755. {
  756. // Show a form asking the user if they want to reset the changes.
  757. FormResetChanges.ActionEnum resetAction = FormResetChanges.ShowResetDialog(owner, unstagedFiles.Any(item => !item.IsNew), unstagedFiles.Any(item => item.IsNew));
  758. if (resetAction == FormResetChanges.ActionEnum.Cancel)
  759. {
  760. return false;
  761. }
  762. Func<bool> action = () =>
  763. {
  764. if (onlyUnstaged)
  765. Module.RunGitCmd("checkout -- .");
  766. else
  767. // Reset all changes.
  768. Module.ResetHard("");
  769. if (resetAction == FormResetChanges.ActionEnum.ResetAndDelete)
  770. Module.RunGitCmd("clean -df");
  771. return true;
  772. };
  773. return DoActionOnRepo(owner, true, true, null, null, action);
  774. }
  775. public bool StartResetChangesDialog(IWin32Window owner, string fileName)
  776. {
  777. // Show a form asking the user if they want to reset the changes.
  778. FormResetChanges.ActionEnum resetAction = FormResetChanges.ShowResetDialog(owner, true, false);
  779. if (resetAction == FormResetChanges.ActionEnum.Cancel)
  780. {
  781. return false;
  782. }
  783. Cursor.Current = Cursors.WaitCursor;
  784. // Reset all changes.
  785. Module.ResetFile(fileName);
  786. // Also delete new files, if requested.
  787. if (resetAction == FormResetChanges.ActionEnum.ResetAndDelete)
  788. {
  789. try
  790. {
  791. string path = Path.Combine(Module.WorkingDir, fileName);
  792. if (File.Exists(path))
  793. File.Delete(path);
  794. else
  795. Directory.Delete(path, true);
  796. }
  797. catch (System.IO.IOException) { }
  798. catch (System.UnauthorizedAccessException) { }
  799. }
  800. Cursor.Current = Cursors.Default;
  801. return true;
  802. }
  803. public bool StartResetChangesDialog(string fileName)
  804. {
  805. return StartResetChangesDialog(null, fileName);
  806. }
  807. public bool StartResetChangesDialog()
  808. {
  809. return StartResetChangesDialog((IWin32Window) null);
  810. }
  811. public bool StartRevertCommitDialog(IWin32Window owner, GitRevision revision)
  812. {
  813. Func<bool> action = () =>
  814. {
  815. using (var form = new FormRevertCommit(this, revision))
  816. {
  817. return form.ShowDialog(owner) == DialogResult.OK;
  818. }
  819. };
  820. return DoActionOnRepo(owner, true, true, PreRevertCommit, PostRevertCommit, action);
  821. }
  822. public bool StartResolveConflictsDialog(IWin32Window owner, bool offerCommit)
  823. {
  824. Func<bool> action = () =>
  825. {
  826. using (var form = new FormResolveConflicts(this, offerCommit))
  827. form.ShowDialog(owner);
  828. return true;
  829. };
  830. return DoActionOnRepo(owner, true, true, PreResolveConflicts, PostResolveConflicts, action);
  831. }
  832. public bool StartResolveConflictsDialog(IWin32Window owner)
  833. {
  834. return StartResolveConflictsDialog(owner, true);
  835. }
  836. public bool StartResolveConflictsDialog(bool offerCommit)
  837. {
  838. return StartResolveConflictsDialog(null, offerCommit);
  839. }
  840. public bool StartResolveConflictsDialog()
  841. {
  842. return StartResolveConflictsDialog(null, true);
  843. }
  844. public bool StartCherryPickDialog(IWin32Window owner, GitRevision revision)
  845. {
  846. Func<bool> action = () =>
  847. {
  848. using (var form = new FormCherryPick(this, revision))
  849. {
  850. return form.ShowDialog(owner) == DialogResult.OK;
  851. }
  852. };
  853. return DoActionOnRepo(owner, true, true, PreCherryPick, PostCherryPick, action);
  854. }
  855. public bool StartCherryPickDialog(IWin32Window owner, IEnumerable<GitRevision> revisions)
  856. {
  857. if (revisions == null)
  858. throw new ArgumentNullException("revisions");
  859. Func<bool> action = () =>
  860. {
  861. FormCherryPick prevForm = null;
  862. try
  863. {
  864. bool repoChanged = false;
  865. foreach (var r in revisions)
  866. {
  867. var frm = new FormCherryPick(this, r);
  868. if (prevForm != null)
  869. {
  870. frm.CopyOptions(prevForm);
  871. prevForm.Dispose();
  872. }
  873. prevForm = frm;
  874. if (frm.ShowDialog(owner) == DialogResult.OK)
  875. repoChanged = true;
  876. else
  877. return repoChanged;
  878. }
  879. return repoChanged;
  880. }
  881. finally
  882. {
  883. if (prevForm != null)
  884. {
  885. prevForm.Dispose();
  886. }
  887. }
  888. };
  889. return DoActionOnRepo(owner, true, true, PreCherryPick, PostCherryPick, action);
  890. }
  891. public bool StartCherryPickDialog(IWin32Window owner)
  892. {
  893. return StartCherryPickDialog(owner, (GitRevision)null);
  894. }
  895. public bool StartCherryPickDialog()
  896. {
  897. return StartCherryPickDialog(null);
  898. }
  899. /// <summary>Start Merge dialog, using the specified branch.</summary>
  900. /// <param name="owner">Owner of the dialog.</param>
  901. /// <param name="branch">Branch to merge into the current branch.</param>
  902. public bool StartMergeBranchDialog(IWin32Window owner, string branch)
  903. {
  904. Func<bool> action = () =>
  905. {
  906. using (var form = new FormMergeBranch(this, branch))
  907. form.ShowDialog(owner);
  908. return true;
  909. };
  910. return DoActionOnRepo(owner, true, false, PreMergeBranch, PostMergeBranch, action);
  911. }
  912. /// <summary>Start Merge dialog, using the specified branch.</summary>
  913. /// <param name="branch">Branch to merge into the current branch.</param>
  914. public bool StartMergeBranchDialog(string branch)
  915. {
  916. return StartMergeBranchDialog(null, branch);
  917. }
  918. public bool StartCreateTagDialog(IWin32Window owner)
  919. {
  920. Func<bool> action = () =>
  921. {
  922. using (var form = new FormCreateTag(this, null))
  923. {
  924. return form.ShowDialog(owner) == DialogResult.OK;
  925. }
  926. };
  927. return DoActionOnRepo(owner, true, true, PreCreateTag, PostCreateTag, action);
  928. }
  929. public bool StartCreateTagDialog()
  930. {
  931. return StartCreateTagDialog(null);
  932. }
  933. public bool StartDeleteTagDialog(IWin32Window owner, string tag)
  934. {
  935. Func<bool> action = () =>
  936. {
  937. using (var form = new FormDeleteTag(this, tag))
  938. {
  939. return form.ShowDialog(owner) == DialogResult.OK;
  940. }
  941. };
  942. return DoActionOnRepo(owner, true, true, PreDeleteTag, PostDeleteTag, action);
  943. }
  944. public bool StartDeleteTagDialog(string tag)
  945. {
  946. return StartDeleteTagDialog(null, tag);
  947. }
  948. public bool StartDeleteTagDialog()
  949. {
  950. return StartDeleteTagDialog(null, "");
  951. }
  952. public bool StartEditGitIgnoreDialog(IWin32Window owner)
  953. {
  954. Func<bool> action = () =>
  955. {
  956. using (var form = new FormGitIgnore(this))
  957. form.ShowDialog(owner);
  958. return true;
  959. };
  960. return DoActionOnRepo(owner, true, false, PreEditGitIgnore, PostEditGitIgnore, action);
  961. }
  962. public bool StartEditGitIgnoreDialog()
  963. {
  964. return StartEditGitIgnoreDialog(null);
  965. }
  966. public bool StartAddToGitIgnoreDialog(IWin32Window owner, params string[] filePattern)
  967. {
  968. Func<bool> action = () =>
  969. {
  970. using (var frm = new FormAddToGitIgnore(this, filePattern))
  971. frm.ShowDialog(owner);
  972. return true;
  973. };
  974. return DoActionOnRepo(owner, true, false, PreEditGitIgnore, PostEditGitIgnore, action);
  975. }
  976. public bool StartSettingsDialog(IWin32Window owner, SettingsPageReference initialPage = null)
  977. {
  978. Func<bool> action = () =>
  979. {
  980. FormSettings.ShowSettingsDialog(this, owner, initialPage);
  981. return true;
  982. };
  983. return DoActionOnRepo(owner, false, true, PreSettings, PostSettings, action);
  984. }
  985. public bool StartSettingsDialog()
  986. {
  987. return StartSettingsDialog(null, null);
  988. }
  989. public bool StartSettingsDialog(IGitPlugin gitPlugin)
  990. {
  991. // TODO: how to pass the main dialog as owner of the SettingsDialog (first parameter):
  992. return StartSettingsDialog(null, new SettingsPageReferenceByPlugin(gitPlugin));
  993. }
  994. /// <summary>
  995. /// Open the archive dialog
  996. /// </summary>
  997. /// <param name="owner"></param>
  998. /// <param name="revision">Revision to create an archive from</param>
  999. /// <param name="revision2">Revision for differencial archive </param>
  1000. /// <param name="path">Files path for archive</param>
  1001. /// <returns></returns>
  1002. public bool StartArchiveDialog(IWin32Window owner = null, GitRevision revision = null, GitRevision revision2 = null, string path = null)
  1003. {
  1004. return DoActionOnRepo(owner, true, false, PreArchive, PostArchive, () =>
  1005. {
  1006. using (var form = new FormArchive(this))
  1007. {
  1008. form.SelectedRevision = revision;
  1009. form.SetDiffSelectedRevision(revision2);
  1010. form.SetPathArgument(path);
  1011. form.ShowDialog(owner);
  1012. }
  1013. return true;
  1014. }
  1015. );
  1016. }
  1017. public bool StartArchiveDialog()
  1018. {
  1019. return StartArchiveDialog(null);
  1020. }
  1021. public bool StartMailMapDialog(IWin32Window owner)
  1022. {
  1023. Func<bool> action = () =>
  1024. {
  1025. using (var form = new FormMailMap(this))
  1026. form.ShowDialog(owner);
  1027. return true;
  1028. };
  1029. return DoActionOnRepo(owner, true, false, PreMailMap, PostMailMap, action);
  1030. }
  1031. public bool StartMailMapDialog()
  1032. {
  1033. return StartMailMapDialog(null);
  1034. }
  1035. public bool StartVerifyDatabaseDialog(IWin32Window owner)
  1036. {
  1037. Func<bool> action = () =>
  1038. {
  1039. using (var form = new FormVerify(this))
  1040. form.ShowDialog(owner);
  1041. return true;
  1042. };
  1043. //TODO: move Notify to FormVerify and friends
  1044. return DoActionOnRepo(owner, true, true, PreVerifyDatabase, PostVerifyDatabase, action);
  1045. }
  1046. public bool StartVerifyDatabaseDialog()
  1047. {
  1048. return StartVerifyDatabaseDialog(null);
  1049. }
  1050. /// <summary>
  1051. ///
  1052. /// </summary>
  1053. /// <param name="owner"></param>
  1054. /// <param name="preselectRemote">makes the FormRemotes initialially select the given remote</param>
  1055. /// <returns></returns>
  1056. public bool StartRemotesDialog(IWin32Window owner, string preselectRemote)
  1057. {
  1058. Func<bool> action = () =>
  1059. {
  1060. using (var form = new FormRemotes(this))
  1061. {
  1062. form.PreselectRemoteOnLoad = preselectRemote;
  1063. form.ShowDialog(owner);
  1064. }
  1065. return true;
  1066. };
  1067. return DoActionOnRepo(owner, true, true, PreRemotes, PostRemotes, action);
  1068. }
  1069. public bool StartRemotesDialog(IWin32Window owner)
  1070. {
  1071. return StartRemotesDialog(owner, null);
  1072. }
  1073. public bool StartRemotesDialog()
  1074. {
  1075. return StartRemotesDialog(null);
  1076. }
  1077. public bool StartRebaseDialog(IWin32Window owner, string branch)
  1078. {
  1079. return StartRebaseDialog(owner, string.Empty, null, branch);
  1080. }
  1081. public bool StartRebaseDialog(IWin32Window owner, string from, string to, string onto)
  1082. {
  1083. Func<bool> action = () =>
  1084. {
  1085. using (var form = new FormRebase(this, from, to, onto))
  1086. form.ShowDialog(owner);
  1087. return true;
  1088. };
  1089. return DoActionOnRepo(owner, true, true, PreRebase, PostRebase, action);
  1090. }
  1091. public bool StartRebaseDialog(string branch)
  1092. {
  1093. return StartRebaseDialog(null, branch);
  1094. }
  1095. public bool StartRenameDialog(string branch)
  1096. {
  1097. return StartRenameDialog(null, branch);
  1098. }
  1099. public bool StartRenameDialog(IWin32Window owner, string branch)
  1100. {
  1101. Func<bool> action = () =>
  1102. {
  1103. using (var form = new FormRenameBranch(this, branch))
  1104. {
  1105. return form.ShowDialog(owner) == DialogResult.OK;
  1106. }
  1107. };
  1108. return DoActionOnRepo(owner, true, true, PreRename, PostRename, action);
  1109. }
  1110. public bool StartSubmodulesDialog(IWin32Window owner)
  1111. {
  1112. Func<bool> action = () =>
  1113. {
  1114. using (var form = new FormSubmodules(this))
  1115. form.ShowDialog(owner);
  1116. return true;
  1117. };
  1118. return DoActionOnRepo(owner, true, true, PreSubmodulesEdit, PostSubmodulesEdit, action);
  1119. }
  1120. public bool StartSubmodulesDialog()
  1121. {
  1122. return StartSubmodulesDialog(null);
  1123. }
  1124. public bool StartUpdateSubmodulesDialog(IWin32Window owner)
  1125. {
  1126. Func<bool> action = () =>
  1127. {
  1128. return FormProcess.ShowDialog(owner, Module, GitCommandHelpers.SubmoduleUpdateCmd(""));
  1129. };
  1130. return DoActionOnRepo(owner, true, true, PreUpdateSubmodules, PostUpdateSubmodules, action);
  1131. }
  1132. public bool StartUpdateSubmodulesDialog()
  1133. {
  1134. return StartUpdateSubmodulesDialog(null);
  1135. }
  1136. public bool StartSyncSubmodulesDialog(IWin32Window owner)
  1137. {
  1138. Func<bool> action = () =>
  1139. {
  1140. return FormProcess.ShowDialog(owner, Module, GitCommandHelpers.SubmoduleSyncCmd(""));
  1141. };
  1142. return DoActionOnRepo(owner, true, true, PreSyncSubmodules, PostSyncSubmodules, action);
  1143. }
  1144. public bool StartSyncSubmodulesDialog()
  1145. {
  1146. return StartSyncSubmodulesDialog(null);
  1147. }
  1148. public void UpdateSubmodules(IWin32Window win)
  1149. {
  1150. if (!Module.HasSubmodules())
  1151. return;
  1152. var updateSubmodules = AppSettings.UpdateSubmodulesOnCheckout ?? MessageBoxes.ConfirmUpdateSubmodules(win);
  1153. if (updateSubmodules)
  1154. StartUpdateSubmodulesDialog(win);
  1155. }
  1156. public bool StartPluginSettingsDialog(IWin32Window owner)
  1157. {
  1158. return StartSettingsDialog(owner, PluginsSettingsGroup.GetPageReference());
  1159. }
  1160. public bool StartPluginSettingsDialog()
  1161. {
  1162. return StartPluginSettingsDialog(null);
  1163. }
  1164. public bool StartRepoSettingsDialog(IWin32Window owner)
  1165. {
  1166. return StartSettingsDialog(owner, GitUI.CommandsDialogs.SettingsDialog.Pages.GitConfigSettingsPage.GetPageReference());
  1167. }
  1168. public bool StartBrowseDialog(IWin32Window owner, string filter)
  1169. {
  1170. if (!InvokeEvent(owner, PreBrowse))
  1171. return false;
  1172. var form = new FormBrowse(this, filter);
  1173. Application.Run(form);
  1174. InvokeEvent(owner, PostBrowse);
  1175. return true;
  1176. }
  1177. public bool StartBrowseDialog(string filter)
  1178. {
  1179. return StartBrowseDialog(null, filter);
  1180. }
  1181. public void StartFileHistoryDialog(IWin32Window owner, string fileName, GitRevision revision, bool filterByRevision, bool showBlame)
  1182. {
  1183. Func<Form> provideForm = () =>
  1184. {
  1185. var form = new FormFileHistory(this, fileName, revision, filterByRevision);
  1186. if (showBlame)
  1187. form.SelectBlameTab();
  1188. return form;
  1189. };
  1190. ShowModelessForm(owner, true, PreFileHistory, PostFileHistory, provideForm);
  1191. }
  1192. public void StartFileHistoryDialog(IWin32Window owner, string fileName, GitRevision revision, bool filterByRevision)
  1193. {
  1194. StartFileHistoryDialog(owner, fileName, revision, filterByRevision, false);
  1195. }
  1196. public void StartFileHistoryDialog(IWin32Window owner, string fileName, GitRevision revision)
  1197. {
  1198. StartFileHistoryDialog(owner, fileName, revision, false);
  1199. }
  1200. public void StartFileHistoryDialog(IWin32Window owner, string fileName)
  1201. {
  1202. StartFileHistoryDialog(owner, fileName, null, false);
  1203. }
  1204. public void StartFileHistoryDialog(string fileName, GitRevision revision)
  1205. {
  1206. StartFileHistoryDialog(null, fileName, revision, false);
  1207. }
  1208. public void StartFileHistoryDialog(string fileName)
  1209. {
  1210. StartFileHistoryDialog(fileName, null);
  1211. }
  1212. public bool StartPushDialog()
  1213. {

Large files files are truncated, but you can click here to view the full file