public void PatchEntryBasics()
        {
            // Init test repo
            var    path = SandboxStandardTestRepoGitDir();
            string file = "numbers.txt";

            // The repo
            using (var repo = new Repository(path))
            {
                Tree rootCommitTree            = repo.Lookup <Commit>("f8d44d7").Tree;
                Tree commitTreeWithUpdatedFile = repo.Lookup <Commit>("ec9e401").Tree;

                // Create path by diffing
                using (var patch = repo.Diff.Compare <Patch>(rootCommitTree, commitTreeWithUpdatedFile))
                {
                    PatchEntryChanges entryChanges = patch[file];
                    Assert.Equal(2, entryChanges.LinesAdded);
                    Assert.Equal(1, entryChanges.LinesDeleted);
                    Assert.Equal(187, entryChanges.Patch.Length);
                    // Smoke test
                    Assert.Equal(Mode.NonExecutableFile, entryChanges.Mode);
                    Assert.Equal(new ObjectId("4625a3628cb78970c57e23a2fe2574514ba403c7"), entryChanges.Oid);
                    Assert.Equal(ChangeKind.Modified, entryChanges.Status);
                    Assert.Equal(file, entryChanges.OldPath);
                    Assert.Equal(Mode.NonExecutableFile, entryChanges.OldMode);
                    Assert.Equal(new ObjectId("7909961ae96accd75b6813d32e0fc1d6d52ec941"), entryChanges.OldOid);
                }
            }
        }
Example #2
0
 public GitChange(PatchEntryChanges patchEntryChanges)
 {
     Summary = new GitChangeSummary(patchEntryChanges.Status, patchEntryChanges.LinesAdded,
                                    patchEntryChanges.LinesDeleted);
     OldBlob = new GitChangeBlob(patchEntryChanges.OldOid, patchEntryChanges.OldPath, patchEntryChanges.OldMode);
     NewBlob = new GitChangeBlob(patchEntryChanges.Oid, patchEntryChanges.Path, patchEntryChanges.Mode);
 }
Example #3
0
        public void CanCompareTwoVersionsOfAFileWithATrailingNewlineDeletion(int contextLines, int expectedPatchLength)
        {
            using (var repo = new Repository(StandardTestRepoPath))
            {
                Tree rootCommitTree            = repo.Lookup <Commit>("f8d44d7").Tree;
                Tree commitTreeWithUpdatedFile = repo.Lookup <Commit>("ec9e401").Tree;

                var changes = repo.Diff.Compare <TreeChanges>(rootCommitTree, commitTreeWithUpdatedFile);

                Assert.Equal(1, changes.Count());
                Assert.Equal(1, changes.Modified.Count());

                var patch = repo.Diff.Compare <Patch>(rootCommitTree, commitTreeWithUpdatedFile,
                                                      compareOptions: new CompareOptions {
                    ContextLines = contextLines
                });

                Assert.Equal(expectedPatchLength, patch.Content.Length);

                PatchEntryChanges entryChanges = patch["numbers.txt"];

                Assert.Equal(2, entryChanges.LinesAdded);
                Assert.Equal(1, entryChanges.LinesDeleted);
                Assert.Equal(expectedPatchLength, entryChanges.Patch.Length);
                Assert.Equal("numbers.txt", entryChanges.Path);
            }
        }
Example #4
0
 public PatchEntry(int offset, int length, Patch patch, PatchEntryChanges changes, IReadOnlyList <PatchHunk> hunks)
 {
     Offset  = offset;
     Length  = length;
     Patch   = patch;
     Changes = changes;
     Hunks   = hunks;
 }
Example #5
0
        public void Prepend(PatchEntryChanges changes)
        {
            List <LineRange> patch = new List <LineRange>();

            //foreach (var l in changes)
            //{
            //
            //}
        }
Example #6
0
 private string GetFileRowString(PatchEntryChanges pe)
 {
     if (pe.Status == ChangeKind.Renamed || pe.Status == ChangeKind.Copied)
     {
         return($"{pe.OldPath} ⇒ {pe.Path} ({pe.Status})");
     }
     else
     {
         return($"{pe.Path} ({pe.Status})");
     }
 }
Example #7
0
        void ComputeMerge_Deleted(Commit mergeBase, PatchEntryChanges change, Patch headChanges)
        {
            var folder = change.Path.Replace($"/{FileSystemStorage.DataFile}", string.Empty);

            if (headChanges.Any(c => c.Path.Equals(folder, StringComparison.OrdinalIgnoreCase) && (c.Status == ChangeKind.Added || c.Status == ChangeKind.Modified)))
            {
                throw new NotImplementedException("Node deletion while children have been added or modified in head is not supported.");
            }

            var mergeBaseObject = GetContent(mergeBase, change.Path, "branch tip");

            DeletedObjects.Add(new MetadataTreeMergeObjectDelete(change.Path, mergeBaseObject));
        }
Example #8
0
        void ComputeMerge_Added(Commit branchTip, PatchEntryChanges change, Patch headChanges)
        {
            var parentDataPath = change.Path.GetDataParentDataPath();

            if (headChanges.Any(c => c.Path.Equals(parentDataPath, StringComparison.OrdinalIgnoreCase) && c.Status == ChangeKind.Deleted))
            {
                throw new NotImplementedException("Node addition while parent has been deleted in head is not supported.");
            }

            var branchObject = GetContent(branchTip, change.Path, "branch tip");

            AddedObjects.Add(new MetadataTreeMergeObjectAdd(change.Path, branchObject));
        }
Example #9
0
        private void btnRunDebug_Click(object sender, EventArgs e)
        {
            var repo = new LibGit2Sharp.Repository(@"c:\client_server\bmm580\");


            foreach (Commit commit in repo.Commits)
            {
                foreach (var parent in commit.Parents)
                {
                    textBoxDebug.AppendText(commit.Sha + "   " + commit.MessageShort + Environment.NewLine);
                    textBoxDebug.AppendText(commit.Committer.ToString() + Environment.NewLine);
                    //textBoxDebug.AppendText(commit.Author.ToString() + Environment.NewLine);


                    foreach (TreeEntryChanges change in repo.Diff.Compare <TreeChanges>(repo.Head.Tip.Tree,
                                                                                        DiffTargets.Index | DiffTargets.WorkingDirectory))
                    // foreach (TreeEntryChanges change in repo.Diff.Compare<TreeChanges>(parent.Tree,commit.Tree))
                    {
                        textBoxDebug.AppendText(change.Status + "  " + change.Path + Environment.NewLine);



                        List <Commit> CommitList = new List <Commit>();
                        foreach (LogEntry entry in repo.Commits.QueryBy(change.Path).ToList())
                        {
                            CommitList.Add(entry.Commit);
                        }
                        CommitList.Add(null);       // Added to show correct initial add

                        int ChangeDesired      = 0; // Change difference desired
                        var repoDifferences    = repo.Diff.Compare <Patch>((Equals(CommitList[ChangeDesired + 1], null)) ? null : CommitList[ChangeDesired + 1].Tree, (Equals(CommitList[ChangeDesired], null)) ? null : CommitList[ChangeDesired].Tree);
                        PatchEntryChanges file = null;
                        try { file = repoDifferences.First(  ); }
                        catch { } // If the file has been renamed in the past- this search will fail
                        if (!Equals(file, null))
                        {
                            String result = file.Patch;
                            textBoxDebug.AppendText(result + "  " + Environment.NewLine);
                        }
                    }
                }
            }
        }
Example #10
0
        /// <summary>
        /// Use LibGit2Sharp to perform a Git diff procedure on the given file, comparing the current working directory
        /// against the file version at the given commit index.  Returns the total number of lines changed.
        /// </summary>
        public int DiffFile(CustomFile file, int commitIndex)
        {
            //Ensure any previous changes detected by Git are removed before considering other changes
            if (file != null)
            {
                file.ClearPreviousChanges();
            }
            // Return if the given file was null or if user selected "NO SELECTION" index from DependencyWindow drop-down
            if (file == null || commitIndex == -1)
            {
                return(0);
            }

            // Select the Git tree and file path for the given CustomFile
            LibGit2Sharp.Tree chosenTree     = commitList[commitIndex].Tree;
            List <string>     chosenFilePath = new List <string>()
            {
                file.relPath
            };

            // Perform the Git diff and create a string for the resulting patch
            Patch             patch     = repo.Diff.Compare <Patch>(chosenTree, DiffTargets.WorkingDirectory, chosenFilePath, pathOptions, compareOptions);
            PatchEntryChanges changes   = patch[file.relPath];
            string            patchText = changes.Patch; // If no changes b/w commits, then "", or if notIncludeModified, null changes

            // Update the CustomFile with this patchText for future direct access
            file.diffPatchText = patchText;

            // Parse the patch to localize additions and deletions to the appropriate CustomTypes and CustomMethods
            int totalFileChanges = ParseDiffPatch(patchText, file);

            //Debugging output for checking where changes were found in file
            //List<CustomType> typesInFile = file.types;
            //foreach (CustomType t in typesInFile) {
            //    Debug.LogError("Total changes in " + t + ": " + t + ", inMethods: " + t.totalChangesInMethods + ", outMethods: " + t.totalChangesOutsideMethods);
            //    foreach (CustomMethod m in t.methods) {
            //        Debug.LogWarning("   Total changes in " + m + ": " + (m.additions + m.deletions) + "(Adds: " + m.additions + ", Dels: " + m.deletions + ")");
            //    }
            //}

            return(totalFileChanges);
        }
        private void AddModifiedProperties(PatchEntryChanges branchChange, IModelObject mergeBaseObject, IModelObject newObject, IModelObject headObject, PatchEntryChanges headChange)
        {
            if (headChange?.Status == ChangeKind.Deleted)
            {
                throw new NotImplementedException($"Conflict as a modified node {branchChange.Path} in merge branch source has been deleted in head.");
            }
            var changes = ComputeModifiedProperties(branchChange, mergeBaseObject, newObject, headObject);

            foreach (var modifiedProperty in changes)
            {
                if (typeof(IObjectRepositoryIndex).IsAssignableFrom(modifiedProperty.Property.Property.ReflectedType))
                {
                    // Indexes will be recomputed anyways from the changes when committed,
                    // so there is no need to track them in the modified chunks
                    continue;
                }

                ModifiedProperties.Add(modifiedProperty);
            }
        }
        private void ComputeMerge_Deleted(Commit mergeBase, PatchEntryChanges change, Patch headChanges)
        {
            // Only data file changes have to be taken into account
            // Changes made to the blobs will product a 'modified' change as well
            if (Path.GetFileName(change.Path) != FileSystemStorage.DataFile)
            {
                return;
            }

            var folder = change.Path.Replace($"/{FileSystemStorage.DataFile}", string.Empty);

            if (headChanges.Any(c => c.Path.Equals(folder, StringComparison.OrdinalIgnoreCase) && (c.Status == ChangeKind.Added || c.Status == ChangeKind.Modified)))
            {
                throw new NotImplementedException("Node deletion while children have been added or modified in head is not supported.");
            }

            var mergeBaseObject = GetContent(mergeBase, change.Path, "branch tip");

            DeletedObjects.Add(new ObjectRepositoryDelete(change.Path, mergeBaseObject.Id));
        }
        private void ComputeMerge_Added(Commit branchTip, PatchEntryChanges change, Patch headChanges)
        {
            // Only data file changes have to be taken into account
            // Changes made to the blobs will product a 'modified' change as well
            if (Path.GetFileName(change.Path) != FileSystemStorage.DataFile)
            {
                return;
            }

            var parentDataPath = change.Path.GetDataParentDataPath();

            if (headChanges.Any(c => c.Path.Equals(parentDataPath, StringComparison.OrdinalIgnoreCase) && c.Status == ChangeKind.Deleted))
            {
                throw new NotImplementedException("Node addition while parent has been deleted in head is not supported.");
            }

            var branchObject = GetContent(branchTip, change.Path, "branch tip");
            var parentId     = change.Path.GetDataParentId(Repository);

            AddedObjects.Add(new ObjectRepositoryAdd(change.Path, branchObject, parentId));
        }
        public static IEnumerable <Method> GetInvolvedMethodInFile(this Commit commit,
                                                                   PatchEntryChanges changes,
                                                                   Func <Hunk, IEnumerable <Line> > linesStrategy)
        {
            var methods = new List <Method>();

            var fileContent = commit.GetFileContent(changes.Path);

            if (fileContent == null)
            {
                return(methods);
            }

            foreach (var chunk in changes.Hunks)
            {
                methods.AddRange(linesStrategy(chunk)
                                 .Select(line => fileContent.GetMethodFromLineAndFile(changes.Path, line)));
            }

            return(methods.Distinct());
        }
Example #15
0
        void AddModifiedChunks(PatchEntryChanges branchChange, JObject mergeBaseObject, JObject newObject, JObject headObject, PatchEntryChanges headChange)
        {
            if (headChange?.Status == ChangeKind.Deleted)
            {
                throw new NotImplementedException($"Conflict as a modified node {branchChange.Path} in merge branch source has been deleted in head.");
            }
            var type       = Type.GetType(mergeBaseObject.Value <string>("$type"));
            var properties = _modelDataProvider.Get(type).ModifiableProperties;

            var changes = from kvp in (IEnumerable <KeyValuePair <string, JToken> >) newObject
                          let p = properties.FirstOrDefault(pr => pr.Name.Equals(kvp.Key, StringComparison.OrdinalIgnoreCase))
                                  where p != null
                                  let mergeBaseValue = mergeBaseObject[kvp.Key]
                                                       where mergeBaseValue == null || !JToken.DeepEquals(kvp.Value, mergeBaseValue)
                                                       let headValue = TryGetToken(headObject, kvp)
                                                                       select new MetadataTreeMergeChunkChange(branchChange.Path, mergeBaseObject, newObject, headObject, p, mergeBaseValue, kvp.Value, headValue);

            foreach (var modifiedProperty in changes)
            {
                ModifiedChunks.Add(modifiedProperty);
            }
        }
        public void CanCompareTwoVersionsOfAFileWithADiffOfTwoHunks(int contextLines, int interhunkLines)
        {
            var compareOptions = new CompareOptions
            {
                ContextLines   = contextLines,
                InterhunkLines = interhunkLines,
                Similarity     = SimilarityOptions.None,
            };

            var path = SandboxStandardTestRepoGitDir();

            using (var repo = new Repository(path))
            {
                Tree rootCommitTree   = repo.Lookup <Commit>("f8d44d7").Tree;
                Tree mergedCommitTree = repo.Lookup <Commit>("7252fe2").Tree;

                var changes = repo.Diff.Compare <TreeChanges>(rootCommitTree, mergedCommitTree, compareOptions: compareOptions);

                Assert.Equal(3, changes.Count());
                Assert.Equal(1, changes.Modified.Count());
                Assert.Equal(1, changes.Deleted.Count());
                Assert.Equal(1, changes.Added.Count());

                Assert.Equal(Mode.Nonexistent, changes["my-name-does-not-feel-right.txt"].Mode);

                var patch = repo.Diff.Compare <Patch>(rootCommitTree, mergedCommitTree, compareOptions: compareOptions);

                PatchEntryChanges entryChanges = patch["numbers.txt"];

                Assert.Equal(3, entryChanges.LinesAdded);
                Assert.Equal(1, entryChanges.LinesDeleted);
                Assert.Equal(Expected("f8d44d7...7252fe2/numbers.txt-{0}-{1}.diff", contextLines, interhunkLines),
                             entryChanges.Patch);
                Assert.Equal(Expected("f8d44d7...7252fe2/full-{0}-{1}.diff", contextLines, interhunkLines),
                             patch);
                Assert.Equal("numbers.txt", entryChanges.Path);
            }
        }
        private Change BuildChange(PatchEntryChanges change)
        {
            var fileChange = new Change();

            fileChange.Name = change.Path;
            switch (change.Status)
            {
            case ChangeKind.Added:
                fileChange.ChangeType = ChangeType.Added;
                break;

            case ChangeKind.Copied:
                fileChange.ChangeType = ChangeType.Copied;
                break;

            case ChangeKind.Deleted:
                fileChange.ChangeType = ChangeType.Deleted;
                break;

            case ChangeKind.Modified:
                fileChange.ChangeType = ChangeType.Modified;
                break;

            case ChangeKind.Renamed:
                fileChange.ChangeType = ChangeType.Renamed;
                break;

            case ChangeKind.TypeChanged:
                fileChange.ChangeType = ChangeType.TypeChanged;
                break;

            case ChangeKind.Unmodified:
                fileChange.ChangeType = ChangeType.Unmerged;
                break;
            }
            return(fileChange);
        }
        /// <summary>
        /// Analyzes a patch entry change
        /// </summary>
        /// <param name="change">The change.</param>
        /// <returns>A file changes descriptor.</returns>
        private IFileChanges AnalyzeChange(PatchEntryChanges change)
        {
            var fileChange = _fileChangesFactory.Create();

            fileChange.RelativePath = change.Path;
            fileChange.AbsolutePath = Path.GetFullPath(Path.Join(_folderPath, change.Path));

            foreach (Match blockHeader in _gitDiffBlockSeparator.Matches(change.Patch))
            {
                var methodNameGroup = blockHeader.Groups["method"];
                var newRowGroup     = blockHeader.Groups["newRow"];

                var blockChange = _blockChangesFactory.Create();
                if (methodNameGroup.Success && newRowGroup.Success)
                {
                    blockChange.Line      = int.Parse(newRowGroup.Value, NumberStyles.Integer, CultureInfo.InvariantCulture);
                    blockChange.StartText = methodNameGroup.Value;
                }

                fileChange.Blocks.Add(blockChange);
            }

            return(fileChange);
        }
Example #19
0
        private string[] GetLines(Commit commit)
        {
            PatchEntryChanges changes = null;

            if (commit != null)
            {
                var patch = gitManager.Repository.Diff.Compare <Patch>(commit.Tree, DiffTargets.WorkingDirectory | DiffTargets.Index, new [] { localPath }, explicitPathsOptions, compareOptions);
                changes = patch[localPath];
            }
            else if (gitManager.Repository.Head != null && gitManager.Repository.Head.Tip != null)
            {
                var patch = gitManager.Repository.Diff.Compare <Patch>(gitManager.Repository.Head.Tip.Tree, DiffTargets.WorkingDirectory | DiffTargets.Index, new[] { localPath }, explicitPathsOptions, compareOptions);
                changes = patch[localPath];
            }


            if (changes != null)
            {
                isBinary = changes.IsBinaryComparison;
                return(changes.Patch.Split('\n'));
            }

            return(new string[0]);
        }
Example #20
0
 private static bool ShouldSkip(PatchEntryChanges change)
 {
     // Игнорируем бинарники и возможно некоторые типы файлов
     return(change.IsBinaryComparison || System.IO.Path.GetExtension(change.Path).ToLower().Contains(FILTERED_EXT));
 }
Example #21
0
        internal static ObjectRepositoryDelete ComputeChanges_Deleted(IObjectRepositorySerializer serializer, IRepository repository, PatchEntryChanges change, Func <string, string> relativeFileDataResolver, Func <string, IList <TreeEntryChanges> > deletionConflictProvider = null)
        {
            // Only data file changes have to be taken into account
            // Changes made to the blobs will product a 'modified' change as well
            if (System.IO.Path.GetFileName(change.Path) != FileSystemStorage.DataFile)
            {
                return(null);
            }

            var conflicts = deletionConflictProvider?.Invoke(change.Path);

            if (conflicts?.Any() ?? false)
            {
                throw new NotImplementedException("Node deletion while children have been added or modified in head is not supported.");
            }

            var mergeBaseObject = serializer.Deserialize(repository.Lookup <Blob>(change.OldOid).GetContentStream(), relativeFileDataResolver);

            return(new ObjectRepositoryDelete(change.Path, mergeBaseObject.Id));
        }
Example #22
0
        /// <summary>
        /// ユニファイド形式のテキストを解析する
        /// </summary>
        void AnalysisUnifiedText(PatchEntryChanges diff, List <ChangedLine> changedLine)
        {
            int startLine     = 0;
            int numberOfLines = 0;
            int lineCount     = 0;

            // 内容の異なる行の開始行
            int startDifferentLine = 0;
            // 内容の異なる行数
            int differentLineCount = 0;

            // ユニファイド形式の差分情報を一行ずつ読み込んで処理する
            using (var rs = new StringReader(diff.Patch))
            {
                // 読み込む文字列がなくなったら -1 が返る
                while (rs.Peek() >= 0)
                {
                    // 一行読み込む
                    string strline = rs.ReadLine();

                    // 先頭が @@ で始まっている場合は変更行に対する情報
                    if (strline.StartsWith("@@") == true)
                    {
                        startLine          = 0;
                        numberOfLines      = 0;
                        lineCount          = 0;
                        startDifferentLine = 0;
                        differentLineCount = 0;

                        // 正規表現で変更範囲を抽出する
                        // ※以下の記事がわかりやすかった
                        // http://www.atmarkit.co.jp/fdotnet/dotnettips/579regexmatch/regexmatch.html
                        Match match = Regex.Match(strline, @".*@@.+,.+ \+(?<StartLine>.*?),(?<NumberOfLines>.*?) @@");

                        if (match.Success == true)
                        {
                            startLine     = int.Parse(match.Groups["StartLine"].Value);
                            numberOfLines = int.Parse(match.Groups["NumberOfLines"].Value);
                            logger.Trace($"<UnifiedText>ファイル名:{diff.Path} 開始行:{startLine} 行数:{numberOfLines}");
                        }
                    }
                    else
                    {
                        // 差分情報を取得できている場合にのみ処理
                        if (startLine > 0)
                        {
                            // 先頭が スペース で始まっている場合は変更なしの内容
                            // 先頭が + で始まっている場合は変更後のファイルの内容
                            // この2つが変更後のファイルに含まれる行なので、この2つだけを行数としてカウントする
                            if (strline.StartsWith(" ") == true)
                            {
                                lineCount++;
                            }

                            if (strline.StartsWith("+") == true)
                            {
                                if (startDifferentLine == 0)
                                {
                                    startDifferentLine = startLine + lineCount;
                                }
                                lineCount++;
                                differentLineCount++;
                            }
                            else
                            {
                                // 先頭が + でない場合は差分情報を登録する
                                if (startDifferentLine > 0)
                                {
                                    AddChangeLine(changedLine, diff.Path, startDifferentLine, differentLineCount);
                                    startDifferentLine = 0;
                                    differentLineCount = 0;
                                }
                            }
                        }
                    }
                }

                // 未登録の差分情報があるかもしれないので、ここで再度登録
                if (startDifferentLine > 0)
                {
                    AddChangeLine(changedLine, diff.Path, startDifferentLine, differentLineCount);
                }
            }
        }
Example #23
0
 public ModifiedInfo(PatchEntryChanges changes)
 {
     Patch  = changes.Patch;
     Binary = changes.IsBinaryComparison;
     Hunks  = Diff.ParsePatch(Patch);
 }
Example #24
0
 private bool FileShouldBeIgnored(PatchEntryChanges file)
 {
     return(_context.IgnorePatterns.Any(pattern => file.Path.Contains(pattern)));
 }
Example #25
0
        void ComputeMerge_Modified(Commit mergeBase, Commit branchTip, Commit headTip, Patch headChanges, PatchEntryChanges change)
        {
            var mergeBaseObject = GetContent(mergeBase, change.Path, "merge base");
            var branchObject    = GetContent(branchTip, change.Path, "branch tip");
            var headObject      = GetContent(headTip, change.Path, "head tip");

            AddModifiedChunks(change, mergeBaseObject, branchObject, headObject, headChanges[change.Path]);
        }
Example #26
0
        internal static ObjectRepositoryAdd ComputeChanges_Added(IObjectRepository objectRepository, IObjectRepositorySerializer serializer, IRepository repository, PatchEntryChanges change, Func <string, string> relativeFileDataResolver)
        {
            // Only data file changes have to be taken into account
            // Changes made to the blobs will product a 'modified' change as well
            if (System.IO.Path.GetFileName(change.Path) != FileSystemStorage.DataFile)
            {
                return(null);
            }

            if (objectRepository.TryGetFromGitPath(change.Path) != null)
            {
                throw new NotImplementedException("Node already present in current state.");
            }
            var parentDataPath = change.Path.GetDataParentDataPath();

            if (objectRepository.TryGetFromGitPath(parentDataPath) == null)
            {
                throw new NotImplementedException("Node addition while parent has been deleted in head is not supported.");
            }

            var @new     = serializer.Deserialize(repository.Lookup <Blob>(change.Oid).GetContentStream(), relativeFileDataResolver);
            var parentId = change.Path.GetDataParentId(objectRepository);

            return(new ObjectRepositoryAdd(change.Path, @new, parentId));
        }
        internal static IEnumerable <ObjectRepositoryPropertyChange> ComputeModifiedProperties(PatchEntryChanges changes, IModelObject ancestor, IModelObject theirs, IModelObject ours)
        {
            return(from property in ours.DataAccessor.ModifiableProperties
                   let ancestorChunk = GetChunk(ancestor, property)
                                       let theirChunk = GetChunk(theirs, property)
                                                        where !ancestorChunk.HasSameValue(theirChunk)
                                                        let ourChunk = GetChunk(ours, property)
                                                                       select new ObjectRepositoryPropertyChange(changes.Path, property, ancestorChunk, theirChunk, ourChunk));

            ObjectRepositoryPropertyValue GetChunk(IModelObject @object, ModifiablePropertyInfo property)
            {
                return(new ObjectRepositoryPropertyValue(@object, property, property.Accessor(@object)));
            }
        }
        private void ComputeMerge_Modified(Commit mergeBase, Commit branchTip, Commit headTip, Patch headChanges, PatchEntryChanges change)
        {
            // Get data file path, in the case where a blob has changed
            var path = change.Path.GetSiblingFile(FileSystemStorage.DataFile);

            var mergeBaseObject = GetContent(mergeBase, path, "merge base");
            var branchObject    = GetContent(branchTip, path, "branch tip");
            var headObject      = GetContent(headTip, path, "head tip");

            AddModifiedProperties(change, mergeBaseObject, branchObject, headObject, headChanges[change.Path]);
        }
Example #29
0
 public PatchDiff(List <DiffAnalyzer.Hunk> hunks, PatchEntryChanges patchEntryChanges, CancellableChanges cancellableChanges)
 => (Hunks, PatchEntryChanges, CancellableChanges) = (hunks, patchEntryChanges, cancellableChanges);
Example #30
0
        internal static IEnumerable <ObjectRepositoryPropertyChange> ComputeChanges_Modified(IObjectRepository objectRepository, IObjectRepositorySerializer serializer, PatchEntryChanges change, Func <string, Blob> relativeFileDataResolverStart, Func <string, Blob> relativeFileDataResolverEnd)
        {
            // Get data file path, in the case where a blob has changed
            var dataPath = change.Path.GetSiblingFile(FileSystemStorage.DataFile);

            var currentObject = objectRepository.TryGetFromGitPath(dataPath) ??
                                throw new NotImplementedException($"Conflict as a modified node {change.Path} has been deleted in current rebase state.");

            var changeStart = serializer.Deserialize(
                relativeFileDataResolverStart(FileSystemStorage.DataFile)?.GetContentStream() ?? throw new GitObjectDbException("Change start content could not be found."),
                relativePath => relativeFileDataResolverStart(relativePath)?.GetContentText() ?? string.Empty);

            var changeEnd = serializer.Deserialize(
                relativeFileDataResolverEnd(FileSystemStorage.DataFile)?.GetContentStream() ?? throw new GitObjectDbException("Change end content could not be found."),
                relativePath => relativeFileDataResolverEnd(relativePath)?.GetContentText() ?? string.Empty);

            var changes = ObjectRepositoryMerge.ComputeModifiedProperties(change, changeStart, changeEnd, currentObject);

            // Indexes will be recomputed anyways from the changes when committed,
            // so there is no need to track them in the modified chunks
            var changesWithoutIndexes = changes.Where(
                modifiedProperty => !typeof(IObjectRepositoryIndex).IsAssignableFrom(modifiedProperty.Property.Property.ReflectedType));

            return(changesWithoutIndexes);
        }