public static ObjectHash WriteFixedTree(string vcsPath, Tree tree) { var resultingTreeLines = new List <Tree.TreeLine>(); bool fixRequired = false; foreach (var treeLine in tree.Lines) { if (!treeLine.IsDirectory()) { resultingTreeLines.Add(treeLine); continue; } var childTree = GitObjectFactory.ReadTree(vcsPath, treeLine.Hash); var fixedTreeHash = WriteFixedTree(vcsPath, childTree); resultingTreeLines.Add(new Tree.TreeLine(treeLine.TextBytes, fixedTreeHash)); if (fixedTreeHash != childTree.Hash) { fixRequired = true; } } if (fixRequired || Tree.HasDuplicateLines(resultingTreeLines)) { tree = Tree.GetFixedTree(resultingTreeLines); HashContent.WriteObject(vcsPath, tree); } return(tree.Hash); }
private static bool HasDefectiveTree(string vcsPath, Commit commit) { if (SeenTrees.TryGetValue(commit.TreeHash, out bool isDefective)) { return(isDefective); } var tree = GitObjectFactory.ReadTree(vcsPath, commit.TreeHash); return(IsDefectiveTree(vcsPath, tree)); }
static Dictionary <ObjectHash, ObjectHash> FixDefectiveCommits(string vcsPath, List <ObjectHash> defectiveCommits) { var rewrittenCommitHashes = new Dictionary <ObjectHash, ObjectHash>(); foreach (var commit in CommitWalker.CommitsInOrder(vcsPath)) { if (rewrittenCommitHashes.ContainsKey(commit.Hash)) { continue; } // Rewrite this commit byte[] newCommitBytes; if (defectiveCommits.Contains(commit.Hash)) { var fixedTreeHash = WriteFixedTree(vcsPath, GitObjectFactory.ReadTree(vcsPath, commit.TreeHash)); newCommitBytes = Commit.GetSerializedCommitWithChangedTreeAndParents(commit, fixedTreeHash, CorrectParents(commit.Parents, rewrittenCommitHashes).ToList()); } else { newCommitBytes = Commit.GetSerializedCommitWithChangedTreeAndParents(commit, commit.TreeHash, CorrectParents(commit.Parents, rewrittenCommitHashes).ToList()); } var fileObjectBytes = GitObjectFactory.GetBytesWithHeader(GitObjectType.Commit, newCommitBytes); var newCommitHash = new ObjectHash(Hash.Create(fileObjectBytes)); if (newCommitHash != commit.Hash && !rewrittenCommitHashes.ContainsKey(commit.Hash)) { HashContent.WriteFile(vcsPath, fileObjectBytes, newCommitHash.ToString()); rewrittenCommitHashes.Add(commit.Hash, newCommitHash); } } return(rewrittenCommitHashes); }