/// <summary> /// Create or clone a new git repository. /// If the Tag field is non-empty, it contains the Repo to clone. /// </summary> private void MenuNewRepoClick(object sender, EventArgs e) { FormNewRepoStep1 newRepoStep1 = new FormNewRepoStep1(); FormNewRepoStep2 newRepoStep2 = new FormNewRepoStep2(); // If we need to clone a repo, set the cloning parameters within the Step1 form ClassRepo repoToClone = ((ToolStripDropDownItem) sender).Tag as ClassRepo; if (repoToClone!=null) { newRepoStep1.Type = "local"; newRepoStep1.Local = repoToClone.ToString(); } BackToStep1: if (newRepoStep1.ShowDialog() == DialogResult.OK) { // For clone operation, apply extra directory rules: // The final directory has to exist and be empty, but the user can also // specify additional 'project name' and that directory will be created newRepoStep2.SetForCloneOperation(newRepoStep1.Type != "empty"); BackToStep2: DialogResult result = newRepoStep2.ShowDialog(); // Clicking on the <<Prev button will return "Retry" result, so we loop back to the first form... if (result == DialogResult.Retry) goto BackToStep1; if (result == DialogResult.OK) { string type = newRepoStep1.Type; string root = newRepoStep2.Destination; string extra = newRepoStep2.Extra; bool isBare = newRepoStep2.IsBare; try { string init = ""; switch (type) { case "empty": init = "init \"" + root + "\"" + (isBare ? " --bare --shared=all " : " ") + extra; break; case "local": init = "clone " + newRepoStep1.Local + " \"" + root + "\"" + (isBare ? " --bare --shared " : " ") + extra; break; case "remote": ClassRemotes.Remote r = newRepoStep1.Remote; init = "clone --progress -v --origin " + r.Name + " " + r.UrlFetch + " \"" + root + "\"" + (isBare ? " --bare --shared " : " ") + extra; // Add HTTPS password for the next execute of a clone operation ClassUtils.AddEnvar("PASSWORD", r.Password); break; } // Get out of the way (so the git can remove directory if the clone operation fails) Directory.SetCurrentDirectory(App.AppHome); if(ClassGit.Run(init).Success()==false) goto BackToStep2; ClassRepo repo = App.Repos.Add(root); // Switch the view mode to Local File View and Local Pending Changelists App.MainForm.ResetViews(); // Finally, switch to the new repo and do a global refresh App.Repos.SetCurrent(repo); App.DoRefresh(); return; } catch (ClassException ex) { if (MessageBox.Show(ex.Message, "Error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error)== DialogResult.Cancel) return; } goto BackToStep2; } } }
/// <summary> /// Global static function that executes a new repo wizard /// If successful, returns the path to the new local repo /// If failed, returns null /// </summary> public static string NewRepoWizard(ClassRepo repoToClone, ClassRepo repoRemote, string folder) { FormNewRepoStep1 newRepoStep1 = new FormNewRepoStep1(); FormNewRepoStep2 newRepoStep2 = new FormNewRepoStep2(); // If the repo to clone parameter was given, build the close repo information if (repoToClone != null) { newRepoStep1.Type = "local"; newRepoStep1.Local = repoToClone.ToString(); } // If the remote repo parameter was given, build the remote repo information if (repoRemote != null) { // If the list of remotes contains at least one entry, use it List <string> remotes = repoRemote.Remotes.GetRemoteNames(); if (remotes.Count > 0) { newRepoStep1.Type = "remote"; ClassRemotes.Remote remote = repoRemote.Remotes.Get(remotes[0]); newRepoStep1.SetRemote(remote); } else { newRepoStep2.Destination = repoRemote.Path; } } // If the folder parameter was given, create a new local repo at that path bool skipStep1 = !string.IsNullOrEmpty(folder); // In this case, we will skip step 1 newRepoStep2.Destination = folder ?? ""; // and assign the folder path to the step 2 dialog BackToStep1: if (skipStep1 || newRepoStep1.ShowDialog() == DialogResult.OK) { // Depending on the type of the source, establish that: // For clone operations: // - The final directory has to exist and be empty // - New repo name will be suggested based on the source project names switch (newRepoStep1.Type) { case "empty": newRepoStep2.ProjectName = ""; newRepoStep2.CheckTargetDirEmpty = false; break; case "local": // Find the project name from the cloned path (the last part of the path) string[] parts = newRepoStep1.Local.Split(new char[] { '\\', '/' }); if (parts.Length > 1) { newRepoStep2.ProjectName = parts[parts.Length - 1]; } newRepoStep2.Destination = ""; newRepoStep2.CheckTargetDirEmpty = true; break; case "remote": ClassRemotes.Remote r = newRepoStep1.Remote; string remoteProjectName = r.UrlFetch; // Extract the project name from the remote Url specification parts = remoteProjectName.Split(new char[] { '.', '\\', '/', ':' }); if (parts.Length > 1 && parts[parts.Length - 1] == "git") { newRepoStep2.ProjectName = parts[parts.Length - 2]; } // If the project name is equal to the last part of the path, use it for the project name instead // and trim the path. This is done to (1) propagate possible upper-cased letters in the // path and (2) to fix the cases where we have given repoRemote with a full path which included // a redundant project name. // Example: root: c:\Projects\Arduino => c:\Projects // project name: arduino => Arduino parts = newRepoStep2.Destination.Split(new char[] { '\\', '/' }); if (parts.Length > 1 && String.Compare(parts[parts.Length - 1], newRepoStep2.ProjectName, StringComparison.OrdinalIgnoreCase) == 0) { newRepoStep2.ProjectName = parts[parts.Length - 1]; newRepoStep2.Destination = Directory.GetParent(newRepoStep2.Destination).FullName; } newRepoStep2.CheckTargetDirEmpty = true; break; } BackToStep2: DialogResult result = newRepoStep2.ShowDialog(); // Clicking on the <<Prev button will return "Retry" result, so we loop back to the first form... skipStep1 = false; if (result == DialogResult.Retry) { goto BackToStep1; } if (result == DialogResult.OK) { string type = newRepoStep1.Type; string root = newRepoStep2.Destination; string extra = newRepoStep2.Extra; bool isBare = newRepoStep2.IsBare; try { string init = ""; ClassUtils.AddEnvar("PASSWORD", ""); // Clear the HTTPS password switch (type) { case "empty": init = "init \"" + root + "\"" + (isBare ? " --bare --shared=all " : " ") + extra; break; case "local": init = "clone " + newRepoStep1.Local + " \"" + root + "\"" + (isBare ? " --bare --shared " : " ") + extra; break; case "remote": ClassRemotes.Remote r = newRepoStep1.Remote; init = "clone --progress -v --origin " + r.Name + " " + r.UrlFetch + " \"" + root + "\"" + (isBare ? " --bare --shared " : " ") + extra; // Add HTTPS password for the next execute of a clone operation ClassUtils.AddEnvar("PASSWORD", r.Password); break; } // Get out of the way (so the git can remove directory if the clone operation fails) Directory.SetCurrentDirectory(App.AppHome); if (ClassGit.Run(init).Success() == false) { goto BackToStep2; } return(root); } catch (ClassException ex) { if (MessageBox.Show(ex.Message, "Error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error) == DialogResult.Cancel) { return(string.Empty); } } goto BackToStep2; } } return(string.Empty); }
/// <summary> /// Global static function that executes a new repo wizard /// If successful, returns the path to the new local repo /// If failed, returns null /// </summary> public static string NewRepoWizard(ClassRepo repoToClone, ClassRepo repoRemote) { FormNewRepoStep1 newRepoStep1 = new FormNewRepoStep1(); FormNewRepoStep2 newRepoStep2 = new FormNewRepoStep2(); // If the repo to clone parameter was given, build the close repo information if (repoToClone != null) { newRepoStep1.Type = "local"; newRepoStep1.Local = repoToClone.ToString(); } // If the remote repo parameter was given, build the remote repo information if (repoRemote != null) { // If the list of remotes contains at least one entry, use it List<string> remotes = repoRemote.Remotes.GetRemoteNames(); if (remotes.Count > 0) { newRepoStep1.Type = "remote"; ClassRemotes.Remote remote = repoRemote.Remotes.Get(remotes[0]); newRepoStep1.SetRemote(remote); } else newRepoStep2.Destination = repoRemote.Root; } BackToStep1: if (newRepoStep1.ShowDialog() == DialogResult.OK) { // Depending on the type of the source, establish that: // For clone operations: // - The final directory has to exist and be empty // - New repo name will be suggested based on the source project names switch (newRepoStep1.Type) { case "empty": newRepoStep2.ProjectName = ""; newRepoStep2.CheckTargetDirEmpty = false; break; case "local": // Find the project name from the cloned path (the last part of the path) string[] parts = newRepoStep1.Local.Split(new char[] { '\\', '/' }); if (parts.Length > 1) newRepoStep2.ProjectName = parts[parts.Length - 1]; newRepoStep2.Destination = ""; newRepoStep2.CheckTargetDirEmpty = true; break; case "remote": ClassRemotes.Remote r = newRepoStep1.Remote; string remoteProjectName = r.UrlFetch; // Extract the project name from the remote Url specification parts = remoteProjectName.Split(new char[] { '.', '\\', '/', ':' }); if (parts.Length > 1 && parts[parts.Length - 1] == "git") newRepoStep2.ProjectName = parts[parts.Length - 2]; // If the project name is equal to the last part of the path, use it for the project name instead // and trim the path. This is done to (1) propagate possible upper-cased letters in the // path and (2) to fix the cases where we have given repoRemote with a full path which included // a redundant project name. // Example: root: c:\Projects\Arduino => c:\Projects // project name: arduino => Arduino parts = newRepoStep2.Destination.Split(new char[] { '\\', '/' }); if (parts.Length > 1 && String.Compare(parts[parts.Length - 1], newRepoStep2.ProjectName, StringComparison.OrdinalIgnoreCase) == 0) { newRepoStep2.ProjectName = parts[parts.Length - 1]; newRepoStep2.Destination = Directory.GetParent(newRepoStep2.Destination).FullName; } newRepoStep2.CheckTargetDirEmpty = true; break; } BackToStep2: DialogResult result = newRepoStep2.ShowDialog(); // Clicking on the <<Prev button will return "Retry" result, so we loop back to the first form... if (result == DialogResult.Retry) goto BackToStep1; if (result == DialogResult.OK) { string type = newRepoStep1.Type; string root = newRepoStep2.Destination; string extra = newRepoStep2.Extra; bool isBare = newRepoStep2.IsBare; try { string init = ""; switch (type) { case "empty": init = "init \"" + root + "\"" + (isBare ? " --bare --shared=all " : " ") + extra; break; case "local": init = "clone " + newRepoStep1.Local + " \"" + root + "\"" + (isBare ? " --bare --shared " : " ") + extra; break; case "remote": ClassRemotes.Remote r = newRepoStep1.Remote; init = "clone --progress -v --origin " + r.Name + " " + r.UrlFetch + " \"" + root + "\"" + (isBare ? " --bare --shared " : " ") + extra; // Add HTTPS password for the next execute of a clone operation ClassUtils.AddEnvar("PASSWORD", r.Password); break; } // Get out of the way (so the git can remove directory if the clone operation fails) Directory.SetCurrentDirectory(App.AppHome); if (ClassGit.Run(init).Success() == false) goto BackToStep2; return root; } catch (ClassException ex) { if (MessageBox.Show(ex.Message, "Error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error) == DialogResult.Cancel) return string.Empty; } goto BackToStep2; } } return string.Empty; }