PageRenderTime 65ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 0ms

/GitUI/FormPull.cs

https://github.com/jotux/gitextensions
C# | 389 lines | 310 code | 70 blank | 9 comment | 61 complexity | 08c172968f82c4d5b27d77f48447ec3e MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.IO;
  5. using System.Windows.Forms;
  6. using GitCommands;
  7. using GitCommands.Repository;
  8. using GitUI.Properties;
  9. using ResourceManager.Translation;
  10. using Settings = GitCommands.Settings;
  11. using GitUI.Script;
  12. namespace GitUI
  13. {
  14. public partial class FormPull : GitExtensionsForm
  15. {
  16. private const string PuttyCaption = "PuTTY";
  17. private readonly TranslationString _allMergeConflictSolvedQuestion =
  18. new TranslationString("Are all merge conflicts solved? Do you want to commit?");
  19. private readonly TranslationString _allMergeConflictSolvedQuestionCaption =
  20. new TranslationString("Conflicts solved");
  21. private readonly TranslationString _applyShashedItemsAgain =
  22. new TranslationString("Apply stashed items to working dir again?");
  23. private readonly TranslationString _applyShashedItemsAgainCaption =
  24. new TranslationString("Auto stash");
  25. private readonly TranslationString _cannotLoadPutty =
  26. new TranslationString("Cannot load SSH key. PuTTY is not configured properly.");
  27. private readonly TranslationString _fetchAllBranchesCanOnlyWithFetch =
  28. new TranslationString("You can only fetch all remote branches (*) without merge or rebase." +
  29. Environment.NewLine + "If you want to fetch all remote branches, choose fetch." +
  30. Environment.NewLine +
  31. "If you want to fetch and merge a branch, choose a specific branch.");
  32. private readonly TranslationString _selectRemoteRepository =
  33. new TranslationString("Please select a remote repository");
  34. private readonly TranslationString _selectSourceDirectory =
  35. new TranslationString("Please select a source directory");
  36. private List<GitHead> _heads;
  37. public FormPull()
  38. {
  39. InitializeComponent();
  40. Translate();
  41. IList<string> remotes = new List<string>(GitCommandHelpers.GetRemotes());
  42. remotes.Insert(0, "[ All ]");
  43. Remotes.DataSource = remotes;
  44. string branch = GitCommandHelpers.GetSelectedBranch();
  45. Remotes.Text = GitCommandHelpers.GetSetting(string.Format("branch.{0}.remote", branch));
  46. _NO_TRANSLATE_localBranch.Text = branch;
  47. Merge.Checked = Settings.PullMerge == "merge";
  48. Rebase.Checked = Settings.PullMerge == "rebase";
  49. Fetch.Checked = Settings.PullMerge == "fetch";
  50. AutoStash.Checked = Settings.AutoStash;
  51. }
  52. public void PullAndShowDialogWhenFailed()
  53. {
  54. if (!PullChanges())
  55. ShowDialog();
  56. }
  57. private void BrowseSourceClick(object sender, EventArgs e)
  58. {
  59. var dialog = new FolderBrowserDialog { SelectedPath = PullSource.Text };
  60. if (dialog.ShowDialog() == DialogResult.OK)
  61. PullSource.Text = dialog.SelectedPath;
  62. }
  63. private void MergetoolClick(object sender, EventArgs e)
  64. {
  65. GitCommandHelpers.RunRealCmd(Settings.GitCommand, "mergetool");
  66. if (MessageBox.Show(_allMergeConflictSolvedQuestion.Text, _allMergeConflictSolvedQuestionCaption.Text,
  67. MessageBoxButtons.YesNo) != DialogResult.Yes)
  68. return;
  69. new FormCommit().ShowDialog();
  70. }
  71. private void BranchesDropDown(object sender, EventArgs e)
  72. {
  73. if ((PullFromUrl.Checked && string.IsNullOrEmpty(PullSource.Text)) &&
  74. (PullFromRemote.Checked && string.IsNullOrEmpty(Remotes.Text)))
  75. {
  76. Branches.DataSource = null;
  77. return;
  78. }
  79. Cursor.Current = Cursors.WaitCursor;
  80. LoadPuttyKey();
  81. if (_heads == null)
  82. {
  83. if (PullFromUrl.Checked)
  84. {
  85. _heads = GitCommandHelpers.GetHeads(false, true);
  86. }
  87. else
  88. {
  89. // The line below is the most reliable way to get a list containing
  90. // all remote branches but it is also the slowest.
  91. // Heads = GitCommands.GitCommands.GetRemoteHeads(Remotes.Text, false, true);
  92. // The code below is a quick way to get a list containg all remote branches.
  93. // It only returns the heads that are allready known to the repository. This
  94. // doesn't return heads that are new on the server. This can be updated using
  95. // update branch info in the manage remotes dialog.
  96. _heads = new List<GitHead>();
  97. foreach (var head in GitCommandHelpers.GetHeads(true, true))
  98. {
  99. if (!head.IsRemote ||
  100. !head.Name.StartsWith(Remotes.Text, StringComparison.CurrentCultureIgnoreCase))
  101. continue;
  102. _heads.Insert(0, head);
  103. }
  104. }
  105. }
  106. Branches.DisplayMember = "LocalName";
  107. //_heads.Insert(0, GitHead.AllHeads); --> disable this because it is only for expert users
  108. _heads.Insert(0, GitHead.NoHead);
  109. Branches.DataSource = _heads;
  110. Cursor.Current = Cursors.Default;
  111. }
  112. private void PullClick(object sender, EventArgs e)
  113. {
  114. if (PullChanges())
  115. Close();
  116. }
  117. public bool PullChanges()
  118. {
  119. if (PullFromUrl.Checked && string.IsNullOrEmpty(PullSource.Text))
  120. {
  121. MessageBox.Show(_selectSourceDirectory.Text);
  122. return false;
  123. }
  124. if (PullFromRemote.Checked && string.IsNullOrEmpty(Remotes.Text) && !PullAll())
  125. {
  126. MessageBox.Show(_selectRemoteRepository.Text);
  127. return false;
  128. }
  129. if (!Fetch.Checked && Branches.Text == "*")
  130. {
  131. MessageBox.Show(_fetchAllBranchesCanOnlyWithFetch.Text);
  132. return false;
  133. }
  134. if (Merge.Checked)
  135. Settings.PullMerge = "merge";
  136. if (Rebase.Checked)
  137. Settings.PullMerge = "rebase";
  138. if (Fetch.Checked)
  139. Settings.PullMerge = "fetch";
  140. Settings.AutoStash = AutoStash.Checked;
  141. Repositories.RepositoryHistory.AddMostRecentRepository(PullSource.Text);
  142. string source;
  143. if (PullFromUrl.Checked)
  144. source = PullSource.Text;
  145. else
  146. {
  147. LoadPuttyKey();
  148. source = PullAll() ? "--all" : Remotes.Text;
  149. }
  150. ScriptManager.RunEventScripts(ScriptEvent.BeforePull);
  151. var stashed = false;
  152. if (!Fetch.Checked && AutoStash.Checked && GitCommandHelpers.GitStatus(false).Count > 0)
  153. {
  154. new FormProcess("stash save").ShowDialog();
  155. stashed = true;
  156. }
  157. FormProcess process = null;
  158. if (Fetch.Checked)
  159. {
  160. process = new FormProcess(GitCommandHelpers.FetchCmd(source, Branches.Text, null));
  161. }
  162. else
  163. {
  164. string localBranch = GitCommandHelpers.GetSelectedBranch();
  165. if (localBranch.Equals("(no branch)", StringComparison.OrdinalIgnoreCase) || string.IsNullOrEmpty(Branches.Text))
  166. localBranch = null;
  167. if (Merge.Checked)
  168. process = new FormProcess(GitCommandHelpers.PullCmd(source, Branches.Text, localBranch, false));
  169. else if (Rebase.Checked)
  170. process = new FormProcess(GitCommandHelpers.PullCmd(source, Branches.Text, localBranch, true));
  171. }
  172. if (process != null)
  173. process.ShowDialog();
  174. try
  175. {
  176. if (!GitCommandHelpers.InTheMiddleOfConflictedMerge() &&
  177. !GitCommandHelpers.InTheMiddleOfRebase() &&
  178. (process != null && !process.ErrorOccurred()))
  179. {
  180. return true;
  181. }
  182. // Rebase failed -> special 'rebase' merge conflict
  183. if (Rebase.Checked && GitCommandHelpers.InTheMiddleOfRebase())
  184. {
  185. GitUICommands.Instance.StartRebaseDialog(null);
  186. if (!GitCommandHelpers.InTheMiddleOfConflictedMerge() &&
  187. !GitCommandHelpers.InTheMiddleOfRebase())
  188. {
  189. return true;
  190. }
  191. }
  192. else
  193. {
  194. MergeConflictHandler.HandleMergeConflicts();
  195. if (!GitCommandHelpers.InTheMiddleOfConflictedMerge() &&
  196. !GitCommandHelpers.InTheMiddleOfRebase())
  197. {
  198. return true;
  199. }
  200. }
  201. if (!AutoStash.Checked || !stashed || GitCommandHelpers.InTheMiddleOfConflictedMerge() ||
  202. GitCommandHelpers.InTheMiddleOfRebase())
  203. {
  204. return true;
  205. }
  206. }
  207. finally
  208. {
  209. if (stashed &&
  210. process != null &&
  211. !process.ErrorOccurred() &&
  212. !GitCommandHelpers.InTheMiddleOfConflictedMerge() &&
  213. !GitCommandHelpers.InTheMiddleOfRebase() &&
  214. MessageBox.Show(_applyShashedItemsAgain.Text, _applyShashedItemsAgainCaption.Text, MessageBoxButtons.YesNo) == DialogResult.Yes)
  215. {
  216. new FormProcess("stash pop").ShowDialog();
  217. MergeConflictHandler.HandleMergeConflicts();
  218. }
  219. ScriptManager.RunEventScripts(ScriptEvent.AfterPull);
  220. }
  221. return false;
  222. }
  223. private void LoadPuttyKey()
  224. {
  225. if (!GitCommandHelpers.Plink())
  226. return;
  227. if (File.Exists(Settings.Pageant))
  228. GitCommandHelpers.StartPageantForRemote(Remotes.Text);
  229. else
  230. MessageBox.Show(_cannotLoadPutty.Text, PuttyCaption);
  231. }
  232. private void FormPullLoad(object sender, EventArgs e)
  233. {
  234. Remotes.Select();
  235. Text = string.Format("Pull ({0})", Settings.WorkingDir);
  236. }
  237. protected override void OnShown(EventArgs e)
  238. {
  239. base.OnShown(e);
  240. }
  241. private void PullSourceDropDown(object sender, EventArgs e)
  242. {
  243. PullSource.DataSource = Repositories.RepositoryHistory.Repositories;
  244. PullSource.DisplayMember = "Path";
  245. }
  246. private void StashClick(object sender, EventArgs e)
  247. {
  248. GitUICommands.Instance.StartStashDialog();
  249. }
  250. private void PullFromRemoteCheckedChanged(object sender, EventArgs e)
  251. {
  252. if (!PullFromRemote.Checked)
  253. return;
  254. ResetRemoteHeads();
  255. PullSource.Enabled = false;
  256. BrowseSource.Enabled = false;
  257. Remotes.Enabled = true;
  258. AddRemote.Enabled = true;
  259. Merge.Enabled = !PullAll();
  260. Rebase.Enabled = !PullAll();
  261. }
  262. private bool PullAll()
  263. {
  264. return Remotes.Text.Equals("[ All ]", StringComparison.InvariantCultureIgnoreCase);
  265. }
  266. private void PullFromUrlCheckedChanged(object sender, EventArgs e)
  267. {
  268. if (!PullFromUrl.Checked)
  269. return;
  270. ResetRemoteHeads();
  271. PullSource.Enabled = true;
  272. BrowseSource.Enabled = true;
  273. Remotes.Enabled = false;
  274. AddRemote.Enabled = false;
  275. Merge.Enabled = true;
  276. Rebase.Enabled = true;
  277. }
  278. private void AddRemoteClick(object sender, EventArgs e)
  279. {
  280. GitUICommands.Instance.StartRemotesDialog();
  281. }
  282. private void MergeCheckedChanged(object sender, EventArgs e)
  283. {
  284. PullImage.BackgroundImage = Resources.merge;
  285. }
  286. private void RebaseCheckedChanged(object sender, EventArgs e)
  287. {
  288. PullImage.BackgroundImage = Resources.Rebase;
  289. }
  290. private void FetchCheckedChanged(object sender, EventArgs e)
  291. {
  292. PullImage.BackgroundImage = Resources.fetch;
  293. }
  294. private void PullSourceValidating(object sender, CancelEventArgs e)
  295. {
  296. ResetRemoteHeads();
  297. }
  298. private void Remotes_TextChanged(object sender, EventArgs e)
  299. {
  300. RemotesValidating(null, null);
  301. }
  302. private void RemotesValidating(object sender, CancelEventArgs e)
  303. {
  304. ResetRemoteHeads();
  305. Merge.Enabled = !PullAll();
  306. Rebase.Enabled = !PullAll();
  307. if (PullAll())
  308. Fetch.Checked = true;
  309. }
  310. private void ResetRemoteHeads()
  311. {
  312. if (PullAll())
  313. {
  314. }
  315. Branches.DataSource = null;
  316. _heads = null;
  317. }
  318. }
  319. }