/// <summary> /// Method creates patch from two loaded folders /// </summary> /// <param name="firstFolderFiles"></param> /// <param name="secondFolderFiles"></param> /// <param name="patch"></param> private void CreatePatchFromFolders(List <FileProperties> firstFolderFiles, List <FileProperties> secondFolderFiles, List <string> patch) { foreach (FileProperties fp in firstFolderFiles) { if (fp.AbsolutePath != string.Empty) { FileProperties obj = secondFolderFiles.Find(x => x.AbsolutePath.Equals(fp.AbsolutePath)); if (obj != null && fp.fileData.Count != 0 && obj.fileData.Count != 0) { patch.AddRange(CreatePatch(fp.fileData, obj.fileData, DiffText(fp.fileData, obj.fileData, false), fp, obj)); } } else if (fp.children != null) { FileProperties obj = secondFolderFiles.Find(x => x.Name.Equals(fp.Name)); if (obj != null) { CreatePatchFromFolders(fp.children, obj.children, patch); } } } }
/// <summary> /// Method creates patch from files difference objects /// </summary> /// <param name="differences"></param> /// <returns></returns> private List <string> CreatePatch(List <string> firstFile, List <string> secondFile, List <Difference> differences, FileProperties firstFileInfo, FileProperties secondFileInfo) { List <string> patch = new List <string>(); List <string> diffRange = new List <string>(); string lastAction = string.Empty; int linesLevel = 0; int firstRange = 0; int secondRange = 0; int firstIndex = 0; int secondIndex = 0; int deletedIndex, insertedIndex; // if there are diffs beetwen files we create patch if (differences.Count != 0) { patch.Add("--- " + firstFileInfo.FilePath + " " + DateTime.Now.ToString()); patch.Add("+++ " + secondFileInfo.FilePath + " " + DateTime.Now.ToString()); // Iterate every diff object and update first file for (int x = 0; x < differences.Count; ++x) { // diffrence between deleted and inserted lines // result give us 3 possible operations int res = differences[x].deletedAmount - differences[x].insertedAmount; // set indexes to patch file deletedIndex = firstIndex + 1; insertedIndex = secondIndex + 1; // 1. if deleted and inserted are equal if (res.Equals(0)) { // complete start lines for (int i = firstIndex; i < differences[x].deletedIndex; ++i) { diffRange.Add(firstFile[i]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } // Insert changed lines with modyfied style for (int i = 0; i < differences[x].deletedAmount; ++i) { diffRange.Add("-" + firstFile[firstIndex]); diffRange.Add("+" + secondFile[secondIndex]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } // complete lines to next diff // there is more than 1 diff if (x + 1 < differences.Count) { int size; if (lastAction.Equals("d")) { size = Math.Min(differences[x + 1].deletedIndex, differences[x + 1].insertedIndex - linesLevel); for (int i = firstIndex; i < size; ++i) { diffRange.Add(firstFile[i]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } } else { size = Math.Min(differences[x + 1].deletedIndex - linesLevel, differences[x + 1].insertedIndex); for (int i = secondIndex; i < size; ++i) { diffRange.Add(secondFile[i]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } } } // we are at last diff else { for (int i = firstIndex; i < firstFile.Count; ++i) { diffRange.Add(firstFile[i]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } } } // 2. if deleted < inserted if (res < 0) { if (lastAction.Equals("d")) { linesLevel *= -1; } // complete start lines to first file for (int i = firstIndex; i < differences[x].insertedIndex + linesLevel; ++i) { diffRange.Add(firstFile[i]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } // if there is some changed lines if (differences[x].deletedAmount > 0) { // we add changed lines to first file for (int i = 0; i < differences[x].deletedAmount; ++i) { diffRange.Add("-" + firstFile[firstIndex]); diffRange.Add("+" + secondFile[secondIndex]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } } // add inserted lines for (int i = 0; i < differences[x].insertedAmount - differences[x].deletedAmount; ++i) { diffRange.Add("+" + secondFile[secondIndex]); ++secondIndex; ++secondRange; } /// set actual line lvl linesLevel += res; lastAction = "i"; // complete lines to next diff // there is more than 1 diff if (x + 1 < differences.Count) { for (int i = secondIndex; i < Math.Min(differences[x + 1].deletedIndex - linesLevel, differences[x + 1].insertedIndex); ++i) { diffRange.Add(secondFile[i]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } } // we are at last diff else { for (int i = firstIndex; i < firstFile.Count; ++i) { diffRange.Add(firstFile[i]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } } } // 3. if deleted > inserted if (res > 0) { if (lastAction.Equals("i")) { linesLevel *= -1; } // complete start lines to first file for (int i = firstIndex; i < differences[x].deletedIndex; ++i) { diffRange.Add(firstFile[i]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } // if there is some changed lines if (differences[x].insertedAmount > 0) { // we add changed lines to first file for (int i = 0; i < differences[x].insertedAmount; ++i) { diffRange.Add("-" + firstFile[firstIndex]); diffRange.Add("+" + secondFile[secondIndex]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } } // add deleted lines for (int i = 0; i < differences[x].deletedAmount - differences[x].insertedAmount; ++i) { diffRange.Add("-" + firstFile[firstIndex]); ++firstIndex; ++firstRange; } linesLevel -= res; lastAction = "d"; // complete lines to next diff // there is more than 1 diff if (x + 1 < differences.Count) { for (int i = firstIndex; i < Math.Min(differences[x + 1].deletedIndex, differences[x + 1].insertedIndex - linesLevel); ++i) { diffRange.Add(firstFile[firstIndex]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } } // we are at last diff else { for (int i = firstIndex; i < firstFile.Count; ++i) { diffRange.Add(firstFile[i]); ++firstIndex; ++firstRange; ++secondIndex; ++secondRange; } } } // add range line and collection with lines patch.Add("@@ -" + deletedIndex.ToString() + "," + firstRange.ToString() + " +" + insertedIndex.ToString() + "," + secondRange.ToString() + " @@"); patch.AddRange(diffRange); // Clear diffrange collection diffRange.Clear(); // init variables firstRange = secondRange = 0; } } return(patch); }
/// <summary> /// Method generates patch /// </summary> public List <string> GeneratePatch(FileProperties firstFileInfo, FileProperties secondFileInfo) { /// Creates file with changes (final version of patch) return(CreatePatch(_firstFile, _secondFile, DiffText(_firstFile, _secondFile, false), firstFileInfo, secondFileInfo)); }