public string GetFullMessage(string hash) { var walk = new RevWalk(this.git.GetRepository()); RevCommit commit = walk.ParseCommit(ObjectId.FromString(hash)); walk.Dispose(); return commit.GetFullMessage(); }
public virtual void TestEquals() { RevCommit a1 = Commit(); RevCommit b1 = Commit(); NUnit.Framework.Assert.IsTrue(a1.Equals(a1)); NUnit.Framework.Assert.IsTrue(a1.Equals((object)a1)); NUnit.Framework.Assert.IsFalse(a1.Equals(b1)); NUnit.Framework.Assert.IsTrue(a1.Equals(a1)); NUnit.Framework.Assert.IsTrue(a1.Equals((object)a1)); NUnit.Framework.Assert.IsFalse(a1.Equals(string.Empty)); RevWalk rw2 = new RevWalk(db); RevCommit a2 = rw2.ParseCommit(a1); RevCommit b2 = rw2.ParseCommit(b1); NUnit.Framework.Assert.AreNotSame(a1, a2); NUnit.Framework.Assert.AreNotSame(b1, b2); NUnit.Framework.Assert.IsTrue(a1.Equals(a2)); NUnit.Framework.Assert.IsTrue(b1.Equals(b2)); NUnit.Framework.Assert.AreEqual(a1.GetHashCode(), a2.GetHashCode()); NUnit.Framework.Assert.AreEqual(b1.GetHashCode(), b2.GetHashCode()); NUnit.Framework.Assert.IsTrue(AnyObjectId.Equals(a1, a2)); NUnit.Framework.Assert.IsTrue(AnyObjectId.Equals(b1, b2)); }
/// <exception cref="System.InvalidOperationException"></exception> /// <exception cref="System.IO.IOException"></exception> private void CheckoutCommit(RevCommit commit) { RevWalk walk = new RevWalk(db); RevCommit head = walk.ParseCommit(db.Resolve(Constants.HEAD)); DirCacheCheckout dco = new DirCacheCheckout(db, head.Tree, db.LockDirCache(), commit .Tree); dco.SetFailOnConflict(true); dco.Checkout(); walk.Release(); // update the HEAD RefUpdate refUpdate = db.UpdateRef(Constants.HEAD, true); refUpdate.SetNewObjectId(commit); refUpdate.ForceUpdate(); }
private RevWalk CreateRevWalker() { var repository = _git.GetRepository(); try { var revWalk = new RevWalk(repository); foreach (var reference in repository.GetAllRefs()) { revWalk.MarkStart(revWalk.ParseCommit(reference.Value.GetObjectId())); } return revWalk; } finally { repository.Close(); } }
public override CommitInfo GetLatestCommit() { using (var repository = GetRepository()) { var repo = (FileRepository)repository; var branch = repo.GetBranch(); if (branch == null) return null; var objId = repo.Resolve(branch); if (objId == null) return null; RevWalk walk = new RevWalk(repo); RevCommit commit = walk.ParseCommit(objId); if (commit == null) return null; return new CommitInfo { Message = commit.GetFullMessage(), Date = commit.GetCommitterIdent().GetWhen().ToLocalTime() }; } }
public static API_NGit files(this API_NGit nGit,string commitId, Action<TreeWalk> onTreeWalk) { try { var headCommit = nGit.Repository.Resolve(commitId); if (commitId.notNull()) { var revWalk = new RevWalk(nGit.Repository); var commit = revWalk.ParseCommit(headCommit); var treeWalk = new TreeWalk(nGit.Repository); var tree = commit.Tree; treeWalk.AddTree(tree); treeWalk.Recursive = true; while (treeWalk.Next()) onTreeWalk(treeWalk); } } catch (Exception ex) { ex.log("[API_NGit][getRepoFiles]"); } return nGit ; }
public static List<GitData_File> gitData_Files(this API_NGit nGit, int max_FilesToShow, string commitSha1) { var gitData_Files = new List<GitData_File>(); try { var headCommit = nGit.Repository.Resolve(commitSha1); if (commitSha1.notNull()) { var revWalk = new RevWalk(nGit.Repository); var commit = revWalk.ParseCommit(headCommit); var treeWalk = new TreeWalk(nGit.Repository); var tree = commit.Tree; treeWalk.AddTree(tree); treeWalk.Recursive = true; while (treeWalk.Next() && (max_FilesToShow == -1) || gitData_Files.size() < max_FilesToShow) gitData_Files.add_File(treeWalk); //repoFiles.Add(treeWalk.PathString); } } catch(Exception ex) { ex.log("[API_NGit][gitData_Files]"); } return gitData_Files; }
public virtual void TestStopOnConflictFileCreationAndDeletion() { // create file1 on master WriteTrashFile(FILE1, "Hello World"); git.Add().AddFilepattern(FILE1).Call(); // create file2 on master FilePath file2 = WriteTrashFile("file2", "Hello World 2"); git.Add().AddFilepattern("file2").Call(); // create file3 on master FilePath file3 = WriteTrashFile("file3", "Hello World 3"); git.Add().AddFilepattern("file3").Call(); RevCommit firstInMaster = git.Commit().SetMessage("Add file 1, 2 and 3").Call(); // create file4 on master FilePath file4 = WriteTrashFile("file4", "Hello World 4"); git.Add().AddFilepattern("file4").Call(); DeleteTrashFile("file2"); git.Add().SetUpdate(true).AddFilepattern("file2").Call(); // create folder folder6 on topic (conflicts with file folder6 on topic // later on) WriteTrashFile("folder6/file1", "Hello World folder6"); git.Add().AddFilepattern("folder6/file1").Call(); git.Commit().SetMessage("Add file 4 and folder folder6, delete file2 on master"). Call(); // create a topic branch based on second commit CreateBranch(firstInMaster, "refs/heads/topic"); CheckoutBranch("refs/heads/topic"); DeleteTrashFile("file3"); git.Add().SetUpdate(true).AddFilepattern("file3").Call(); // create file5 on topic FilePath file5 = WriteTrashFile("file5", "Hello World 5"); git.Add().AddFilepattern("file5").Call(); git.Commit().SetMessage("Delete file3 and add file5 in topic").Call(); // create file folder6 on topic (conflicts with folder6 on master) WriteTrashFile("folder6", "Hello World 6"); git.Add().AddFilepattern("folder6").Call(); // create file7 on topic FilePath file7 = WriteTrashFile("file7", "Hello World 7"); git.Add().AddFilepattern("file7").Call(); DeleteTrashFile("file5"); git.Add().SetUpdate(true).AddFilepattern("file5").Call(); RevCommit conflicting = git.Commit().SetMessage("Delete file5, add file folder6 and file7 in topic" ).Call(); RebaseResult res = git.Rebase().SetUpstream("refs/heads/master").Call(); NUnit.Framework.Assert.AreEqual(RebaseResult.Status.STOPPED, res.GetStatus()); NUnit.Framework.Assert.AreEqual(conflicting, res.GetCurrentCommit()); NUnit.Framework.Assert.AreEqual(RepositoryState.REBASING_INTERACTIVE, db.GetRepositoryState ()); NUnit.Framework.Assert.IsTrue(new FilePath(db.Directory, "rebase-merge").Exists() ); // the first one should be included, so we should have left two picks in // the file NUnit.Framework.Assert.AreEqual(0, CountPicks()); NUnit.Framework.Assert.IsFalse(file2.Exists()); NUnit.Framework.Assert.IsFalse(file3.Exists()); NUnit.Framework.Assert.IsTrue(file4.Exists()); NUnit.Framework.Assert.IsFalse(file5.Exists()); NUnit.Framework.Assert.IsTrue(file7.Exists()); // abort should reset to topic branch res = git.Rebase().SetOperation(RebaseCommand.Operation.ABORT).Call(); NUnit.Framework.Assert.AreEqual(res.GetStatus(), RebaseResult.Status.ABORTED); NUnit.Framework.Assert.AreEqual("refs/heads/topic", db.GetFullBranch()); RevWalk rw = new RevWalk(db); NUnit.Framework.Assert.AreEqual(conflicting, rw.ParseCommit(db.Resolve(Constants. HEAD))); NUnit.Framework.Assert.AreEqual(RepositoryState.SAFE, db.GetRepositoryState()); // rebase- dir in .git must be deleted NUnit.Framework.Assert.IsFalse(new FilePath(db.Directory, "rebase-merge").Exists( )); NUnit.Framework.Assert.IsTrue(file2.Exists()); NUnit.Framework.Assert.IsFalse(file3.Exists()); NUnit.Framework.Assert.IsFalse(file4.Exists()); NUnit.Framework.Assert.IsFalse(file5.Exists()); NUnit.Framework.Assert.IsTrue(file7.Exists()); }
public virtual void TestStopOnConflict() { // create file1 on master RevCommit firstInMaster = WriteFileAndCommit(FILE1, "Add file1", "1", "2", "3"); // change first line in master WriteFileAndCommit(FILE1, "change file1 in master", "1master", "2", "3"); CheckFile(FILE1, "1master", "2", "3"); // create a topic branch based on second commit CreateBranch(firstInMaster, "refs/heads/topic"); CheckoutBranch("refs/heads/topic"); // we have the old content again CheckFile(FILE1, "1", "2", "3"); // add a line (non-conflicting) WriteFileAndCommit(FILE1, "add a line to file1 in topic", "1", "2", "3", "topic4" ); // change first line (conflicting) RevCommit conflicting = WriteFileAndCommit(FILE1, "change file1 in topic", "1topic" , "2", "3", "topic4"); RevCommit lastTopicCommit = WriteFileAndCommit(FILE1, "change file1 in topic again" , "1topic", "2", "3", "topic4"); RebaseResult res = git.Rebase().SetUpstream("refs/heads/master").Call(); NUnit.Framework.Assert.AreEqual(RebaseResult.Status.STOPPED, res.GetStatus()); NUnit.Framework.Assert.AreEqual(conflicting, res.GetCurrentCommit()); CheckFile(FILE1, "<<<<<<< OURS\n1master\n=======\n1topic\n>>>>>>> THEIRS\n2\n3\ntopic4" ); NUnit.Framework.Assert.AreEqual(RepositoryState.REBASING_INTERACTIVE, db.GetRepositoryState ()); NUnit.Framework.Assert.IsTrue(new FilePath(db.Directory, "rebase-merge").Exists() ); // the first one should be included, so we should have left two picks in // the file NUnit.Framework.Assert.AreEqual(1, CountPicks()); // rebase should not succeed in this state try { git.Rebase().SetUpstream("refs/heads/master").Call(); NUnit.Framework.Assert.Fail("Expected exception was not thrown"); } catch (WrongRepositoryStateException) { } // expected // abort should reset to topic branch res = git.Rebase().SetOperation(RebaseCommand.Operation.ABORT).Call(); NUnit.Framework.Assert.AreEqual(res.GetStatus(), RebaseResult.Status.ABORTED); NUnit.Framework.Assert.AreEqual("refs/heads/topic", db.GetFullBranch()); CheckFile(FILE1, "1topic", "2", "3", "topic4"); RevWalk rw = new RevWalk(db); NUnit.Framework.Assert.AreEqual(lastTopicCommit, rw.ParseCommit(db.Resolve(Constants .HEAD))); NUnit.Framework.Assert.AreEqual(RepositoryState.SAFE, db.GetRepositoryState()); // rebase- dir in .git must be deleted NUnit.Framework.Assert.IsFalse(new FilePath(db.Directory, "rebase-merge").Exists( )); }
public static FileRepository Clone (string targetLocalPath, string url, IProgressMonitor monitor) { FileRepository repo = Init (targetLocalPath, url, monitor); // Fetch string remoteName = "origin"; string branch = Constants.R_HEADS + "master"; Transport tn = Transport.Open (repo, remoteName); FetchResult r; try { r = tn.Fetch(new GitMonitor (monitor), null); } finally { tn.Close (); } // Create the master branch // branch is like 'Constants.R_HEADS + branchName', we need only // the 'branchName' part String branchName = branch.Substring (Constants.R_HEADS.Length); NGit.Api.Git git = new NGit.Api.Git (repo); git.BranchCreate ().SetName (branchName).SetUpstreamMode (CreateBranchCommand.SetupUpstreamMode.TRACK).SetStartPoint ("origin/master").Call (); // Checkout DirCache dc = repo.LockDirCache (); try { RevWalk rw = new RevWalk (repo); ObjectId remCommitId = repo.Resolve (remoteName + "/" + branchName); RevCommit remCommit = rw.ParseCommit (remCommitId); DirCacheCheckout co = new DirCacheCheckout (repo, null, dc, remCommit.Tree); co.Checkout (); } catch { dc.Unlock (); throw; } return repo; }
public static void HardReset (NGit.Repository repo, ObjectId newHead) { DirCache dc = null; try { // Reset head to upstream RefUpdate ru = repo.UpdateRef (Constants.HEAD); ru.SetNewObjectId (newHead); ru.SetForceUpdate (true); RefUpdate.Result rc = ru.Update (); switch (rc) { case RefUpdate.Result.NO_CHANGE: case RefUpdate.Result.NEW: case RefUpdate.Result.FAST_FORWARD: case RefUpdate.Result.FORCED: break; case RefUpdate.Result.REJECTED: case RefUpdate.Result.LOCK_FAILURE: throw new ConcurrentRefUpdateException (JGitText.Get ().couldNotLockHEAD, ru.GetRef (), rc); default: throw new JGitInternalException ("Reference update failed: " + rc); } dc = repo.LockDirCache (); RevWalk rw = new RevWalk (repo); RevCommit c = rw.ParseCommit (newHead); DirCacheCheckout checkout = new DirCacheCheckout (repo, null, dc, c.Tree); checkout.Checkout (); } catch { if (dc != null) dc.Unlock (); throw; } }
// TODO not implemented yet // TODO not implemented yet /// <summary> /// Executes the /// <code>Reset</code> /// command. Each instance of this class should /// only be used for one invocation of the command. Don't call this method /// twice on an instance. /// </summary> /// <returns>the Ref after reset</returns> /// <exception cref="System.IO.IOException"></exception> public override Ref Call() { CheckCallable(); Ref r; RevCommit commit; try { bool merging = false; if (repo.GetRepositoryState().Equals(RepositoryState.MERGING) || repo.GetRepositoryState ().Equals(RepositoryState.MERGING_RESOLVED)) { merging = true; } // resolve the ref to a commit ObjectId commitId; try { commitId = repo.Resolve(@ref); } catch (IOException e) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().cannotRead, @ref ), e); } RevWalk rw = new RevWalk(repo); try { commit = rw.ParseCommit(commitId); } catch (IOException e) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().cannotReadCommit , commitId.ToString()), e); } finally { rw.Release(); } // write the ref RefUpdate ru = repo.UpdateRef(Constants.HEAD); ru.SetNewObjectId(commitId); string refName = Repository.ShortenRefName(@ref); string message = "reset --" + mode.ToString().ToLower() + " " + refName; //$NON-NLS-1$ //$NON-NLS-1$ ru.SetRefLogMessage(message, false); if (ru.ForceUpdate() == RefUpdate.Result.LOCK_FAILURE) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().cannotLock, ru .GetName())); } switch (mode) { case ResetCommand.ResetType.HARD: { CheckoutIndex(commit); break; } case ResetCommand.ResetType.MIXED: { ResetIndex(commit); break; } case ResetCommand.ResetType.SOFT: { // do nothing, only the ref was changed break; } case ResetCommand.ResetType.KEEP: case ResetCommand.ResetType.MERGE: { // TODO // TODO throw new NotSupportedException(); } } if (mode != ResetCommand.ResetType.SOFT && merging) { ResetMerge(); } SetCallable(false); r = ru.GetRef(); } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfResetCommand , e); } return(r); }
/// <exception cref="NGit.Api.Errors.NotMergedException"> /// when trying to delete a branch which has not been merged into /// the currently checked out branch without force /// </exception> /// <returns>the list with the (full) names of the deleted branches</returns> /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception> /// <exception cref="NGit.Api.Errors.CannotDeleteCurrentBranchException"></exception> public override IList <string> Call() { CheckCallable(); IList <string> result = new AList <string>(); if (branchNames.IsEmpty()) { return(result); } try { string currentBranch = repo.GetFullBranch(); if (!force) { // check if the branches to be deleted // are all merged into the current branch RevWalk walk = new RevWalk(repo); RevCommit tip = walk.ParseCommit(repo.Resolve(Constants.HEAD)); foreach (string branchName in branchNames) { if (branchName == null) { continue; } Ref currentRef = repo.GetRef(branchName); if (currentRef == null) { continue; } RevCommit @base = walk.ParseCommit(repo.Resolve(branchName)); if (!walk.IsMergedInto(@base, tip)) { throw new NotMergedException(); } } } SetCallable(false); foreach (string branchName_1 in branchNames) { if (branchName_1 == null) { continue; } Ref currentRef = repo.GetRef(branchName_1); if (currentRef == null) { continue; } string fullName = currentRef.GetName(); if (fullName.Equals(currentBranch)) { throw new CannotDeleteCurrentBranchException(MessageFormat.Format(JGitText.Get(). cannotDeleteCheckedOutBranch, branchName_1)); } RefUpdate update = repo.UpdateRef(fullName); update.SetRefLogMessage("branch deleted", false); update.SetForceUpdate(true); RefUpdate.Result deleteResult = update.Delete(); bool ok = true; switch (deleteResult) { case RefUpdate.Result.IO_FAILURE: case RefUpdate.Result.LOCK_FAILURE: case RefUpdate.Result.REJECTED: { ok = false; break; } default: { break; break; } } if (ok) { result.AddItem(fullName); if (fullName.StartsWith(Constants.R_HEADS)) { string shortenedName = Sharpen.Runtime.Substring(fullName, Constants.R_HEADS.Length ); // remove upstream configuration if any StoredConfig cfg = repo.GetConfig(); cfg.UnsetSection(ConfigConstants.CONFIG_BRANCH_SECTION, shortenedName); cfg.Save(); } } else { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().deleteBranchUnexpectedResult , deleteResult.ToString())); } } return(result); } catch (IOException ioe) { throw new JGitInternalException(ioe.Message, ioe); } }
/// <summary> /// Executes the /// <code>Cherry-Pick</code> /// command with all the options and /// parameters collected by the setter methods (e.g. /// <see cref="Include(NGit.Ref)">Include(NGit.Ref)</see> /// of /// this class. Each instance of this class should only be used for one /// invocation of the command. Don't call this method twice on an instance. /// </summary> /// <returns>the result of the cherry-pick</returns> /// <exception cref="NGit.Api.Errors.GitAPIException"></exception> public override CherryPickResult Call() { RevCommit newHead = null; IList <Ref> cherryPickedRefs = new List <Ref>(); CheckCallable(); RevWalk revWalk = new RevWalk(repo); try { // get the head commit Ref headRef = repo.GetRef(Constants.HEAD); if (headRef == null) { throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported ); } RevCommit headCommit = revWalk.ParseCommit(headRef.GetObjectId()); newHead = headCommit; // loop through all refs to be cherry-picked foreach (Ref src in commits) { // get the commit to be cherry-picked // handle annotated tags ObjectId srcObjectId = src.GetPeeledObjectId(); if (srcObjectId == null) { srcObjectId = src.GetObjectId(); } RevCommit srcCommit = revWalk.ParseCommit(srcObjectId); // get the parent of the commit to cherry-pick if (srcCommit.ParentCount != 1) { throw new MultipleParentsNotAllowedException(JGitText.Get().canOnlyCherryPickCommitsWithOneParent ); } RevCommit srcParent = srcCommit.GetParent(0); revWalk.ParseHeaders(srcParent); ResolveMerger merger = (ResolveMerger)((ThreeWayMerger)MergeStrategy.RESOLVE.NewMerger (repo)); merger.SetWorkingTreeIterator(new FileTreeIterator(repo)); merger.SetBase(srcParent.Tree); if (merger.Merge(headCommit, srcCommit)) { if (AnyObjectId.Equals(headCommit.Tree.Id, merger.GetResultTreeId())) { continue; } DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache (), merger.GetResultTreeId()); dco.SetFailOnConflict(true); dco.Checkout(); newHead = new Git(GetRepository()).Commit().SetMessage(srcCommit.GetFullMessage() ).SetAuthor(srcCommit.GetAuthorIdent()).Call(); cherryPickedRefs.AddItem(src); } else { if (merger.Failed()) { return(new CherryPickResult(merger.GetFailingPaths())); } // merge conflicts return(CherryPickResult.CONFLICT); } } } catch (IOException e) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().exceptionCaughtDuringExecutionOfCherryPickCommand , e), e); } finally { revWalk.Release(); } return(new CherryPickResult(newHead, cherryPickedRefs)); }
/// <summary> /// Executes the /// <code>Rebase</code> /// command with all the options and parameters /// collected by the setter methods of this class. Each instance of this /// class should only be used for one invocation of the command. Don't call /// this method twice on an instance. /// </summary> /// <returns>an object describing the result of this command</returns> /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException /// </exception> /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">NGit.Api.Errors.WrongRepositoryStateException /// </exception> /// <exception cref="NGit.Api.Errors.NoHeadException">NGit.Api.Errors.NoHeadException /// </exception> /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException /// </exception> public override RebaseResult Call() { RevCommit newHead = null; bool lastStepWasForward = false; CheckCallable(); CheckParameters(); try { switch (operation) { case RebaseCommand.Operation.ABORT: { try { return(Abort(RebaseResult.ABORTED_RESULT)); } catch (IOException ioe) { throw new JGitInternalException(ioe.Message, ioe); } goto case RebaseCommand.Operation.SKIP; } case RebaseCommand.Operation.SKIP: case RebaseCommand.Operation.CONTINUE: { // fall through string upstreamCommitName = ReadFile(rebaseDir, ONTO); this.upstreamCommit = walk.ParseCommit(repo.Resolve(upstreamCommitName)); break; } case RebaseCommand.Operation.BEGIN: { RebaseResult res = InitFilesAndRewind(); if (res != null) { return(res); } break; } } if (monitor.IsCancelled()) { return(Abort(RebaseResult.ABORTED_RESULT)); } if (operation == RebaseCommand.Operation.CONTINUE) { newHead = ContinueRebase(); if (newHead == null) { // continueRebase() returns null only if no commit was // neccessary. This means that no changes where left over // after resolving all conflicts. In this case, cgit stops // and displays a nice message to the user, telling him to // either do changes or skip the commit instead of continue. return(RebaseResult.NOTHING_TO_COMMIT_RESULT); } } if (operation == RebaseCommand.Operation.SKIP) { newHead = CheckoutCurrentHead(); } ObjectReader or = repo.NewObjectReader(); IList <RebaseCommand.Step> steps = LoadSteps(); foreach (RebaseCommand.Step step in steps) { PopSteps(1); ICollection <ObjectId> ids = or.Resolve(step.commit); if (ids.Count != 1) { throw new JGitInternalException("Could not resolve uniquely the abbreviated object ID" ); } RevCommit commitToPick = walk.ParseCommit(ids.Iterator().Next()); if (monitor.IsCancelled()) { return(new RebaseResult(commitToPick)); } try { monitor.BeginTask(MessageFormat.Format(JGitText.Get().applyingCommit, commitToPick .GetShortMessage()), ProgressMonitor.UNKNOWN); // if the first parent of commitToPick is the current HEAD, // we do a fast-forward instead of cherry-pick to avoid // unnecessary object rewriting newHead = TryFastForward(commitToPick); lastStepWasForward = newHead != null; if (!lastStepWasForward) { // TODO if the content of this commit is already merged // here we should skip this step in order to avoid // confusing pseudo-changed CherryPickResult cherryPickResult = new Git(repo).CherryPick().Include(commitToPick ).Call(); switch (cherryPickResult.GetStatus()) { case CherryPickResult.CherryPickStatus.FAILED: { if (operation == RebaseCommand.Operation.BEGIN) { return(Abort(new RebaseResult(cherryPickResult.GetFailingPaths()))); } else { return(Stop(commitToPick)); } goto case CherryPickResult.CherryPickStatus.CONFLICTING; } case CherryPickResult.CherryPickStatus.CONFLICTING: { return(Stop(commitToPick)); } case CherryPickResult.CherryPickStatus.OK: { newHead = cherryPickResult.GetNewHead(); break; } } } } finally { monitor.EndTask(); } } if (newHead != null) { string headName = ReadFile(rebaseDir, HEAD_NAME); UpdateHead(headName, newHead); FileUtils.Delete(rebaseDir, FileUtils.RECURSIVE); if (lastStepWasForward) { return(RebaseResult.FAST_FORWARD_RESULT); } return(RebaseResult.OK_RESULT); } return(RebaseResult.FAST_FORWARD_RESULT); } catch (IOException ioe) { throw new JGitInternalException(ioe.Message, ioe); } }
/// <summary> /// Executes the /// <code>commit</code> /// command with all the options and parameters /// collected by the setter methods of this class. Each instance of this /// class should only be used for one invocation of the command (means: one /// call to /// <see cref="Call()">Call()</see> /// ) /// </summary> /// <returns> /// a /// <see cref="NGit.Revwalk.RevCommit">NGit.Revwalk.RevCommit</see> /// object representing the successful commit. /// </returns> /// <exception cref="NGit.Api.Errors.NoHeadException">when called on a git repo without a HEAD reference /// </exception> /// <exception cref="NGit.Api.Errors.NoMessageException">when called without specifying a commit message /// </exception> /// <exception cref="NGit.Errors.UnmergedPathException">when the current index contained unmerged paths (conflicts) /// </exception> /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">when repository is not in the right state for committing /// </exception> /// <exception cref="NGit.Api.Errors.JGitInternalException"> /// a low-level exception of JGit has occurred. The original /// exception can be retrieved by calling /// <see cref="System.Exception.InnerException()">System.Exception.InnerException()</see> /// . Expect only /// <code>IOException's</code> /// to be wrapped. Subclasses of /// <see cref="System.IO.IOException">System.IO.IOException</see> /// (e.g. /// <see cref="NGit.Errors.UnmergedPathException">NGit.Errors.UnmergedPathException</see> /// ) are /// typically not wrapped here but thrown as original exception /// </exception> /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException"></exception> public override RevCommit Call() { CheckCallable(); RepositoryState state = repo.GetRepositoryState(); if (!state.CanCommit()) { throw new WrongRepositoryStateException(MessageFormat.Format(JGitText.Get().cannotCommitOnARepoWithState , state.Name())); } ProcessOptions(state); try { if (all && !repo.IsBare && repo.WorkTree != null) { Git git = new Git(repo); try { git.Add().AddFilepattern(".").SetUpdate(true).Call(); } catch (NoFilepatternException e) { // should really not happen throw new JGitInternalException(e.Message, e); } } Ref head = repo.GetRef(Constants.HEAD); if (head == null) { throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported ); } // determine the current HEAD and the commit it is referring to ObjectId headId = repo.Resolve(Constants.HEAD + "^{commit}"); if (headId != null) { if (amend) { RevCommit previousCommit = new RevWalk(repo).ParseCommit(headId); RevCommit[] p = previousCommit.Parents; for (int i = 0; i < p.Length; i++) { parents.Add(0, p[i].Id); } } else { parents.Add(0, headId); } } // lock the index DirCache index = repo.LockDirCache(); try { ObjectInserter odi = repo.NewObjectInserter(); try { // Write the index as tree to the object database. This may // fail for example when the index contains unmerged paths // (unresolved conflicts) ObjectId indexTreeId = index.WriteTree(odi); // Create a Commit object, populate it and write it NGit.CommitBuilder commit = new NGit.CommitBuilder(); commit.Committer = committer; commit.Author = author; commit.Message = message; commit.SetParentIds(parents); commit.TreeId = indexTreeId; ObjectId commitId = odi.Insert(commit); odi.Flush(); RevWalk revWalk = new RevWalk(repo); try { RevCommit revCommit = revWalk.ParseCommit(commitId); RefUpdate ru = repo.UpdateRef(Constants.HEAD); ru.SetNewObjectId(commitId); ru.SetRefLogMessage("commit : " + revCommit.GetShortMessage(), false); ru.SetExpectedOldObjectId(headId); RefUpdate.Result rc = ru.ForceUpdate(); switch (rc) { case RefUpdate.Result.NEW: case RefUpdate.Result.FORCED: case RefUpdate.Result.FAST_FORWARD: { SetCallable(false); if (state == RepositoryState.MERGING_RESOLVED) { // Commit was successful. Now delete the files // used for merge commits repo.WriteMergeCommitMsg(null); repo.WriteMergeHeads(null); } return(revCommit); } case RefUpdate.Result.REJECTED: case RefUpdate.Result.LOCK_FAILURE: { throw new ConcurrentRefUpdateException(JGitText.Get().couldNotLockHEAD, ru.GetRef (), rc); } default: { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().updatingRefFailed , Constants.HEAD, commitId.ToString(), rc)); } } } finally { revWalk.Release(); } } finally { odi.Release(); } } finally { index.Unlock(); } } catch (UnmergedPathException e) { // since UnmergedPathException is a subclass of IOException // which should not be wrapped by a JGitInternalException we // have to catch and re-throw it here throw; } catch (IOException e) { throw new JGitInternalException(JGitText.Get().exceptionCaughtDuringExecutionOfCommitCommand , e); } }
} // End Sub ListAllBranches // https://stackoverflow.com/questions/15822544/jgit-how-to-get-all-commits-of-a-branch-without-changes-to-the-working-direct public static void WalkCommits() { string dir = GetRepoPath(); Git git = Git.Open(dir); Repository repo = git.GetRepository(); RevWalk walk = new RevWalk(repo); System.Collections.Generic.IList <Ref> branches = git.BranchList().Call(); // https://stackoverflow.com/questions/15822544/jgit-how-to-get-all-commits-of-a-branch-without-changes-to-the-working-direct foreach (Ref branch in branches) { string branchName = branch.GetName(); System.Console.WriteLine("Commits of branch: " + branchName); System.Console.WriteLine("-------------------------------------"); Sharpen.Iterable <RevCommit> commits = git.Log().All().Call(); foreach (RevCommit commit in commits) { bool foundInThisBranch = false; RevCommit targetCommit = walk.ParseCommit(repo.Resolve(commit.Name)); foreach (System.Collections.Generic.KeyValuePair <string, Ref> e in repo.GetAllRefs()) { if (e.Key.StartsWith(Constants.R_HEADS)) { if (walk.IsMergedInto(targetCommit, walk.ParseCommit(e.Value.GetObjectId()))) { string foundInBranch = e.Value.GetName(); if (branchName.Equals(foundInBranch)) { foundInThisBranch = true; break; } // End if (branchName.Equals(foundInBranch)) } // End if (walk.IsMergedInto(targetCommit, walk.ParseCommit(e.Value.GetObjectId()))) } // End if (e.Key.StartsWith(Constants.R_HEADS)) } // Next e if (foundInThisBranch) { System.Console.WriteLine(commit.Name); System.Console.WriteLine(commit.GetAuthorIdent().GetName()); // System.DateTime dt = new System.DateTime(commit.CommitTime); System.DateTime dt = UnixTimeStampToDateTime(commit.CommitTime); System.Console.WriteLine(dt); System.Console.WriteLine(commit.GetFullMessage()); } // End if (foundInThisBranch) } // Next commit } // Next branch // Handle disposing of NGit's locks repo.Close(); repo.ObjectDatabase.Close(); repo = null; git = null; } // End Sub
public Stash Create(NGit.ProgressMonitor monitor, string message) { if (monitor != null) { monitor.Start(1); monitor.BeginTask("Stashing changes", 100); } UserConfig config = _repo.GetConfig().Get(UserConfig.KEY); RevWalk rw = new RevWalk(_repo); ObjectId headId = _repo.Resolve(Constants.HEAD); var parent = rw.ParseCommit(headId); PersonIdent author = new PersonIdent(config.GetAuthorName() ?? "unknown", config.GetAuthorEmail() ?? "unknown@(none)."); if (string.IsNullOrEmpty(message)) { // Use the commit summary as message message = parent.Abbreviate(7).ToString() + " " + parent.GetShortMessage(); int i = message.IndexOfAny(new char[] { '\r', '\n' }); if (i != -1) { message = message.Substring(0, i); } } // Create the index tree commit ObjectInserter inserter = _repo.NewObjectInserter(); DirCache dc = _repo.ReadDirCache(); if (monitor != null) { monitor.Update(10); } var tree_id = dc.WriteTree(inserter); inserter.Release(); if (monitor != null) { monitor.Update(10); } string commitMsg = "index on " + _repo.GetBranch() + ": " + message; ObjectId indexCommit = GitUtil.CreateCommit(_repo, commitMsg + "\n", new ObjectId[] { headId }, tree_id, author, author); if (monitor != null) { monitor.Update(20); } // Create the working dir commit tree_id = WriteWorkingDirectoryTree(parent.Tree, dc); commitMsg = "WIP on " + _repo.GetBranch() + ": " + message; var wipCommit = GitUtil.CreateCommit(_repo, commitMsg + "\n", new ObjectId[] { headId, indexCommit }, tree_id, author, author); if (monitor != null) { monitor.Update(20); } string prevCommit = null; FileInfo sf = StashRefFile; if (sf.Exists) { prevCommit = File.ReadAllText(sf.FullName).Trim(' ', '\t', '\r', '\n'); } Stash s = new Stash(prevCommit, wipCommit.Name, author, commitMsg); FileInfo stashLog = StashLogFile; File.AppendAllText(stashLog.FullName, s.FullLine + "\n"); File.WriteAllText(sf.FullName, s.CommitId + "\n"); if (monitor != null) { monitor.Update(5); } // Wipe all local changes GitUtil.HardReset(_repo, Constants.HEAD); monitor.EndTask(); s.StashCollection = this; return(s); }
public override string GetTextAtRevision (FilePath repositoryPath, Revision revision) { var repository = GetRepository (repositoryPath); ObjectId id = repository.Resolve (revision.ToString ()); RevWalk rw = new RevWalk (repository); RevCommit c = rw.ParseCommit (id); if (c == null) return string.Empty; else return GetCommitTextContent (c, repositoryPath); }
public static MergeCommandResult MergeTrees(NGit.ProgressMonitor monitor, NGit.Repository repo, RevCommit srcBase, RevCommit srcCommit, string sourceDisplayName, bool commitResult) { RevCommit newHead = null; RevWalk revWalk = new RevWalk(repo); try { // get the head commit Ref headRef = repo.GetRef(Constants.HEAD); if (headRef == null) { throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported ); } RevCommit headCommit = revWalk.ParseCommit(headRef.GetObjectId()); ResolveMerger merger = (ResolveMerger)((ThreeWayMerger)MergeStrategy.RESOLVE.NewMerger (repo)); merger.SetWorkingTreeIterator(new FileTreeIterator(repo)); merger.SetBase(srcBase); bool noProblems; IDictionary <string, MergeResult <NGit.Diff.Sequence> > lowLevelResults = null; IDictionary <string, ResolveMerger.MergeFailureReason> failingPaths = null; IList <string> modifiedFiles = null; ResolveMerger resolveMerger = (ResolveMerger)merger; resolveMerger.SetCommitNames(new string[] { "BASE", "HEAD", sourceDisplayName }); noProblems = merger.Merge(headCommit, srcCommit); lowLevelResults = resolveMerger.GetMergeResults(); modifiedFiles = resolveMerger.GetModifiedFiles(); failingPaths = resolveMerger.GetFailingPaths(); if (monitor != null) { monitor.Update(50); } if (noProblems) { if (modifiedFiles != null && modifiedFiles.Count == 0) { return(new MergeCommandResult(headCommit, null, new ObjectId[] { headCommit.Id, srcCommit .Id }, MergeStatus.ALREADY_UP_TO_DATE, MergeStrategy.RESOLVE, null, null)); } DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache (), merger.GetResultTreeId()); dco.SetFailOnConflict(true); dco.Checkout(); if (commitResult) { newHead = new NGit.Api.Git(repo).Commit().SetMessage(srcCommit.GetFullMessage() ).SetAuthor(srcCommit.GetAuthorIdent()).Call(); return(new MergeCommandResult(newHead.Id, null, new ObjectId[] { headCommit.Id, srcCommit .Id }, MergeStatus.MERGED, MergeStrategy.RESOLVE, null, null)); } else { return(new MergeCommandResult(headCommit, null, new ObjectId[] { headCommit.Id, srcCommit .Id }, MergeStatus.MERGED, MergeStrategy.RESOLVE, null, null)); } } else { if (failingPaths != null) { return(new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] { headCommit.Id, srcCommit.Id }, MergeStatus.FAILED, MergeStrategy.RESOLVE, lowLevelResults , failingPaths, null)); } else { return(new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] { headCommit.Id, srcCommit.Id }, MergeStatus.CONFLICTING, MergeStrategy.RESOLVE, lowLevelResults , null)); } } } finally { revWalk.Release(); } }
/// <summary>Apply the changes in a stashed commit to the working directory and index /// </summary> /// <returns>id of stashed commit that was applied</returns> /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException /// </exception> /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">NGit.Api.Errors.WrongRepositoryStateException /// </exception> public override ObjectId Call() { CheckCallable(); if (repo.GetRepositoryState() != RepositoryState.SAFE) { throw new WrongRepositoryStateException(MessageFormat.Format(JGitText.Get().stashApplyOnUnsafeRepository , repo.GetRepositoryState())); } ObjectId headTree = GetHeadTree(); ObjectId stashId = GetStashId(); ObjectReader reader = repo.NewObjectReader(); try { RevWalk revWalk = new RevWalk(reader); RevCommit stashCommit = revWalk.ParseCommit(stashId); if (stashCommit.ParentCount != 2) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().stashCommitMissingTwoParents , stashId.Name)); } RevTree stashWorkingTree = stashCommit.Tree; RevTree stashIndexTree = revWalk.ParseCommit(stashCommit.GetParent(1)).Tree; RevTree stashHeadTree = revWalk.ParseCommit(stashCommit.GetParent(0)).Tree; CanonicalTreeParser stashWorkingIter = new CanonicalTreeParser(); stashWorkingIter.Reset(reader, stashWorkingTree); CanonicalTreeParser stashIndexIter = new CanonicalTreeParser(); stashIndexIter.Reset(reader, stashIndexTree); CanonicalTreeParser stashHeadIter = new CanonicalTreeParser(); stashHeadIter.Reset(reader, stashHeadTree); CanonicalTreeParser headIter = new CanonicalTreeParser(); headIter.Reset(reader, headTree); DirCache cache = repo.LockDirCache(); DirCacheEditor editor = cache.Editor(); try { DirCacheIterator indexIter = new DirCacheIterator(cache); FileTreeIterator workingIter = new FileTreeIterator(repo); TreeWalk treeWalk = new TreeWalk(reader); treeWalk.Recursive = true; treeWalk.Filter = new StashApplyCommand.StashDiffFilter(); treeWalk.AddTree(stashHeadIter); treeWalk.AddTree(stashIndexIter); treeWalk.AddTree(stashWorkingIter); treeWalk.AddTree(headIter); treeWalk.AddTree(indexIter); treeWalk.AddTree(workingIter); ScanForConflicts(treeWalk); // Reset trees and walk treeWalk.Reset(); stashWorkingIter.Reset(reader, stashWorkingTree); stashIndexIter.Reset(reader, stashIndexTree); stashHeadIter.Reset(reader, stashHeadTree); treeWalk.AddTree(stashHeadIter); treeWalk.AddTree(stashIndexIter); treeWalk.AddTree(stashWorkingIter); ApplyChanges(treeWalk, cache, editor); } finally { editor.Commit(); cache.Unlock(); } } catch (JGitInternalException e) { throw; } catch (IOException e) { throw new JGitInternalException(JGitText.Get().stashApplyFailed, e); } finally { reader.Release(); } return(stashId); }
public static void MergeTest(EngineContext engineContext) { // TODO: Currently hardcoded var db = new FileRepository(new FilePath(@"C:\DEV\hotei_scene", Constants.DOT_GIT)); var git = new Git(db); var tree1Ref = db.GetRef("test"); var tree2Ref = db.GetRef(Constants.HEAD); var tree1CommitId = tree1Ref.GetObjectId(); var tree2CommitId = tree2Ref.GetObjectId(); // Merge tree1 into current tree var mergeResult = git.Merge().Include(tree1CommitId).Call(); if (mergeResult.GetMergeStatus() == MergeStatus.CONFLICTING) { foreach (var conflict in mergeResult.GetConflicts()) { if (conflict.Key.EndsWith(".hotei")) { // Search base tree (common ancestor), if any var walk = new RevWalk(db); walk.SetRevFilter(RevFilter.MERGE_BASE); walk.MarkStart(walk.ParseCommit(tree1CommitId)); walk.MarkStart(walk.ParseCommit(tree2CommitId)); var baseTree = walk.Next(); var tw = new NameConflictTreeWalk(db); tw.AddTree(new RevWalk(db).ParseTree(tree1CommitId).ToObjectId()); tw.AddTree(new RevWalk(db).ParseTree(tree2CommitId).ToObjectId()); if (baseTree != null) { tw.AddTree(new RevWalk(db).ParseTree(baseTree.ToObjectId()).ToObjectId()); } tw.Filter = PathFilter.Create(conflict.Key); // Should be only one iteration while (tw.Next()) { var tree0 = baseTree != null?tw.GetTree <AbstractTreeIterator>(2) : null; var tree1 = tw.GetTree <AbstractTreeIterator>(0); var tree2 = tw.GetTree <AbstractTreeIterator>(1); // Get contents of every versions for the 3-way merge var data0 = baseTree != null?LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree0.EntryObjectId).GetBytes())) : null; var data1 = LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree1.EntryObjectId).GetBytes())); var data2 = LoadEntities(new MemoryStream(tw.ObjectReader.Open(tree2.EntryObjectId).GetBytes())); // Perform 3-way merge var entities = new List <EntityDefinition>(); ThreeWayMergeOrdered.Merge(entities, data0, data1, data2, x => x.Guid, (x, y) => x == y, ResolveEntityConflicts); // Save new merged file var fileStream = new FileStream(new FilePath(db.WorkTree, conflict.Key), FileMode.Create, FileAccess.Write); var stream = new BinarySerializationWriter(fileStream); stream.Context.Serializer = Serializer; stream.SerializeClass(null, ref entities, ArchiveMode.Serialize); fileStream.Close(); // TODO: Check if all conflicts are really resolved // Add resolved file for merge commit git.Add().AddFilepattern(conflict.Key).Call(); } } } } }
public static IEnumerable<Change> GetChangedFiles (NGit.Repository repo, string refRev) { // Get a list of files that are different in the target branch RevWalk rw = new RevWalk (repo); ObjectId remCommitId = repo.Resolve (refRev); if (remCommitId == null) return null; RevCommit remCommit = rw.ParseCommit (remCommitId); ObjectId headId = repo.Resolve (Constants.HEAD); if (headId == null) return null; RevCommit headCommit = rw.ParseCommit (headId); return GitUtil.CompareCommits (repo, headCommit, remCommit); }
public static FileRepository Clone (string targetLocalPath, string url, IProgressMonitor monitor) { // Initialize InitCommand ci = new InitCommand (); ci.SetDirectory (targetLocalPath); var git = ci.Call (); FileRepository repo = (FileRepository) git.GetRepository (); string branch = Constants.R_HEADS + "master"; string remoteName = "origin"; RefUpdate head = repo.UpdateRef (Constants.HEAD); head.DisableRefLog (); head.Link (branch); RemoteConfig remoteConfig = new RemoteConfig (repo.GetConfig (), remoteName); remoteConfig.AddURI (new URIish (url)); string dst = Constants.R_REMOTES + remoteConfig.Name; RefSpec wcrs = new RefSpec(); wcrs = wcrs.SetForceUpdate (true); wcrs = wcrs.SetSourceDestination (Constants.R_HEADS + "*", dst + "/*"); remoteConfig.AddFetchRefSpec (wcrs); // we're setting up for a clone with a checkout repo.GetConfig().SetBoolean ("core", null, "bare", false); remoteConfig.Update (repo.GetConfig()); repo.GetConfig().Save(); // Fetch Transport tn = Transport.Open (repo, remoteName); FetchResult r; try { r = tn.Fetch(new GitMonitor (monitor), null); } finally { tn.Close (); } // Create the master branch // branch is like 'Constants.R_HEADS + branchName', we need only // the 'branchName' part String branchName = branch.Substring (Constants.R_HEADS.Length); git.BranchCreate ().SetName (branchName).SetUpstreamMode (CreateBranchCommand.SetupUpstreamMode.TRACK).SetStartPoint ("origin/master").Call (); // Checkout DirCache dc = repo.LockDirCache (); try { RevWalk rw = new RevWalk (repo); ObjectId remCommitId = repo.Resolve (remoteName + "/" + branchName); RevCommit remCommit = rw.ParseCommit (remCommitId); DirCacheCheckout co = new DirCacheCheckout (repo, null, dc, remCommit.Tree); co.Checkout (); } catch { dc.Unlock (); throw; } return repo; }
public static MergeCommandResult MergeTrees (NGit.Repository repo, RevCommit srcBase, RevCommit srcCommit, string sourceDisplayName, bool commitResult) { RevCommit newHead = null; RevWalk revWalk = new RevWalk(repo); try { // get the head commit Ref headRef = repo.GetRef(Constants.HEAD); if (headRef == null) { throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported ); } RevCommit headCommit = revWalk.ParseCommit(headRef.GetObjectId()); ResolveMerger merger = (ResolveMerger)((ThreeWayMerger)MergeStrategy.RESOLVE.NewMerger (repo)); // CherryPick command sets the working tree, but this should not be necessary, and when setting it // untracked files are deleted during the merge // merger.SetWorkingTreeIterator(new FileTreeIterator(repo)); merger.SetBase(srcBase); bool noProblems; IDictionary<string, MergeResult<NGit.Diff.Sequence>> lowLevelResults = null; IDictionary<string, ResolveMerger.MergeFailureReason> failingPaths = null; IList<string> modifiedFiles = null; ResolveMerger resolveMerger = (ResolveMerger)merger; resolveMerger.SetCommitNames(new string[] { "BASE", "HEAD", sourceDisplayName }); noProblems = merger.Merge(headCommit, srcCommit); lowLevelResults = resolveMerger.GetMergeResults(); modifiedFiles = resolveMerger.GetModifiedFiles(); failingPaths = resolveMerger.GetFailingPaths(); if (noProblems) { if (modifiedFiles != null && modifiedFiles.Count == 0) { return new MergeCommandResult(headCommit, null, new ObjectId[] { headCommit.Id, srcCommit .Id }, MergeStatus.ALREADY_UP_TO_DATE, MergeStrategy.RESOLVE, null, null); } DirCacheCheckout dco = new DirCacheCheckout(repo, headCommit.Tree, repo.LockDirCache (), merger.GetResultTreeId()); dco.SetFailOnConflict(true); dco.Checkout(); if (commitResult) { newHead = new NGit.Api.Git(repo).Commit().SetMessage(srcCommit.GetFullMessage() ).SetAuthor(srcCommit.GetAuthorIdent()).Call(); return new MergeCommandResult(newHead.Id, null, new ObjectId[] { headCommit.Id, srcCommit .Id }, MergeStatus.MERGED, MergeStrategy.RESOLVE, null, null); } else { return new MergeCommandResult(headCommit, null, new ObjectId[] { headCommit.Id, srcCommit .Id }, MergeStatus.MERGED, MergeStrategy.RESOLVE, null, null); } } else { if (failingPaths != null) { return new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] { headCommit.Id, srcCommit.Id }, MergeStatus.FAILED, MergeStrategy.RESOLVE, lowLevelResults , null); } else { return new MergeCommandResult(null, merger.GetBaseCommit(0, 1), new ObjectId[] { headCommit.Id, srcCommit.Id }, MergeStatus.CONFLICTING, MergeStrategy.RESOLVE, lowLevelResults , null); } } } finally { revWalk.Release(); } }
public static RevCommit[] Blame (NGit.Repository repo, RevCommit c, string file) { TreeWalk tw = TreeWalk.ForPath (repo, ToGitPath (repo, file), c.Tree); if (tw == null) return new RevCommit [0]; ObjectId id = tw.GetObjectId (0); byte[] data = repo.ObjectDatabase.Open (id).GetBytes (); int lineCount = NGit.Util.RawParseUtils.LineMap (data, 0, data.Length).Size (); RevCommit[] lines = new RevCommit [lineCount]; var curText = new RawText (data); RevCommit prevAncestor = c; ObjectId prevObjectId = null; RevCommit prevCommit = null; int emptyLines = lineCount; RevWalk rw = new RevWalk (repo); foreach (ObjectId ancestorId in c.Parents) { RevCommit ancestor = rw.ParseCommit (ancestorId); tw = TreeWalk.ForPath (repo, ToGitPath (repo, file), ancestor.Tree); if (prevCommit != null && (tw == null || tw.GetObjectId (0) != prevObjectId)) { if (prevObjectId == null) break; byte[] prevData = repo.ObjectDatabase.Open (prevObjectId).GetBytes (); var prevText = new RawText (prevData); var differ = MyersDiff<RawText>.INSTANCE; foreach (Edit e in differ.Diff (RawTextComparator.DEFAULT, prevText, curText)) { for (int n = e.GetBeginB (); n < e.GetEndB (); n++) { if (lines [n] == null) { lines [n] = prevCommit; emptyLines--; } } } if (tw == null || emptyLines <= 0) break; } prevCommit = ancestor; prevObjectId = tw != null ? tw.GetObjectId (0) : null; } for (int n=0; n<lines.Length; n++) if (lines [n] == null) lines [n] = prevAncestor; return lines; }
protected override string OnGetTextAtRevision (FilePath repositoryPath, Revision revision) { var repository = GetRepository (repositoryPath); ObjectId id = repository.Resolve (revision.ToString ()); RevWalk rw = new RevWalk (repository); RevCommit c = rw.ParseCommit (id); return c == null ? string.Empty : GetCommitTextContent (c, repositoryPath); }
public static MergeCommandResult CherryPick (NGit.Repository repo, RevCommit srcCommit) { RevCommit newHead = null; RevWalk revWalk = new RevWalk(repo); try { // get the head commit Ref headRef = repo.GetRef(Constants.HEAD); if (headRef == null) { throw new NoHeadException(JGitText.Get().commitOnRepoWithoutHEADCurrentlyNotSupported ); } RevCommit headCommit = revWalk.ParseCommit(headRef.GetObjectId()); // get the parent of the commit to cherry-pick if (srcCommit.ParentCount != 1) { throw new MultipleParentsNotAllowedException(JGitText.Get().canOnlyCherryPickCommitsWithOneParent ); } RevCommit srcParent = srcCommit.GetParent(0); revWalk.ParseHeaders(srcParent); return MergeTrees (repo, srcParent, srcCommit, srcCommit.Name, true); } catch (IOException e) { throw new Exception ("Commit failed", e); } finally { revWalk.Release(); } }
public virtual void TestStopOnConflictCommitAndContinue() { // create file1 on master RevCommit firstInMaster = WriteFileAndCommit(FILE1, "Add file1", "1", "2", "3"); // change in master WriteFileAndCommit(FILE1, "change file1 in master", "1master", "2", "3"); CheckFile(FILE1, "1master", "2", "3"); // create a topic branch based on the first commit CreateBranch(firstInMaster, "refs/heads/topic"); CheckoutBranch("refs/heads/topic"); // we have the old content again CheckFile(FILE1, "1", "2", "3"); // add a line (non-conflicting) WriteFileAndCommit(FILE1, "add a line to file1 in topic", "1", "2", "3", "4topic" ); // change first line (conflicting) WriteFileAndCommit(FILE1, "change file1 in topic\n\nThis is conflicting", "1topic" , "2", "3", "4topic"); // change second line (not conflicting) WriteFileAndCommit(FILE1, "change file1 in topic again", "1topic", "2", "3topic", "4topic"); RebaseResult res = git.Rebase().SetUpstream("refs/heads/master").Call(); NUnit.Framework.Assert.AreEqual(RebaseResult.Status.STOPPED, res.GetStatus()); // continue should throw a meaningful exception try { res = git.Rebase().SetOperation(RebaseCommand.Operation.CONTINUE).Call(); NUnit.Framework.Assert.Fail("Expected Exception not thrown"); } catch (UnmergedPathsException) { } // expected // merge the file; the second topic commit should go through WriteFileAndCommit(FILE1, "A different commit message", "1topic", "2", "3", "4topic" ); res = git.Rebase().SetOperation(RebaseCommand.Operation.CONTINUE).Call(); NUnit.Framework.Assert.IsNotNull(res); NUnit.Framework.Assert.AreEqual(RebaseResult.Status.OK, res.GetStatus()); NUnit.Framework.Assert.AreEqual(RepositoryState.SAFE, db.GetRepositoryState()); ObjectId headId = db.Resolve(Constants.HEAD); RevWalk rw = new RevWalk(db); RevCommit rc = rw.ParseCommit(headId); RevCommit parent = rw.ParseCommit(rc.GetParent(0)); NUnit.Framework.Assert.AreEqual("A different commit message", parent.GetFullMessage ()); }
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); } // Switch to the target branch DirCache dc = RootRepository.LockDirCache (); try { RevWalk rw = new RevWalk (RootRepository); ObjectId branchHeadId = RootRepository.Resolve (branch); if (branchHeadId == null) throw new InvalidOperationException ("Branch head commit not found"); RevCommit branchCommit = rw.ParseCommit (branchHeadId); DirCacheCheckout checkout = new DirCacheCheckout (RootRepository, null, dc, branchCommit.Tree); checkout.Checkout (); RefUpdate u = RootRepository.UpdateRef(Constants.HEAD); u.Link ("refs/heads/" + branch); monitor.Step (1); } catch { dc.Unlock (); if (GitService.StashUnstashWhenSwitchingBranches) { // If something goes wrong, restore the work tree status using (var gm = new GitMonitor (monitor)) stash.Apply (gm); stashes.Remove (stash); } throw; } // 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 (); }
/// <exception cref="NGit.Errors.MissingObjectException"></exception> /// <exception cref="NGit.Errors.IncorrectObjectTypeException"></exception> /// <exception cref="System.IO.IOException"></exception> private RevCommit ParseCommit(AnyObjectId id) { RevWalk rw = new RevWalk(db); try { return rw.ParseCommit(id); } finally { rw.Release(); } }
public DiffInfo[] GetPushDiff (string remote, string branch) { ObjectId cid1 = RootRepository.Resolve (remote + "/" + branch); ObjectId cid2 = RootRepository.Resolve (RootRepository.GetBranch ()); RevWalk rw = new RevWalk (RootRepository); RevCommit c1 = rw.ParseCommit (cid1); RevCommit c2 = rw.ParseCommit (cid2); List<DiffInfo> diffs = new List<DiffInfo> (); foreach (var change in GitUtil.CompareCommits (RootRepository, c1, c2)) { string diff; switch (change.GetChangeType ()) { case DiffEntry.ChangeType.DELETE: diff = GenerateDiff (EmptyContent, GetCommitContent (c2, change.GetOldPath ())); break; case DiffEntry.ChangeType.ADD: diff = GenerateDiff (GetCommitContent (c1, change.GetNewPath ()), EmptyContent); break; default: diff = GenerateDiff (GetCommitContent (c1, change.GetNewPath ()), GetCommitContent (c2, change.GetNewPath ())); break; } DiffInfo di = new DiffInfo (RootPath, RootRepository.FromGitPath (change.GetNewPath ()), diff); diffs.Add (di); } return diffs.ToArray (); }
public bool IsBranchMerged (string branchName) { // check if a branch is merged into HEAD RevWalk walk = new RevWalk(RootRepository); RevCommit tip = walk.ParseCommit(RootRepository.Resolve(Constants.HEAD)); Ref currentRef = RootRepository.GetRef(branchName); if (currentRef == null) return true; RevCommit @base = walk.ParseCommit(RootRepository.Resolve(branchName)); return walk.IsMergedInto(@base, tip); }
/// <exception cref="NGit.Api.Errors.RefAlreadyExistsException"> /// when trying to create (without force) a branch with a name /// that already exists /// </exception> /// <exception cref="NGit.Api.Errors.RefNotFoundException">if the start point or branch can not be found /// </exception> /// <exception cref="NGit.Api.Errors.InvalidRefNameException"> /// if the provided name is <code>null</code> or otherwise /// invalid /// </exception> /// <returns>the newly created branch</returns> /// <exception cref="NGit.Api.Errors.JGitInternalException"></exception> public override Ref Call() { CheckCallable(); ProcessOptions(); try { if (!paths.IsEmpty()) { CheckoutPaths(); status = CheckoutResult.OK_RESULT; SetCallable(false); return(null); } if (createBranch) { Git git = new Git(repo); CreateBranchCommand command = git.BranchCreate(); command.SetName(name); command.SetStartPoint(GetStartPoint().Name); if (upstreamMode != null) { command.SetUpstreamMode(upstreamMode); } command.Call(); } Ref headRef = repo.GetRef(Constants.HEAD); string refLogMessage = "checkout: moving from " + headRef.GetTarget().GetName(); ObjectId branch = repo.Resolve(name); if (branch == null) { throw new RefNotFoundException(MessageFormat.Format(JGitText.Get().refNotResolved , name)); } RevWalk revWalk = new RevWalk(repo); AnyObjectId headId = headRef.GetObjectId(); RevCommit headCommit = headId == null ? null : revWalk.ParseCommit(headId); RevCommit newCommit = revWalk.ParseCommit(branch); RevTree headTree = headCommit == null ? null : headCommit.Tree; DirCacheCheckout dco = new DirCacheCheckout(repo, headTree, repo.LockDirCache(), newCommit.Tree); dco.SetFailOnConflict(true); try { dco.Checkout(); } catch (NGit.Errors.CheckoutConflictException e) { status = new CheckoutResult(CheckoutResult.Status.CONFLICTS, dco.GetConflicts()); throw; } Ref @ref = repo.GetRef(name); if (@ref != null && [email protected]().StartsWith(Constants.R_HEADS)) { @ref = null; } RefUpdate refUpdate = repo.UpdateRef(Constants.HEAD, @ref == null); refUpdate.SetForceUpdate(force); refUpdate.SetRefLogMessage(refLogMessage + " to " + newCommit.GetName(), false); RefUpdate.Result updateResult; if (@ref != null) { updateResult = refUpdate.Link(@ref.GetName()); } else { refUpdate.SetNewObjectId(newCommit); updateResult = refUpdate.ForceUpdate(); } SetCallable(false); bool ok = false; switch (updateResult) { case RefUpdate.Result.NEW: { ok = true; break; } case RefUpdate.Result.NO_CHANGE: case RefUpdate.Result.FAST_FORWARD: case RefUpdate.Result.FORCED: { ok = true; break; } default: { break; break; } } if (!ok) { throw new JGitInternalException(MessageFormat.Format(JGitText.Get().checkoutUnexpectedResult , updateResult.ToString())); } if (!dco.GetToBeDeleted().IsEmpty()) { status = new CheckoutResult(CheckoutResult.Status.NONDELETED, dco.GetToBeDeleted( )); } else { status = CheckoutResult.OK_RESULT; } return(@ref); } catch (IOException ioe) { throw new JGitInternalException(ioe.Message, ioe); } finally { if (status == null) { status = CheckoutResult.ERROR_RESULT; } } }
public ChangeSet GetPushChangeSet (string remote, string branch) { ChangeSet cset = CreateChangeSet (RootPath); ObjectId cid1 = RootRepository.Resolve (remote + "/" + branch); ObjectId cid2 = RootRepository.Resolve (RootRepository.GetBranch ()); RevWalk rw = new RevWalk (RootRepository); RevCommit c1 = rw.ParseCommit (cid1); RevCommit c2 = rw.ParseCommit (cid2); foreach (var change in GitUtil.CompareCommits (RootRepository, c2, c1)) { VersionStatus status; switch (change.GetChangeType ()) { case DiffEntry.ChangeType.ADD: status = VersionStatus.ScheduledAdd; break; case DiffEntry.ChangeType.DELETE: status = VersionStatus.ScheduledDelete; break; default: status = VersionStatus.Modified; break; } VersionInfo vi = new VersionInfo (RootRepository.FromGitPath (change.GetNewPath ()), "", false, status | VersionStatus.Versioned, null, VersionStatus.Versioned, null); cset.AddFile (vi); } return cset; }
private RevCommit ParseCommit(Repository repo, ObjectId id) { RevWalk rw = new RevWalk(repo); var head = rw.ParseCommit(id); rw.MarkStart(head); RevCommit commit = null; try { commit = rw.Next(); while( commit != null ) { if (commit.Id.Name == id.Name) { return commit; } commit = rw.Next(); } } finally { rw.Release(); } return commit; }
RevCommit GetHeadCommit (NGit.Repository repository) { RevWalk rw = new RevWalk (repository); ObjectId headId = repository.Resolve (Constants.HEAD); if (headId == null) return null; return rw.ParseCommit (headId); }
/// <exception cref="System.InvalidOperationException"></exception> /// <exception cref="System.IO.IOException"></exception> private void CheckoutBranch(string branchName) { RevWalk walk = new RevWalk(db); RevCommit head = walk.ParseCommit(db.Resolve(Constants.HEAD)); RevCommit branch = walk.ParseCommit(db.Resolve(branchName)); DirCacheCheckout dco = new DirCacheCheckout(db, head.Tree, db.LockDirCache(), branch .Tree); dco.SetFailOnConflict(true); NUnit.Framework.Assert.IsTrue(dco.Checkout()); walk.Release(); // update the HEAD RefUpdate refUpdate = db.UpdateRef(Constants.HEAD); NUnit.Framework.Assert.AreEqual(RefUpdate.Result.FORCED, refUpdate.Link(branchName )); }
/// <exception cref="System.InvalidOperationException"></exception> /// <exception cref="System.IO.IOException"></exception> protected internal virtual void CheckoutBranch(string branchName) { RevWalk walk = new RevWalk(db); RevCommit head = walk.ParseCommit(db.Resolve(Constants.HEAD)); RevCommit branch = walk.ParseCommit(db.Resolve(branchName)); DirCacheCheckout dco = new DirCacheCheckout(db, head.Tree.Id, db.LockDirCache(), branch.Tree.Id); dco.SetFailOnConflict(true); dco.Checkout(); walk.Release(); // update the HEAD RefUpdate refUpdate = db.UpdateRef(Constants.HEAD); refUpdate.Link(branchName); }
/// <summary> /// Run the diff operation. Until this is called, all lists will be empty /// </summary> /// <returns>true if anything is different between index, tree, and workdir</returns> private void UpdateDirectory (IEnumerable<string> paths, bool recursive) { RevWalk rw = new RevWalk (Repository); ObjectId id = Repository.Resolve (Constants.HEAD); var commit = id != null ? rw.ParseCommit (id) : null; TreeWalk treeWalk = new TreeWalk (Repository); treeWalk.Reset (); treeWalk.Recursive = false; if (commit != null) treeWalk.AddTree (commit.Tree); else treeWalk.AddTree (new EmptyTreeIterator()); DirCache dc = Repository.ReadDirCache (); treeWalk.AddTree (new DirCacheIterator (dc)); FileTreeIterator workTree = new FileTreeIterator (Repository.WorkTree, Repository.FileSystem, WorkingTreeOptions.KEY.Parse(Repository.GetConfig())); treeWalk.AddTree (workTree); List<TreeFilter> filters = new List<TreeFilter> (); filters.Add (new SkipWorkTreeFilter(1)); var pathFilters = paths.Where (p => p != ".").Select (p => PathFilter.Create (p)).ToArray (); if (pathFilters.Length > 1) { filters.Add (OrTreeFilter.Create (pathFilters)); // Use an OR to join all path filters } else if (pathFilters.Length == 1) filters.Add (pathFilters[0]); if (filters.Count > 1) treeWalk.Filter = AndTreeFilter.Create(filters); else treeWalk.Filter = filters[0]; while (treeWalk.Next()) { AbstractTreeIterator treeIterator = treeWalk.GetTree<AbstractTreeIterator>(0); DirCacheIterator dirCacheIterator = treeWalk.GetTree<DirCacheIterator>(1); WorkingTreeIterator workingTreeIterator = treeWalk.GetTree<WorkingTreeIterator>(2); NGit.FileMode fileModeTree = treeWalk.GetFileMode(0); if (treeWalk.IsSubtree) { treeWalk.EnterSubtree (); continue; } int stage = dirCacheIterator != null ? dirCacheIterator.GetDirCacheEntry ().Stage : 0; if (stage > 1) continue; else if (stage == 1) { MergeConflict.Add(dirCacheIterator.EntryPathString); changesExist = true; continue; } if (treeIterator != null) { if (dirCacheIterator != null) { if (!treeIterator.EntryObjectId.Equals(dirCacheIterator.EntryObjectId)) { // in repo, in index, content diff => changed Modified.Add(dirCacheIterator.EntryPathString); changesExist = true; } } else { // in repo, not in index => removed if (!fileModeTree.Equals(NGit.FileMode.TYPE_TREE)) { Removed.Add(treeIterator.EntryPathString); changesExist = true; } } } else { if (dirCacheIterator != null) { // not in repo, in index => added Added.Add(dirCacheIterator.EntryPathString); changesExist = true; } else { // not in repo, not in index => untracked if (workingTreeIterator != null && !workingTreeIterator.IsEntryIgnored()) { Untracked.Add(workingTreeIterator.EntryPathString); changesExist = true; } } } if (dirCacheIterator != null) { if (workingTreeIterator == null) { // in index, not in workdir => missing Missing.Add(dirCacheIterator.EntryPathString); changesExist = true; } else { // Workaround to file time resolution issues long itime = dirCacheIterator.GetDirCacheEntry ().LastModified; long ftime = workingTreeIterator.GetEntryLastModified (); if (itime / 1000 != ftime / 1000) { if (!dirCacheIterator.IdEqual(workingTreeIterator)) { // in index, in workdir, content differs => modified Modified.Add(dirCacheIterator.EntryPathString); changesExist = true; } } } } } }
protected override Revision GetHeadRevision () { GitRepository repo2 = (GitRepository)repo; RevWalk rw = new RevWalk (repo2.RootRepository); ObjectId headId = repo2.RootRepository.Resolve (Constants.HEAD); if (headId == null) return null; RevCommit commit = rw.ParseCommit (headId); GitRevision rev = new GitRevision (repo, repo2.RootRepository, commit.Id.Name); rev.Commit = commit; return rev; }
/// <summary>Execute the SubmoduleUpdateCommand command.</summary> /// <remarks>Execute the SubmoduleUpdateCommand command.</remarks> /// <returns>a collection of updated submodule paths</returns> /// <exception cref="NGit.Api.Errors.ConcurrentRefUpdateException">NGit.Api.Errors.ConcurrentRefUpdateException /// </exception> /// <exception cref="NGit.Api.Errors.CheckoutConflictException">NGit.Api.Errors.CheckoutConflictException /// </exception> /// <exception cref="NGit.Api.Errors.InvalidMergeHeadsException">NGit.Api.Errors.InvalidMergeHeadsException /// </exception> /// <exception cref="NGit.Api.Errors.InvalidConfigurationException">NGit.Api.Errors.InvalidConfigurationException /// </exception> /// <exception cref="NGit.Api.Errors.NoHeadException">NGit.Api.Errors.NoHeadException /// </exception> /// <exception cref="NGit.Api.Errors.NoMessageException">NGit.Api.Errors.NoMessageException /// </exception> /// <exception cref="NGit.Api.Errors.RefNotFoundException">NGit.Api.Errors.RefNotFoundException /// </exception> /// <exception cref="NGit.Api.Errors.WrongRepositoryStateException">NGit.Api.Errors.WrongRepositoryStateException /// </exception> /// <exception cref="NGit.Api.Errors.GitAPIException">NGit.Api.Errors.GitAPIException /// </exception> public override ICollection <string> Call() { CheckCallable(); try { SubmoduleWalk generator = SubmoduleWalk.ForIndex(repo); if (!paths.IsEmpty()) { generator.SetFilter(PathFilterGroup.CreateFromStrings(paths)); } IList <string> updated = new AList <string>(); while (generator.Next()) { // Skip submodules not registered in .gitmodules file if (generator.GetModulesPath() == null) { continue; } // Skip submodules not registered in parent repository's config string url = generator.GetConfigUrl(); if (url == null) { continue; } Repository submoduleRepo = generator.GetRepository(); // Clone repository is not present if (submoduleRepo == null) { CloneCommand clone = Git.CloneRepository(); Configure(clone); clone.SetURI(url); clone.SetDirectory(generator.GetDirectory()); if (monitor != null) { clone.SetProgressMonitor(monitor); } submoduleRepo = clone.Call().GetRepository(); } try { RevWalk walk = new RevWalk(submoduleRepo); RevCommit commit = walk.ParseCommit(generator.GetObjectId()); string update = generator.GetConfigUpdate(); if (ConfigConstants.CONFIG_KEY_MERGE.Equals(update)) { MergeCommand merge = new MergeCommand(submoduleRepo); merge.Include(commit); merge.Call(); } else { if (ConfigConstants.CONFIG_KEY_REBASE.Equals(update)) { RebaseCommand rebase = new RebaseCommand(submoduleRepo); rebase.SetUpstream(commit); rebase.Call(); } else { // Checkout commit referenced in parent repository's // index as a detached HEAD DirCacheCheckout co = new DirCacheCheckout(submoduleRepo, submoduleRepo.LockDirCache (), commit.Tree); co.SetFailOnConflict(true); co.Checkout(); RefUpdate refUpdate = submoduleRepo.UpdateRef(Constants.HEAD, true); refUpdate.SetNewObjectId(commit); refUpdate.ForceUpdate(); } } } finally { submoduleRepo.Close(); } updated.AddItem(generator.GetPath()); } return(updated); } catch (IOException e) { throw new JGitInternalException(e.Message, e); } catch (ConfigInvalidException e) { throw new InvalidConfigurationException(e.Message, e); } }