/// <summary> /// Returns a list of files that have changed in a commit /// </summary> public static IEnumerable <DiffEntry> GetCommitChanges(NGit.Repository repo, RevCommit commit) { var rev = commit.ToObjectId(); var prev = repo.Resolve(commit.Name + "^") ?? ObjectId.ZeroId; return(CompareCommits(repo, rev, prev)); }
/// <summary> /// Compares two commits and returns a list of files that have changed /// </summary> public static IEnumerable <Change> CompareCommits(NGit.Repository repo, RevCommit reference, RevCommit compared) { var changes = new List <Change>(); if (reference == null && compared == null) { return(changes); } ObjectId refTree = (reference != null ? reference.Tree.Id : ObjectId.ZeroId); ObjectId comparedTree = (compared != null ? compared.Tree.Id : ObjectId.ZeroId); var walk = new TreeWalk(repo); if (reference == null || compared == null) { walk.Reset((reference ?? compared).Tree.Id); } else { walk.Reset(new AnyObjectId[] { refTree, comparedTree }); } walk.Recursive = true; walk.Filter = AndTreeFilter.Create(TreeFilter.ANY_DIFF, TreeFilter.ALL); return(CalculateCommitDiff(repo, walk, new[] { reference, compared })); }
public static string GetUpstreamSource(NGit.Repository repo, string branch) { StoredConfig config = repo.GetConfig(); string remote = config.GetString("branch", branch, "remote"); string rbranch = config.GetString("branch", branch, "merge"); if (string.IsNullOrEmpty(rbranch)) { return(null); } if (rbranch.StartsWith(Constants.R_HEADS, System.StringComparison.Ordinal)) { rbranch = rbranch.Substring(Constants.R_HEADS.Length); } else if (rbranch.StartsWith(Constants.R_TAGS, System.StringComparison.Ordinal)) { rbranch = rbranch.Substring(Constants.R_TAGS.Length); } if (!string.IsNullOrEmpty(remote) && remote != ".") { return(remote + "/" + rbranch); } else { return(rbranch); } }
public static ObjectId CreateCommit(NGit.Repository rep, string message, IList <ObjectId> parents, ObjectId indexTreeId, PersonIdent author, PersonIdent committer) { try { ObjectInserter odi = rep.NewObjectInserter(); try { // 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(); return(commitId); } finally { odi.Release(); } } catch (UnmergedPathException) { // 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("Commit failed", e); } }
public static void SetUpstreamSource(NGit.Repository repo, string branch, string remoteBranch) { StoredConfig config = repo.GetConfig(); if (string.IsNullOrEmpty(remoteBranch)) { config.UnsetSection("branch", branch); config.Save(); return; } int i = remoteBranch.IndexOf('/'); string upBranch; if (i == -1) { var tags = repo.GetTags(); if (tags.ContainsKey(remoteBranch)) { upBranch = Constants.R_TAGS + remoteBranch; } else { upBranch = Constants.R_HEADS + remoteBranch; } config.SetString("branch", branch, "remote", "."); } else { upBranch = Constants.R_HEADS + remoteBranch.Substring(i + 1); config.SetString("branch", branch, "remote", remoteBranch.Substring(0, i)); } config.SetString("branch", branch, "merge", upBranch); config.Save(); }
public static IEnumerable <string> ToGitPath(this NGit.Repository repo, IEnumerable <FilePath> filePaths) { foreach (var p in filePaths) { yield return(ToGitPath(repo, p)); } }
static int GetFileLineCount(NGit.Repository repo, TreeWalk tw) { ObjectId id = tw.GetObjectId(0); byte[] data = repo.ObjectDatabase.Open(id).GetBytes(); return(new RawText(data).Size()); }
internal RepositoryStatus(NGit.Repository repository, IEnumerable <string> singleFiles, string rootDir, bool recursive) { Repository = repository; _root_path = rootDir; _recursive = recursive; _file_paths = singleFiles; Update(); }
public RebaseOperation (NGit.Repository repo, string upstreamRef, IProgressMonitor monitor) { this.monitor = monitor; this.repo = repo; this.upstreamRef = upstreamRef; rw = new RevWalk (repo); branch = repo.GetBranch (); starting = true; }
/// <summary> /// Returns a list of files that have changed in a commit /// </summary> public static IEnumerable <Change> GetCommitChanges(NGit.Repository repo, RevCommit commit) { var treeIds = new[] { commit.Tree.Id }.Concat(commit.Parents.Select(c => c.Tree.Id)).ToArray(); var walk = new TreeWalk(repo); walk.Reset(treeIds); walk.Recursive = true; walk.Filter = AndTreeFilter.Create(AndTreeFilter.ANY_DIFF, AndTreeFilter.ALL); return(CalculateCommitDiff(repo, walk, new[] { commit }.Concat(commit.Parents).ToArray())); }
static RawText GetRawText(NGit.Repository repo, string file, RevCommit commit) { TreeWalk tw = TreeWalk.ForPath(repo, file, commit.Tree); if (tw == null) { return(new RawText(new byte[0])); } ObjectId objectID = tw.GetObjectId(0); byte[] data = repo.ObjectDatabase.Open(objectID).GetBytes(); return(new RawText(data)); }
/// <summary> /// Compares two commits and returns a list of files that have changed /// </summary> public static IEnumerable <DiffEntry> CompareCommits(NGit.Repository repo, RevCommit reference, RevCommit compared) { var changes = new List <DiffEntry>(); if (reference == null && compared == null) { return(changes); } ObjectId refTree = (reference != null ? reference.Tree.Id : ObjectId.ZeroId); ObjectId comparedTree = (compared != null ? compared.Tree.Id : ObjectId.ZeroId); return(CompareCommits(repo, refTree, comparedTree)); }
public static IEnumerable <DiffEntry> CompareCommits(NGit.Repository repo, AnyObjectId reference, ObjectId compared) { var diff = new MyersDiff(repo); if (reference != ObjectId.ZeroId) { var firstTree = new CanonicalTreeParser(); firstTree.Reset(repo.NewObjectReader(), new RevWalk(repo).ParseTree(reference)); diff.SetOldTree(firstTree); } var secondTree = new CanonicalTreeParser(); secondTree.Reset(repo.NewObjectReader(), new RevWalk(repo).ParseTree(compared)); diff.SetNewTree(secondTree); return(diff.Call()); }
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; } }
static int SetBlameLines(NGit.Repository repo, RevCommit[] lines, RevCommit commit, RawText curText, RawText ancestorText) { int lineCount = 0; IEnumerable <Hunk> diffHunks = GetDiffHunks(curText, ancestorText); foreach (Hunk e in diffHunks) { int basePosition = e.InsertStart - 1; for (int i = 0; i < e.Inserted; i++) { int lineNum = basePosition + i; if (lines [lineNum] == null) { lines [lineNum] = commit; lineCount++; } } } return(lineCount); }
public static List <string> GetConflictedFiles(NGit.Repository repo) { List <string> list = new List <string> (); TreeWalk treeWalk = new TreeWalk(repo); treeWalk.Reset(); treeWalk.Recursive = true; DirCache dc = repo.ReadDirCache(); treeWalk.AddTree(new DirCacheIterator(dc)); while (treeWalk.Next()) { DirCacheIterator dirCacheIterator = treeWalk.GetTree <DirCacheIterator>(0); var ce = dirCacheIterator.GetDirCacheEntry(); if (ce != null && ce.Stage == 1) { list.Add(ce.PathString); } } return(list); }
public static IEnumerable <DiffEntry> 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 IEnumerable <FileDiff> GetFileDiffs(string newHash, string oldHash) { NGit.Repository repo = this.git.GetRepository(); ObjectId newCommit = repo.Resolve(newHash + "^{tree}"); ObjectId oldCommit = repo.Resolve(oldHash + "^{tree}"); var walk = new TreeWalk(repo) { Recursive = true }; walk.AddTree(oldCommit); walk.AddTree(newCommit); IEnumerable <DiffEntry> entries = DiffEntry.Scan(walk); var diffs = entries.Where(diff => diff.GetNewId().Name != diff.GetOldId().Name); return(from diffEntry in diffs let diffType = ToDiffType(diffEntry.GetChangeType()) let path = diffType == DiffType.Delete ? diffEntry.GetOldPath() : diffEntry.GetNewPath() select new FileDiff(path, diffType)); }
public static FilePath FromGitPath(this NGit.Repository repo, string filePath) { filePath = filePath.Replace('/', Path.DirectorySeparatorChar); return(Path.Combine(repo.WorkTree, filePath)); }
public static void HardReset(NGit.Repository repo, string toRef) { ObjectId newHead = repo.Resolve(toRef); HardReset(repo, newHead); }
public static string ToGitPath(this NGit.Repository repo, FilePath filePath) { return(filePath.FullPath.ToRelative(repo.WorkTree.ToString()).ToString().Replace('\\', '/')); }
public override void CopyConfigurationFrom (Repository other) { base.CopyConfigurationFrom (other); GitRepository r = (GitRepository)other; path = r.path; if (r.repo != null) repo = new FileRepository (path); }
public static RepositoryStatus GetDirectoryStatus(NGit.Repository repo, string dir, bool recursive) { return(new RepositoryStatus(repo, null, repo.ToGitPath(dir), recursive)); }
public static MergeCommandResult MergeTrees(ProgressMonitor monitor, NGit.Repository repo, RevCommit srcBase, RevCommit srcCommit, string sourceDisplayName, bool commitResult) { RevCommit newHead; 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 <Sequence> > lowLevelResults = null; IDictionary <string, ResolveMerger.MergeFailureReason> failingPaths = null; IList <string> modifiedFiles = null; 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(); } }
public static void Checkout(NGit.Repository repo, RevCommit commit, string working_directory) { DirCacheCheckout co = new DirCacheCheckout(repo, null, repo.ReadDirCache(), commit.Tree); co.Checkout(); }
public static RepositoryStatus GetFileStatus(NGit.Repository repo, IEnumerable <FilePath> fileNames) { return(new RepositoryStatus(repo, repo.ToGitPath(fileNames), null, false)); }
static IEnumerable <Change> CalculateCommitDiff(NGit.Repository repo, TreeWalk walk, RevCommit[] commits) { while (walk.Next()) { int m0 = walk.GetRawMode(0); if (walk.TreeCount == 2) { int m1 = walk.GetRawMode(1); var change = new Change { ReferenceCommit = commits[0], ComparedCommit = commits[1], ReferencePermissions = walk.GetFileMode(0).GetBits(), ComparedPermissions = walk.GetFileMode(1).GetBits(), Name = walk.NameString, Path = walk.PathString }; if (m0 != 0 && m1 == 0) { change.ChangeType = ChangeType.Added; change.ComparedObject = walk.GetObjectId(0); } else if (m0 == 0 && m1 != 0) { change.ChangeType = ChangeType.Deleted; change.ReferenceObject = walk.GetObjectId(0); } else if (m0 != m1 && walk.IdEqual(0, 1)) { change.ChangeType = ChangeType.TypeChanged; change.ReferenceObject = walk.GetObjectId(0); change.ComparedObject = walk.GetObjectId(1); } else { change.ChangeType = ChangeType.Modified; change.ReferenceObject = walk.GetObjectId(0); change.ComparedObject = walk.GetObjectId(1); } yield return(change); } else { var raw_modes = new int[walk.TreeCount - 1]; for (int i = 0; i < walk.TreeCount - 1; i++) { raw_modes[i] = walk.GetRawMode(i + 1); } //ComparedCommit = compared, var change = new Change { ReferenceCommit = commits[0], Name = walk.NameString, Path = walk.PathString }; if (m0 != 0 && raw_modes.All(m1 => m1 == 0)) { change.ChangeType = ChangeType.Added; change.ComparedObject = walk.GetObjectId(0); yield return(change); } else if (m0 == 0 && raw_modes.Any(m1 => m1 != 0)) { change.ChangeType = ChangeType.Deleted; yield return(change); // TODO: not sure if this condition suffices in some special cases. } else if (raw_modes.Select((m1, i) => new { Mode = m1, Index = i + 1 }).All(x => !walk.IdEqual(0, x.Index))) { change.ChangeType = ChangeType.Modified; change.ReferenceObject = walk.GetObjectId(0); yield return(change); } else if (raw_modes.Select((m1, i) => new { Mode = m1, Index = i + 1 }).Any(x => m0 != x.Mode && walk.IdEqual(0, x.Index))) { change.ChangeType = ChangeType.TypeChanged; change.ReferenceObject = walk.GetObjectId(0); yield return(change); } } } }
public static StashCollection GetStashes(NGit.Repository repo) { return(new StashCollection(repo)); }
public static RevCommit[] Blame(NGit.Repository repo, RevCommit commit, string file) { string localFile = ToGitPath(repo, file); TreeWalk tw = TreeWalk.ForPath(repo, localFile, commit.Tree); if (tw == null) { return(new RevCommit [0]); } int totalLines = GetFileLineCount(repo, tw); int lineCount = totalLines; RevCommit[] lines = new RevCommit [lineCount]; RevWalk revWalker = new RevWalk(repo); revWalker.MarkStart(commit); List <RevCommit> commitHistory = new List <RevCommit>(); FilePath localCpath = FromGitPath(repo, localFile); foreach (RevCommit ancestorCommit in revWalker) { foreach (Change change in GetCommitChanges(repo, ancestorCommit)) { FilePath cpath = FromGitPath(repo, change.Path); if (change.ChangeType != ChangeType.Deleted && (localCpath == cpath || cpath.IsChildPathOf(localCpath))) { commitHistory.Add(ancestorCommit); break; } } } int historySize = commitHistory.Count; if (historySize > 1) { RevCommit recentCommit = commitHistory[0]; RawText latestRawText = GetRawText(repo, localFile, recentCommit); for (int i = 1; i < historySize; i++) { RevCommit ancestorCommit = commitHistory[i]; RawText ancestorRawText = GetRawText(repo, localFile, ancestorCommit); lineCount -= SetBlameLines(repo, lines, recentCommit, latestRawText, ancestorRawText); recentCommit = ancestorCommit; if (lineCount <= 0) { break; } } if (lineCount > 0) { RevCommit firstCommit = commitHistory[historySize - 1]; for (int i = 0; i < totalLines; i++) { if (lines[i] == null) { lines[i] = firstCommit; } } } } else if (historySize == 1) { RevCommit firstCommit = commitHistory[0]; for (int i = 0; i < totalLines; i++) { lines[i] = firstCommit; } } return(lines); }
public FilteredStatus(NGit.Repository repository) : base(repository) { }
public FilteredStatus(NGit.Repository repository, IEnumerable <string> files) : base(repository) { Files = files; }
public GitRevision (Repository repo, NGit.Repository gitRepository, string rev) : base(repo) { this.rev = rev; GitRepository = gitRepository; }
public GitRepository (FilePath path, string url) { this.path = path; Url = url; repo = new FileRepository (path.Combine (Constants.DOT_GIT)); }
VersionInfo[] GetDirectoryVersionInfo (FilePath localDirectory, IEnumerable<FilePath> localFileNames, bool getRemoteStatus, bool recursive) { List<VersionInfo> versions = new List<VersionInfo> (); HashSet<FilePath> existingFiles = new HashSet<FilePath> (); HashSet<FilePath> nonVersionedMissingFiles = new HashSet<FilePath> (); if (localFileNames != null) { var localFiles = new List<FilePath> (); foreach (var group in GroupByRepository (localFileNames)) { var repository = group.Key; var arev = new GitRevision (this, repository, ""); foreach (var p in group) { if (Directory.Exists (p)) { if (recursive) versions.AddRange (GetDirectoryVersionInfo (p, getRemoteStatus, true)); versions.Add (new VersionInfo (p, "", true, VersionStatus.Versioned, arev, VersionStatus.Versioned, null)); } else { localFiles.Add (p); if (File.Exists (p)) existingFiles.Add (p.CanonicalPath); else nonVersionedMissingFiles.Add (p.CanonicalPath); } } } // No files to check, we are done if (localFiles.Count == 0) return versions.ToArray (); localFileNames = localFiles; } else { List<FilePath> directories = new List<FilePath> (); CollectFiles (existingFiles, directories, localDirectory, recursive); foreach (var group in GroupByRepository (directories)) { var repository = group.Key; var arev = new GitRevision (this, repository, ""); foreach (var p in group) versions.Add (new VersionInfo (p, "", true, VersionStatus.Versioned, arev, VersionStatus.Versioned, null)); } } IEnumerable<FilePath> paths; if (localFileNames == null) { if (recursive) { paths = new [] { localDirectory }; } else { if (Directory.Exists (localDirectory)) paths = Directory.GetFiles (localDirectory).Select (f => (FilePath)f); else paths = new FilePath [0]; } } else { paths = localFileNames; } foreach (var group in GroupByRepository (paths)) { var repository = group.Key; GitRevision rev = null; if (versionInfoCacheRepository == null || versionInfoCacheRepository != repository) { versionInfoCacheRepository = repository; RevCommit headCommit = GetHeadCommit (repository); if (headCommit != null) { rev = new GitRevision (this, repository, headCommit.Id.Name); versionInfoCacheRevision = rev; } } else rev = versionInfoCacheRevision; GetDirectoryVersionInfoCore (repository, rev, group, existingFiles, nonVersionedMissingFiles, versions); // Existing files for which git did not report a status are supposed to be tracked foreach (FilePath file in existingFiles.Where (f => group.Contains (f))) { VersionInfo vi = new VersionInfo (file, "", false, VersionStatus.Versioned, rev, VersionStatus.Versioned, null); versions.Add (vi); } } // Non existing files for which git did not report an status are unversioned foreach (FilePath file in nonVersionedMissingFiles) versions.Add (VersionInfo.CreateUnversioned (file, false)); return versions.ToArray (); }
internal StashCollection(NGit.Repository repo) { this._repo = repo; }
public GitRevision (Repository repo, NGit.Repository gitRepository, string rev, DateTime time, string author, string message) : base(repo, time, author, message) { this.rev = rev; GitRepository = gitRepository; }
public override Repository Publish (string serverPath, FilePath localPath, FilePath[] files, string message, IProgressMonitor monitor) { // Initialize the repository repo = GitUtil.Init (localPath, Url, monitor); path = localPath; // Add the project files ChangeSet cs = CreateChangeSet (localPath); NGit.Api.Git git = new NGit.Api.Git (repo); var cmd = git.Add (); foreach (FilePath fp in files) { cmd.AddFilepattern (ToGitPath (fp)); cs.AddFile (fp); } cmd.Call (); // Create the initial commit cs.GlobalComment = message; Commit (cs, monitor); // Push to remote repo Push (monitor, "origin", "master"); return this; }