/// <summary> /// Formats the results of a merge of <see cref="RawText"/> objects in a Git /// conformant way. This method also assumes that the <see cref="RawText"/> objects /// being merged are line oriented files which use LF as delimiter. This /// method will also use LF to separate chunks and conflict metadata, /// therefore it fits only to texts that are LF-separated lines. /// </summary> /// <param name="out">the outputstream where to write the textual presentation</param> /// <param name="res">the merge result which should be presented</param> /// <param name="seqName"> /// When a conflict is reported each conflicting range will get a /// name. This name is following the "<<<<<<< " or ">>>>>>> " /// conflict markers. The names for the sequences are given in /// this list /// </param> /// <param name="charsetName"> /// the name of the characterSet used when writing conflict /// metadata /// </param> public void formatMerge(BinaryWriter @out, MergeResult res, List <String> seqName, string charsetName) { String lastConflictingName = null; // is set to non-null whenever we are // in a conflict bool threeWayMerge = (res.getSequences().Count == 3); foreach (MergeChunk chunk in res) { RawText seq = (RawText)res.getSequences()[ chunk.getSequenceIndex()]; if (lastConflictingName != null && chunk.getConflictState() != MergeChunk.ConflictState.NEXT_CONFLICTING_RANGE) { // found the end of an conflict @out.Write((">>>>>>> " + lastConflictingName + "\n").getBytes(charsetName)); lastConflictingName = null; } if (chunk.getConflictState() == MergeChunk.ConflictState.FIRST_CONFLICTING_RANGE) { // found the start of an conflict @out.Write(("<<<<<<< " + seqName[chunk.getSequenceIndex()] + "\n").getBytes(charsetName)); lastConflictingName = seqName[chunk.getSequenceIndex()]; } else if (chunk.getConflictState() == MergeChunk.ConflictState.NEXT_CONFLICTING_RANGE) { // found another conflicting chunk /* * In case of a non-three-way merge I'll add the name of the * conflicting chunk behind the equal signs. I also append the * name of the last conflicting chunk after the ending * greater-than signs. If somebody knows a better notation to * present non-three-way merges - feel free to correct here. */ lastConflictingName = seqName[chunk.getSequenceIndex()]; @out.Write((threeWayMerge ? "=======\n" : "======= " + lastConflictingName + "\n").getBytes(charsetName)); } // the lines with conflict-metadata are written. Now write the chunk for (int i = chunk.getBegin(); i < chunk.getEnd(); i++) { if (i > 0) { @out.Write('\n'); } seq.writeLine(@out.BaseStream, i); } } // one possible leftover: if the merge result ended with a conflict we // have to close the last conflict here if (lastConflictingName != null) { @out.Write('\n'); @out.Write((">>>>>>> " + lastConflictingName + "\n").getBytes(charsetName)); } }
public void testWriteLine3() { var a = new RawText(Constants.encodeASCII("a\n\nb\n")); var o = new MemoryStream(); a.writeLine(o, 1); byte[] r = o.ToArray(); Assert.AreEqual(string.Empty, RawParseUtils.decode(r)); }
public void testWriteLine2() { var a = new RawText(Constants.encodeASCII("foo-a\nfoo-b")); var o = new MemoryStream(); a.writeLine(o, 1); byte[] r = o.ToArray(); Assert.AreEqual("foo-b", RawParseUtils.decode(r)); }