public override Task UpdateAsync(GitUpdateOptions options) { this.log.LogDebug($"Using repository at '{this.repository.LocalRepositoryPath}'..."); using (var repository = new Repository(this.repository.LocalRepositoryPath)) { this.log.LogDebug("Fetching commits from origin..."); repository.Fetch("origin", new FetchOptions { CredentialsProvider = CredentialsHandler, Prune = true }); var refName = "FETCH_HEAD"; if (options.Branch != null) { refName = "origin/" + options.Branch; } else if (options.Tag != null) { refName = "origin/" + options.Tag; } this.log.LogDebug($"Resetting the index and working tree to {refName}..."); repository.Reset(ResetMode.Hard, refName); repository.RemoveUntrackedFiles(); if (options.RecurseSubmodules) { foreach (var submodule in repository.Submodules) { repository.Submodules.Update(submodule.Name, new SubmoduleUpdateOptions { CredentialsProvider = CredentialsHandler, Init = true }); } } } return(Complete); }
public async override Task UpdateAsync(GitUpdateOptions options) { await this.ExecuteRemoteAsync( ClientCommand.Update, new RemoteLibGitSharpContext { UpdateOptions = options } ).ConfigureAwait(false); }
public override async Task <string> UpdateAsync(GitUpdateOptions options) { /* * git remote set-url origin <url> | Make sure we're talking to the correct remote repository * git fetch origin | Update the local cache of the remote repository * git reset --hard <ref> | Resets to the HEAD revision and removes commits that haven't been pushed * git clean -dfq | Remove all non-Git versioned files and directories from the repository working directory * git submodule update --init --recursive | Updates submodules to the version referenced by the HEAD revision */ var remoteArgs = new GitArgumentsBuilder("remote set-url origin"); remoteArgs.AppendSensitive(this.repository.GetRemoteUrlWithCredentials()); await this.ExecuteCommandLineAsync(remoteArgs, this.repository.LocalRepositoryPath).ConfigureAwait(false); await this.ExecuteCommandLineAsync(new GitArgumentsBuilder("fetch origin"), this.repository.LocalRepositoryPath).ConfigureAwait(false); var resetArgs = new GitArgumentsBuilder("reset --hard"); if (options.Ref != null) { resetArgs.AppendQuoted(options.Ref); } else if (options.Branch != null) { resetArgs.AppendQuoted("origin/" + options.Branch); } else { resetArgs.Append("FETCH_HEAD"); } await this.ExecuteCommandLineAsync( resetArgs, this.repository.LocalRepositoryPath ).ConfigureAwait(false); await this.ExecuteCommandLineAsync( new GitArgumentsBuilder("clean -dfq"), this.repository.LocalRepositoryPath ).ConfigureAwait(false); if (options.RecurseSubmodules) { await this.ExecuteCommandLineAsync( new GitArgumentsBuilder("submodule update --init --recursive"), this.repository.LocalRepositoryPath ).ConfigureAwait(false); } var results = await this.ExecuteCommandLineAsync( new GitArgumentsBuilder("log -n 1 --format=%H"), this.repository.LocalRepositoryPath ).ConfigureAwait(false); return(string.Join(" ", results.Output).Trim()); }
public override Task <string> UpdateAsync(GitUpdateOptions options) { try { this.log.LogDebug($"Using repository at '{this.repository.LocalRepositoryPath}'..."); using (var repository = new Repository(this.repository.LocalRepositoryPath)) { this.log.LogDebug("Fetching commits from origin..."); Commands.Fetch(repository, "origin", new string[0], new FetchOptions { CredentialsProvider = this.CredentialsHandler, Prune = true }, null); var refName = "FETCH_HEAD"; if (options.Branch != null) { refName = "origin/" + options.Branch; } else if (options.Ref != null) { refName = options.Ref; } this.log.LogDebug($"Resetting the index and working tree to {refName}..."); repository.Reset(ResetMode.Hard, refName); repository.RemoveUntrackedFiles(); if (options.RecurseSubmodules) { foreach (var submodule in repository.Submodules) { repository.Submodules.Update(submodule.Name, new SubmoduleUpdateOptions { CredentialsProvider = this.CredentialsHandler, Init = true }); } } return(Task.FromResult(repository.Head?.Tip?.Sha)); } } catch (Exception ex) { // gitsharp exceptions are not always serializable throw new ExecutionFailureException("Update failed: " + ex.Message); } finally { this.EndOperation(); } }
public void Merge (string branch, GitUpdateOptions options, IProgressMonitor monitor) { IEnumerable<DiffEntry> statusList = null; Stash stash = null; StashCollection stashes = GetStashes (RootRepository); NGit.Api.Git git = new NGit.Api.Git (RootRepository); try { monitor.BeginTask (GettextCatalog.GetString ("Merging"), 5); List<string> UpdateSubmodules = new List<string> (); // TODO: Fix stash so we don't have to do update before the main repo update. if ((options & GitUpdateOptions.UpdateSubmodules) == GitUpdateOptions.UpdateSubmodules) { monitor.Log.WriteLine (GettextCatalog.GetString ("Checking repository submodules")); if (!GetSubmodulesToUpdate (UpdateSubmodules)) return; monitor.Log.WriteLine (GettextCatalog.GetString ("Updating repository submodules")); var submoduleUpdate = git.SubmoduleUpdate (); foreach (var submodule in UpdateSubmodules) submoduleUpdate.AddPath (submodule); submoduleUpdate.Call (); monitor.Step (1); } // Get a list of files that are different in the target branch statusList = GitUtil.GetChangedFiles (RootRepository, branch); monitor.Step (1); if ((options & GitUpdateOptions.SaveLocalChanges) != GitUpdateOptions.SaveLocalChanges) { const VersionStatus unclean = VersionStatus.Modified | VersionStatus.ScheduledAdd | VersionStatus.ScheduledDelete; bool modified = false; if (GetDirectoryVersionInfo (RootPath, false, true).Any (v => (v.Status & unclean) != VersionStatus.Unversioned)) modified = true; if (modified) { if (MessageService.GenericAlert ( MonoDevelop.Ide.Gui.Stock.Question, GettextCatalog.GetString ("You have uncommitted changes"), GettextCatalog.GetString ("What do you want to do?"), AlertButton.Cancel, new AlertButton ("Stash")) == AlertButton.Cancel) return; options |= GitUpdateOptions.SaveLocalChanges; } } if ((options & GitUpdateOptions.SaveLocalChanges) == GitUpdateOptions.SaveLocalChanges) { monitor.Log.WriteLine (GettextCatalog.GetString ("Saving local changes")); using (var gm = new GitMonitor (monitor)) stash = stashes.Create (gm, GetStashName ("_tmp_")); monitor.Step (1); } // Apply changes ObjectId branchId = RootRepository.Resolve (branch); MergeCommandResult mergeResult = git.Merge ().SetStrategy (MergeStrategy.RESOLVE).Include (branchId).Call (); if (mergeResult.GetMergeStatus () == MergeStatus.CONFLICTING || mergeResult.GetMergeStatus () == MergeStatus.FAILED) { var conflicts = mergeResult.GetConflicts (); bool commit = true; if (conflicts != null) { foreach (string conflictFile in conflicts.Keys) { ConflictResult res = ResolveConflict (RootRepository.FromGitPath (conflictFile)); if (res == ConflictResult.Abort) { GitUtil.HardReset (RootRepository, GetHeadCommit (RootRepository)); commit = false; break; } else if (res == ConflictResult.Skip) { Revert (RootRepository.FromGitPath (conflictFile), false, monitor); break; } } } if (commit) git.Commit ().Call (); } if ((options & GitUpdateOptions.UpdateSubmodules) == GitUpdateOptions.UpdateSubmodules) { monitor.Log.WriteLine (GettextCatalog.GetString ("Updating repository submodules")); var submoduleUpdate = git.SubmoduleUpdate (); foreach (var submodule in CachedSubmodules) submoduleUpdate.AddPath (submodule.Item1); submoduleUpdate.Call (); monitor.Step (1); } } finally { if ((options & GitUpdateOptions.SaveLocalChanges) == GitUpdateOptions.SaveLocalChanges) monitor.Step (1); // Restore local changes if (stash != null) { monitor.Log.WriteLine (GettextCatalog.GetString ("Restoring local changes")); using (var gm = new GitMonitor (monitor)) stash.Apply (gm); stashes.Remove (stash); monitor.Step (1); } monitor.EndTask (); } // Notify changes if (statusList != null) NotifyFileChanges (monitor, statusList); }
public void Rebase (string upstreamRef, GitUpdateOptions options, IProgressMonitor monitor) { StashCollection stashes = GitUtil.GetStashes (RootRepository); Stash stash = null; NGit.Api.Git git = new NGit.Api.Git (RootRepository); try { monitor.BeginTask (GettextCatalog.GetString ("Rebasing"), 5); List<string> UpdateSubmodules = new List<string> (); // TODO: Fix stash so we don't have to do update before the main repo update. if ((options & GitUpdateOptions.UpdateSubmodules) == GitUpdateOptions.UpdateSubmodules) { monitor.Log.WriteLine (GettextCatalog.GetString ("Checking repository submodules")); if (!GetSubmodulesToUpdate (UpdateSubmodules)) return; monitor.Log.WriteLine (GettextCatalog.GetString ("Updating repository submodules")); var submoduleUpdate = git.SubmoduleUpdate (); foreach (var submodule in UpdateSubmodules) submoduleUpdate.AddPath (submodule); submoduleUpdate.Call (); monitor.Step (1); } if ((options & GitUpdateOptions.SaveLocalChanges) != GitUpdateOptions.SaveLocalChanges) { const VersionStatus unclean = VersionStatus.Modified | VersionStatus.ScheduledAdd | VersionStatus.ScheduledDelete; bool modified = false; if (GetDirectoryVersionInfo (RootPath, false, true).Any (v => (v.Status & unclean) != VersionStatus.Unversioned)) modified = true; if (modified) { if (MessageService.GenericAlert ( MonoDevelop.Ide.Gui.Stock.Question, GettextCatalog.GetString ("You have uncommitted changes"), GettextCatalog.GetString ("What do you want to do?"), AlertButton.Cancel, new AlertButton ("Stash")) == AlertButton.Cancel) return; options |= GitUpdateOptions.SaveLocalChanges; } } if ((options & GitUpdateOptions.SaveLocalChanges) == GitUpdateOptions.SaveLocalChanges) { monitor.Log.WriteLine (GettextCatalog.GetString ("Saving local changes")); using (var gm = new GitMonitor (monitor)) stash = stashes.Create (gm, GetStashName ("_tmp_")); monitor.Step (1); } RebaseCommand rebase = git.Rebase (); rebase.SetOperation (RebaseCommand.Operation.BEGIN); rebase.SetUpstream (upstreamRef); var gmonitor = new GitMonitor (monitor); rebase.SetProgressMonitor (gmonitor); bool aborted = false; try { var result = rebase.Call (); while (!aborted && result.GetStatus () == RebaseResult.Status.STOPPED) { rebase = git.Rebase (); rebase.SetProgressMonitor (gmonitor); rebase.SetOperation (RebaseCommand.Operation.CONTINUE); bool commitChanges = true; var conflicts = GitUtil.GetConflictedFiles (RootRepository); foreach (string conflictFile in conflicts) { ConflictResult res = ResolveConflict (RootRepository.FromGitPath (conflictFile)); if (res == ConflictResult.Abort) { aborted = true; commitChanges = false; rebase.SetOperation (RebaseCommand.Operation.ABORT); break; } else if (res == ConflictResult.Skip) { rebase.SetOperation (RebaseCommand.Operation.SKIP); commitChanges = false; break; } } if (commitChanges) { NGit.Api.AddCommand cmd = git.Add (); foreach (string conflictFile in conflicts) cmd.AddFilepattern (conflictFile); cmd.Call (); } result = rebase.Call (); } if ((options & GitUpdateOptions.UpdateSubmodules) == GitUpdateOptions.UpdateSubmodules) { monitor.Log.WriteLine (GettextCatalog.GetString ("Updating repository submodules")); var submoduleUpdate = git.SubmoduleUpdate (); foreach (var submodule in UpdateSubmodules) submoduleUpdate.AddPath (submodule); submoduleUpdate.Call (); } } catch { if (!aborted) { rebase = git.Rebase (); rebase.SetOperation (RebaseCommand.Operation.ABORT); rebase.SetProgressMonitor (gmonitor); rebase.Call (); } throw; } finally { gmonitor.Dispose (); } } finally { if ((options & GitUpdateOptions.SaveLocalChanges) == GitUpdateOptions.SaveLocalChanges) monitor.Step (1); // Restore local changes if (stash != null) { monitor.Log.WriteLine (GettextCatalog.GetString ("Restoring local changes")); using (var gm = new GitMonitor (monitor)) stash.Apply (gm); stashes.Remove (stash); } monitor.EndTask (); } }
public void Merge (string branch, GitUpdateOptions options, ProgressMonitor monitor, FastForwardStrategy strategy = FastForwardStrategy.Default) { int stashIndex = -1; var oldHead = RootRepository.Head.Tip; Signature sig = GetSignature (); if (sig == null) return; try { monitor.BeginTask (GettextCatalog.GetString ("Merging"), 5); CommonPreMergeRebase (options, monitor, out stashIndex); // Do a merge. MergeResult mergeResult = RootRepository.Merge (branch, sig, new MergeOptions { CheckoutNotifyFlags = refreshFlags, OnCheckoutNotify = RefreshFile, }); if (mergeResult.Status == MergeStatus.Conflicts) ConflictResolver (monitor, RootRepository.Head.Tip, RootRepository.Info.Message); } finally { CommonPostMergeRebase (stashIndex, GitUpdateOptions.SaveLocalChanges, monitor, oldHead); } }
public void Rebase (string branch, GitUpdateOptions options, ProgressMonitor monitor) { int stashIndex = -1; var oldHead = RootRepository.Head.Tip; try { monitor.BeginTask (GettextCatalog.GetString ("Rebasing"), 5); if (!CommonPreMergeRebase (options, monitor, out stashIndex)) return; // Do a rebase. var divergence = RootRepository.ObjectDatabase.CalculateHistoryDivergence (RootRepository.Head.Tip, RootRepository.Branches [branch].Tip); var toApply = RootRepository.Commits.QueryBy (new CommitFilter { IncludeReachableFrom = RootRepository.Head.Tip, ExcludeReachableFrom = divergence.CommonAncestor, SortBy = CommitSortStrategies.Topological | CommitSortStrategies.Reverse }).ToArray (); RootRepository.Reset (ResetMode.Hard, divergence.Another); int count = toApply.Length; int i = 1; foreach (var com in toApply) { monitor.Log.WriteLine ("Cherry-picking {0} - {1}/{2}", com.Id, i, count); CherryPickResult cherryRes = RootRepository.CherryPick (com, com.Author, new CherryPickOptions { CheckoutNotifyFlags = refreshFlags, OnCheckoutNotify = RefreshFile, }); if (cherryRes.Status == CherryPickStatus.Conflicts) ConflictResolver(monitor, toApply.Last(), RootRepository.Info.Message ?? com.Message); ++i; } } finally { CommonPostMergeRebase (stashIndex, options, monitor, oldHead); } }
void CommonPostMergeRebase(int stashIndex, GitUpdateOptions options, ProgressMonitor monitor, Commit oldHead) { if ((options & GitUpdateOptions.SaveLocalChanges) == GitUpdateOptions.SaveLocalChanges) { monitor.Step (1); // Restore local changes if (stashIndex != -1) { monitor.Log.WriteLine (GettextCatalog.GetString ("Restoring local changes")); ApplyStash (monitor, stashIndex); // FIXME: No StashApplyStatus.Conflicts here. if (RootRepository.Index.Conflicts.Any () && !ConflictResolver (monitor, oldHead, string.Empty)) PopStash (monitor, stashIndex); else RootRepository.Stashes.Remove (stashIndex); monitor.Step (1); } } monitor.EndTask (); }
bool CommonPreMergeRebase (GitUpdateOptions options, ProgressMonitor monitor, out int stashIndex) { stashIndex = -1; monitor.Step (1); if ((options & GitUpdateOptions.SaveLocalChanges) != GitUpdateOptions.SaveLocalChanges) { const VersionStatus unclean = VersionStatus.Modified | VersionStatus.ScheduledAdd | VersionStatus.ScheduledDelete; bool modified = false; if (GetDirectoryVersionInfo (RootPath, false, true).Any (v => (v.Status & unclean) != VersionStatus.Unversioned)) modified = true; if (modified) { if (MessageService.GenericAlert ( MonoDevelop.Ide.Gui.Stock.Question, GettextCatalog.GetString ("You have uncommitted changes"), GettextCatalog.GetString ("What do you want to do?"), AlertButton.Cancel, new AlertButton ("Stash")) == AlertButton.Cancel) return false; options |= GitUpdateOptions.SaveLocalChanges; } } if ((options & GitUpdateOptions.SaveLocalChanges) == GitUpdateOptions.SaveLocalChanges) { monitor.Log.WriteLine (GettextCatalog.GetString ("Saving local changes")); Stash stash; if (!TryCreateStash (monitor, GetStashName ("_tmp_"), out stash)) return false; if (stash != null) stashIndex = 0; monitor.Step (1); } return true; }
public void Rebase (string upstreamRef, GitUpdateOptions options, IProgressMonitor monitor) { StashCollection stashes = GitUtil.GetStashes (RootRepository); Stash stash = null; NGit.Api.Git git = new NGit.Api.Git (RootRepository); try { monitor.BeginTask (GettextCatalog.GetString ("Rebasing"), 5); List<string> UpdateSubmodules = new List<string> (); // TODO: Fix stash so we don't have to do update before the main repo update. if ((options & GitUpdateOptions.UpdateSubmodules) == GitUpdateOptions.UpdateSubmodules) { monitor.Log.WriteLine (GettextCatalog.GetString ("Checking repository submodules")); if (!GetSubmodulesToUpdate (UpdateSubmodules)) return; monitor.Log.WriteLine (GettextCatalog.GetString ("Updating repository submodules")); var submoduleUpdate = git.SubmoduleUpdate (); foreach (var submodule in UpdateSubmodules) submoduleUpdate.AddPath (submodule); submoduleUpdate.Call (); monitor.Step (1); } if ((options & GitUpdateOptions.SaveLocalChanges) == GitUpdateOptions.SaveLocalChanges) { monitor.Log.WriteLine (GettextCatalog.GetString ("Saving local changes")); using (var gm = new GitMonitor (monitor)) stash = stashes.Create (gm, GetStashName ("_tmp_")); monitor.Step (1); } RebaseCommand rebase = git.Rebase (); rebase.SetOperation (RebaseCommand.Operation.BEGIN); rebase.SetUpstream (upstreamRef); var gmonitor = new GitMonitor (monitor); rebase.SetProgressMonitor (gmonitor); bool aborted = false; try { var result = rebase.Call (); while (!aborted && result.GetStatus () == RebaseResult.Status.STOPPED) { rebase = git.Rebase (); rebase.SetProgressMonitor (gmonitor); rebase.SetOperation (RebaseCommand.Operation.CONTINUE); bool commitChanges = true; var conflicts = GitUtil.GetConflictedFiles (RootRepository); foreach (string conflictFile in conflicts) { ConflictResult res = ResolveConflict (RootRepository.FromGitPath (conflictFile)); if (res == ConflictResult.Abort) { aborted = true; commitChanges = false; rebase.SetOperation (RebaseCommand.Operation.ABORT); break; } else if (res == ConflictResult.Skip) { rebase.SetOperation (RebaseCommand.Operation.SKIP); commitChanges = false; break; } } if (commitChanges) { NGit.Api.AddCommand cmd = git.Add (); foreach (string conflictFile in conflicts) cmd.AddFilepattern (conflictFile); cmd.Call (); } result = rebase.Call (); } if ((options & GitUpdateOptions.UpdateSubmodules) == GitUpdateOptions.UpdateSubmodules) { monitor.Log.WriteLine (GettextCatalog.GetString ("Updating repository submodules")); var submoduleUpdate = git.SubmoduleUpdate (); foreach (var submodule in UpdateSubmodules) submoduleUpdate.AddPath (submodule); submoduleUpdate.Call (); monitor.Step (1); } } catch { if (!aborted) { rebase = git.Rebase (); rebase.SetOperation (RebaseCommand.Operation.ABORT); rebase.SetProgressMonitor (gmonitor); rebase.Call (); } throw; } finally { gmonitor.Dispose (); } } finally { if ((options & GitUpdateOptions.SaveLocalChanges) == GitUpdateOptions.SaveLocalChanges) monitor.Step (1); // Restore local changes if (stash != null) { monitor.Log.WriteLine (GettextCatalog.GetString ("Restoring local changes")); using (var gm = new GitMonitor (monitor)) stash.Apply (gm); stashes.Remove (stash); } monitor.EndTask (); } }
void CommonPostMergeRebase(int stashIndex, GitUpdateOptions options, IProgressMonitor monitor) { if ((options & GitUpdateOptions.SaveLocalChanges) == GitUpdateOptions.SaveLocalChanges) { monitor.Step (1); // Restore local changes if (stashIndex != -1) { monitor.Log.WriteLine (GettextCatalog.GetString ("Restoring local changes")); PopStash (monitor, stashIndex); monitor.Step (1); } } monitor.EndTask (); }