public static IEnumerable <DiffEntry> CompareCommits(NGit.Repository repo, AnyObjectId reference, ObjectId compared) { var diff = new NGit.Api.Git(repo).Diff(); var firstTree = new CanonicalTreeParser(); firstTree.Reset(repo.NewObjectReader(), new RevWalk(repo).ParseTree(reference)); var secondTree = new CanonicalTreeParser(); secondTree.Reset(repo.NewObjectReader(), new RevWalk(repo).ParseTree(compared)); diff.SetNewTree(firstTree); if (compared != ObjectId.ZeroId) { diff.SetOldTree(secondTree); } return(diff.Call()); }
/// <returns>the commit if we had to do a commit, otherwise null</returns> /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException /// </exception> /// <exception cref="System.IO.IOException">System.IO.IOException</exception> private RevCommit ContinueRebase() { // if there are still conflicts, we throw a specific Exception DirCache dc = repo.ReadDirCache(); bool hasUnmergedPaths = dc.HasUnmergedPaths(); if (hasUnmergedPaths) { throw new UnmergedPathsException(); } // determine whether we need to commit TreeWalk treeWalk = new TreeWalk(repo); treeWalk.Reset(); treeWalk.Recursive = true; treeWalk.AddTree(new DirCacheIterator(dc)); ObjectId id = repo.Resolve(Constants.HEAD + "^{tree}"); if (id == null) { throw new NoHeadException(JGitText.Get().cannotRebaseWithoutCurrentHead); } treeWalk.AddTree(id); treeWalk.Filter = TreeFilter.ANY_DIFF; bool needsCommit = treeWalk.Next(); treeWalk.Release(); if (needsCommit) { CommitCommand commit = new Git(repo).Commit(); commit.SetMessage(ReadFile(rebaseDir, MESSAGE)); commit.SetAuthor(ParseAuthor()); return(commit.Call()); } return(null); }
public IEnumerable<string> GetRemoteBranches (string remoteName) { var list = new NGit.Api.Git (RootRepository).BranchList ().SetListMode (ListBranchCommand.ListMode.REMOTE); foreach (var item in list.Call ()) { string name = NGit.Repository.ShortenRefName (item.GetName ()); if (name.StartsWith (remoteName + "/", StringComparison.Ordinal)) yield return name.Substring (remoteName.Length + 1); } }
public void AddTag (string name, Revision rev, string message) { var addTag = new NGit.Api.Git (RootRepository).Tag (); var gitRev = (GitRevision)rev; addTag.SetName (name).SetMessage (message).SetObjectId (gitRev.Commit); addTag.SetObjectId (gitRev.Commit).SetTagger (new PersonIdent (RootRepository)); addTag.Call (); }
public IEnumerable<string> GetTags () { var list = new NGit.Api.Git (RootRepository).TagList (); foreach (var item in list.Call ()) { string name = NGit.Repository.ShortenRefName (item.GetName ()); yield return name; } }
public IEnumerable<Branch> GetBranches () { var list = new NGit.Api.Git (RootRepository).BranchList ().SetListMode (ListBranchCommand.ListMode.HEAD); foreach (var item in list.Call ()) { string name = NGit.Repository.ShortenRefName (item.GetName ()); Branch br = new Branch (); br.Name = name; br.Tracking = GitUtil.GetUpstreamSource (RootRepository, name); yield return br; } }
public void CreateBranch (string name, string trackSource) { var create = new NGit.Api.Git (RootRepository).BranchCreate (); if (!String.IsNullOrEmpty (trackSource)) create.SetStartPoint (trackSource); create.SetName (name); create.Call (); }
public void CreateBranchFromCommit (string name, RevCommit id) { var create = new NGit.Api.Git (RootRepository).BranchCreate (); if (id != null) create.SetStartPoint (id); create.SetName (name); create.Call (); }
/// <exception cref="NGit.Api.Errors.RefNotFoundException"></exception> /// <exception cref="System.IO.IOException"></exception> /// <exception cref="NGit.Api.Errors.NoHeadException"></exception> /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception> private RebaseResult InitFilesAndRewind() { // we need to store everything into files so that we can implement // --skip, --continue, and --abort Ref head = repo.GetRef(Constants.HEAD); if (head == null || head.GetObjectId() == null) { throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved , Constants.HEAD)); } string headName; if (head.IsSymbolic()) { headName = head.GetTarget().GetName(); } else { headName = "detached HEAD"; } ObjectId headId = head.GetObjectId(); if (headId == null) { throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved , Constants.HEAD)); } RevCommit headCommit = walk.LookupCommit(headId); RevCommit upstream = walk.LookupCommit(upstreamCommit.Id); if (walk.IsMergedInto(upstream, headCommit)) { return(RebaseResult.UP_TO_DATE_RESULT); } else { if (walk.IsMergedInto(headCommit, upstream)) { // head is already merged into upstream, fast-foward monitor.BeginTask(MessageFormat.Format(JGitText.Get().resettingHead, upstreamCommit .GetShortMessage()), ProgressMonitor.UNKNOWN); CheckoutCommit(upstreamCommit); monitor.EndTask(); UpdateHead(headName, upstreamCommit); return(RebaseResult.FAST_FORWARD_RESULT); } } monitor.BeginTask(JGitText.Get().obtainingCommitsForCherryPick, ProgressMonitor.UNKNOWN ); // determine the commits to be applied LogCommand cmd = new Git(repo).Log().AddRange(upstreamCommit, headCommit); Iterable <RevCommit> commitsToUse = cmd.Call(); IList <RevCommit> cherryPickList = new AList <RevCommit>(); foreach (RevCommit commit in commitsToUse) { if (commit.ParentCount != 1) { throw new JGitInternalException(JGitText.Get().canOnlyCherryPickCommitsWithOneParent ); } cherryPickList.AddItem(commit); } Sharpen.Collections.Reverse(cherryPickList); // create the folder for the meta information FileUtils.Mkdir(rebaseDir); CreateFile(repo.Directory, Constants.ORIG_HEAD, headId.Name); CreateFile(rebaseDir, REBASE_HEAD, headId.Name); CreateFile(rebaseDir, HEAD_NAME, headName); CreateFile(rebaseDir, ONTO, upstreamCommit.Name); CreateFile(rebaseDir, INTERACTIVE, string.Empty); BufferedWriter fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream (new FilePath(rebaseDir, GIT_REBASE_TODO)), Constants.CHARACTER_ENCODING)); fw.Write("# Created by EGit: rebasing " + upstreamCommit.Name + " onto " + headId .Name); fw.NewLine(); try { StringBuilder sb = new StringBuilder(); ObjectReader reader = walk.GetObjectReader(); foreach (RevCommit commit_1 in cherryPickList) { sb.Length = 0; sb.Append(RebaseCommand.Action.PICK.ToToken()); sb.Append(" "); sb.Append(reader.Abbreviate(commit_1).Name); sb.Append(" "); sb.Append(commit_1.GetShortMessage()); fw.Write(sb.ToString()); fw.NewLine(); } } finally { fw.Close(); } monitor.EndTask(); // we rewind to the upstream commit monitor.BeginTask(MessageFormat.Format(JGitText.Get().rewinding, upstreamCommit.GetShortMessage ()), ProgressMonitor.UNKNOWN); bool checkoutOk = false; try { checkoutOk = CheckoutCommit(upstreamCommit); } finally { if (!checkoutOk) { FileUtils.Delete(rebaseDir, FileUtils.RECURSIVE); } } monitor.EndTask(); return(null); }
/// <exception cref="NGit.Api.Errors.RefNotFoundException"></exception> /// <exception cref="System.IO.IOException"></exception> /// <exception cref="NGit.Api.Errors.NoHeadException"></exception> /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception> private RebaseResult InitFilesAndRewind() { // we need to store everything into files so that we can implement // --skip, --continue, and --abort // first of all, we determine the commits to be applied IList <RevCommit> cherryPickList = new AList <RevCommit>(); Ref head = repo.GetRef(Constants.HEAD); if (head == null || head.GetObjectId() == null) { throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved , Constants.HEAD)); } string headName; if (head.IsSymbolic()) { headName = head.GetTarget().GetName(); } else { headName = "detached HEAD"; } ObjectId headId = head.GetObjectId(); if (headId == null) { throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved , Constants.HEAD)); } RevCommit headCommit = walk.LookupCommit(headId); monitor.BeginTask(JGitText.Get().obtainingCommitsForCherryPick, ProgressMonitor.UNKNOWN ); LogCommand cmd = new Git(repo).Log().AddRange(upstreamCommit, headCommit); Iterable <RevCommit> commitsToUse = cmd.Call(); foreach (RevCommit commit in commitsToUse) { cherryPickList.AddItem(commit); } // if the upstream commit is in a direct line to the current head, // the log command will not report any commits; in this case, // we create the cherry-pick list ourselves if (cherryPickList.IsEmpty()) { Iterable <RevCommit> parents = new Git(repo).Log().Add(upstreamCommit).Call(); foreach (RevCommit parent in parents) { if (parent.Equals(headCommit)) { break; } if (parent.ParentCount != 1) { throw new JGitInternalException(JGitText.Get().canOnlyCherryPickCommitsWithOneParent ); } cherryPickList.AddItem(parent); } } // nothing to do: return with UP_TO_DATE_RESULT if (cherryPickList.IsEmpty()) { return(RebaseResult.UP_TO_DATE_RESULT); } Sharpen.Collections.Reverse(cherryPickList); // create the folder for the meta information FileUtils.Mkdir(rebaseDir); CreateFile(repo.Directory, Constants.ORIG_HEAD, headId.Name); CreateFile(rebaseDir, REBASE_HEAD, headId.Name); CreateFile(rebaseDir, HEAD_NAME, headName); CreateFile(rebaseDir, ONTO, upstreamCommit.Name); CreateFile(rebaseDir, INTERACTIVE, string.Empty); BufferedWriter fw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream (new FilePath(rebaseDir, GIT_REBASE_TODO)), Constants.CHARACTER_ENCODING)); fw.Write("# Created by EGit: rebasing " + upstreamCommit.Name + " onto " + headId .Name); fw.NewLine(); try { StringBuilder sb = new StringBuilder(); ObjectReader reader = walk.GetObjectReader(); foreach (RevCommit commit_1 in cherryPickList) { sb.Length = 0; sb.Append(RebaseCommand.Action.PICK.ToToken()); sb.Append(" "); sb.Append(reader.Abbreviate(commit_1).Name); sb.Append(" "); sb.Append(commit_1.GetShortMessage()); fw.Write(sb.ToString()); fw.NewLine(); } } finally { fw.Close(); } monitor.EndTask(); // we rewind to the upstream commit monitor.BeginTask(MessageFormat.Format(JGitText.Get().rewinding, upstreamCommit.GetShortMessage ()), ProgressMonitor.UNKNOWN); CheckoutCommit(upstreamCommit); monitor.EndTask(); return(null); }
/// <summary> /// Requires absolute path /// </summary> /// <param name="fileName"></param> public void UnStageFile(string fileName) { if (!this.HasGitRepository) return; var fileNameRel = GetRelativeFileName(fileName); if (GitBash.Exists) { if (head == null) { GitBash.Run(string.Format("rm --cached -- \"{0}\"", fileNameRel), this.GitWorkingDirectory); } else { GitBash.Run(string.Format("reset -- \"{0}\"", fileNameRel), this.GitWorkingDirectory); } } else { ResetCommand resetCommand = new Git(repository).Reset(); resetCommand.AddPath(GetRelativeFileNameForGit(fileName)); resetCommand.SetRef(Constants.HEAD); resetCommand.Call(); } this.cache.Remove(GetCacheKey(fileName)); this.changedFiles = null; }
/// <summary> /// Requires absolute path /// </summary> /// <param name="fileName"></param> public void StageFile(string fileName) { if (!this.HasGitRepository) return; //var index = repository.GetIndex(); //index.RereadIfNecessary(); if (GitBash.Exists) { if (File.Exists(fileName)) { GitBash.Run(string.Format("add \"{0}\"", GetRelativeFileName(fileName)), this.GitWorkingDirectory); } else { GitBash.Run(string.Format("rm --cached -- \"{0}\"", GetRelativeFileName(fileName)), this.GitWorkingDirectory); } } else { if (File.Exists(fileName)) { AddCommand addCommand = new Git(repository).Add(); addCommand.AddFilepattern(GetRelativeFileNameForGit(fileName)); addCommand.Call(); } else { RmCommand rmCommand = new Git(repository).Rm(); rmCommand.AddFilepattern(GetRelativeFileNameForGit(fileName)); rmCommand.Call(); } } this.cache.Remove(GetCacheKey(fileName)); this.changedFiles = null; }
public static IEnumerable<DiffEntry> CompareCommits (NGit.Repository repo, AnyObjectId reference, ObjectId compared) { var diff = new NGit.Api.Git (repo).Diff (); var firstTree = new CanonicalTreeParser (); firstTree.Reset (repo.NewObjectReader (), new RevWalk (repo).ParseTree (reference)); diff.SetNewTree (firstTree); if (compared != ObjectId.ZeroId) { var secondTree = new CanonicalTreeParser (); secondTree.Reset (repo.NewObjectReader (), new RevWalk (repo).ParseTree (compared)); if (compared != ObjectId.ZeroId) diff.SetOldTree (secondTree); } return diff.Call (); }
public void SwitchToBranch (IProgressMonitor monitor, string branch) { monitor.BeginTask (GettextCatalog.GetString ("Switching to branch {0}", branch), GitService.StashUnstashWhenSwitchingBranches ? 4 : 2); // Get a list of files that are different in the target branch IEnumerable<DiffEntry> statusList = GitUtil.GetChangedFiles (RootRepository, branch); StashCollection stashes = null; Stash stash = null; if (GitService.StashUnstashWhenSwitchingBranches) { stashes = GitUtil.GetStashes (RootRepository); // Remove the stash for this branch, if exists string currentBranch = GetCurrentBranch (); stash = GetStashForBranch (stashes, currentBranch); if (stash != null) stashes.Remove (stash); // Create a new stash for the branch. This allows switching branches // without losing local changes using (var gm = new GitMonitor (monitor)) stash = stashes.Create (gm, GetStashName (currentBranch)); monitor.Step (1); } // Replace with NGit.Api.Git ().Checkout () // Switch to the target branch var checkout = new NGit.Api.Git (RootRepository).Checkout (); checkout.SetName (branch); try { checkout.Call (); } finally { // Restore the branch stash if (GitService.StashUnstashWhenSwitchingBranches) { stash = GetStashForBranch (stashes, branch); if (stash != null) { using (var gm = new GitMonitor (monitor)) stash.Apply (gm); stashes.Remove (stash); } monitor.Step (1); } } // Notify file changes NotifyFileChanges (monitor, statusList); if (BranchSelectionChanged != null) BranchSelectionChanged (this, EventArgs.Empty); monitor.EndTask (); }
public void Push (IProgressMonitor monitor, string remote, string remoteBranch) { string remoteRef = "refs/heads/" + remoteBranch; IEnumerable<PushResult> res; var push = new NGit.Api.Git (RootRepository).Push (); // We only have one pushed branch. push.SetRemote (remote).SetRefSpecs (new RefSpec (remoteRef)); using (var gm = new GitMonitor (monitor)) { push.SetProgressMonitor (gm); res = push.Call (); } foreach (var pr in res) { var remoteUpdate = pr.GetRemoteUpdate (remoteRef); switch (remoteUpdate.GetStatus ()) { case RemoteRefUpdate.Status.UP_TO_DATE: monitor.ReportSuccess (GettextCatalog.GetString ("Remote branch is up to date.")); break; case RemoteRefUpdate.Status.REJECTED_NODELETE: monitor.ReportError (GettextCatalog.GetString ("The server is configured to deny deletion of the branch"), null); break; case RemoteRefUpdate.Status.REJECTED_NONFASTFORWARD: monitor.ReportError (GettextCatalog.GetString ("The update is a non-fast-forward update. Merge the remote changes before pushing again."), null); break; case RemoteRefUpdate.Status.OK: monitor.ReportSuccess (GettextCatalog.GetString ("Push operation successfully completed.")); // Update the remote branch ObjectId headId = remoteUpdate.GetNewObjectId (); RefUpdate updateRef = RootRepository.UpdateRef (Constants.R_REMOTES + remote + "/" + remoteBranch); updateRef.SetNewObjectId(headId); updateRef.Update(); break; default: string msg = remoteUpdate.GetMessage (); msg = !string.IsNullOrEmpty (msg) ? msg : GettextCatalog.GetString ("Push operation failed"); monitor.ReportError (msg, null); break; } } }
public void Fetch (IProgressMonitor monitor) { string remote = GetCurrentRemote (); if (remote == null) throw new InvalidOperationException ("No remotes defined"); monitor.Log.WriteLine (GettextCatalog.GetString ("Fetching from '{0}'", remote)); var fetch = new NGit.Api.Git (RootRepository).Fetch (); using (var gm = new GitMonitor (monitor)) { fetch.SetRemote (remote); fetch.SetProgressMonitor (gm); fetch.Call (); } monitor.Step (1); }
public bool Rebase () { NGit.Api.Git git = new NGit.Api.Git (repo); if (aborted) return false; if (starting) { ObjectId headId = repo.Resolve (Constants.HEAD + "^{commit}"); RevCommit headCommit = rw.ParseCommit (headId); oldHead = headCommit; ObjectId upstreamId = repo.Resolve (upstreamRef); RevCommit upstreamCommit = rw.ParseCommit (upstreamId); oldHead = headCommit; lastGoodHead = upstreamId; commitChain = new List<RevCommit> (); LogCommand cmd = new NGit.Api.Git(repo).Log().AddRange(upstreamId, headCommit); foreach (RevCommit commit in cmd.Call()) commitChain.Add(commit); commitChain.Reverse (); currentMergeIndex = 0; // Checkout the upstream commit // Reset head to upstream GitUtil.HardReset (repo, upstreamRef); string rebaseDir = Path.Combine (repo.Directory, "rebase-apply"); if (!Directory.Exists (rebaseDir)) Directory.CreateDirectory (rebaseDir); string rebasingFile = Path.Combine (rebaseDir, "rebasing"); if (!File.Exists (rebasingFile)) File.WriteAllBytes (rebasingFile, new byte[0]); starting = false; monitor.BeginTask ("Applying local commits", commitChain.Count); } else { // Conflicts resolved. Continue. NGit.Api.AddCommand cmd = git.Add (); var conflicts = LastMergeResult.GetConflicts (); foreach (string conflictFile in conflicts.Keys) { cmd.AddFilepattern (conflictFile); } cmd.Call (); NGit.Api.CommitCommand commit = git.Commit (); commit.SetMessage (currentMergeCommit.GetFullMessage ()); commit.SetAuthor (currentMergeCommit.GetAuthorIdent ()); commit.SetCommitter (currentMergeCommit.GetCommitterIdent ()); commit.Call(); } // Merge commit by commit until the current head while (currentMergeIndex < commitChain.Count) { currentMergeCommit = commitChain[currentMergeIndex++]; mergeResult = GitUtil.CherryPick (repo, currentMergeCommit); monitor.Log.WriteLine ("Applied '{0}'", currentMergeCommit.GetShortMessage ()); monitor.Step (1); if (mergeResult.GetMergeStatus () == MergeStatus.CONFLICTING || mergeResult.GetMergeStatus () == MergeStatus.FAILED) return false; lastGoodHead = mergeResult.GetNewHead (); } monitor.EndTask (); CleanRebaseFile (); return true; }