Remove System.out.println from RevWalkFilterTest
[egit/qmx.git] / org.spearce.jgit / src / org / spearce / jgit / patch / CombinedFileHeader.java
blobcc9170ea1f2ef7c264d1e6d3a03ab45db2d1d7b5
1 /*
2 * Copyright (C) 2008, Google Inc.
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * - Neither the name of the Git Development Community nor the
19 * names of its contributors may be used to endorse or promote
20 * products derived from this software without specific prior
21 * written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 package org.spearce.jgit.patch;
40 import static org.spearce.jgit.lib.Constants.encodeASCII;
41 import static org.spearce.jgit.util.RawParseUtils.match;
42 import static org.spearce.jgit.util.RawParseUtils.nextLF;
44 import java.nio.charset.Charset;
45 import java.util.ArrayList;
46 import java.util.Arrays;
47 import java.util.List;
49 import org.spearce.jgit.lib.AbbreviatedObjectId;
50 import org.spearce.jgit.lib.FileMode;
52 /**
53 * A file in the Git "diff --cc" or "diff --combined" format.
54 * <p>
55 * A combined diff shows an n-way comparison between two or more ancestors and
56 * the final revision. Its primary function is to perform code reviews on a
57 * merge which introduces changes not in any ancestor.
59 public class CombinedFileHeader extends FileHeader {
60 private static final byte[] MODE = encodeASCII("mode ");
62 private AbbreviatedObjectId[] oldIds;
64 private FileMode[] oldModes;
66 CombinedFileHeader(final byte[] b, final int offset) {
67 super(b, offset);
70 @Override
71 @SuppressWarnings("unchecked")
72 public List<? extends CombinedHunkHeader> getHunks() {
73 return (List<CombinedHunkHeader>) super.getHunks();
76 /** @return number of ancestor revisions mentioned in this diff. */
77 @Override
78 public int getParentCount() {
79 return oldIds.length;
82 /** @return get the file mode of the first parent. */
83 @Override
84 public FileMode getOldMode() {
85 return getOldMode(0);
88 /**
89 * Get the file mode of the nth ancestor
91 * @param nthParent
92 * the ancestor to get the mode of
93 * @return the mode of the requested ancestor.
95 public FileMode getOldMode(final int nthParent) {
96 return oldModes[nthParent];
99 /** @return get the object id of the first parent. */
100 @Override
101 public AbbreviatedObjectId getOldId() {
102 return getOldId(0);
106 * Get the ObjectId of the nth ancestor
108 * @param nthParent
109 * the ancestor to get the object id of
110 * @return the id of the requested ancestor.
112 public AbbreviatedObjectId getOldId(final int nthParent) {
113 return oldIds[nthParent];
116 @Override
117 public String getScriptText(final Charset ocs, final Charset ncs) {
118 final Charset[] cs = new Charset[getParentCount() + 1];
119 Arrays.fill(cs, ocs);
120 cs[getParentCount()] = ncs;
121 return getScriptText(cs);
125 * Convert the patch script for this file into a string.
127 * @param charsetGuess
128 * optional array to suggest the character set to use when
129 * decoding each file's line. If supplied the array must have a
130 * length of <code>{@link #getParentCount()} + 1</code>
131 * representing the old revision character sets and the new
132 * revision character set.
133 * @return the patch script, as a Unicode string.
135 @Override
136 public String getScriptText(final Charset[] charsetGuess) {
137 return super.getScriptText(charsetGuess);
140 @Override
141 int parseGitHeaders(int ptr, final int end) {
142 while (ptr < end) {
143 final int eol = nextLF(buf, ptr);
144 if (isHunkHdr(buf, ptr, end) >= 1) {
145 // First hunk header; break out and parse them later.
146 break;
148 } else if (match(buf, ptr, OLD_NAME) >= 0) {
149 parseOldName(ptr, eol);
151 } else if (match(buf, ptr, NEW_NAME) >= 0) {
152 parseNewName(ptr, eol);
154 } else if (match(buf, ptr, INDEX) >= 0) {
155 parseIndexLine(ptr + INDEX.length, eol);
157 } else if (match(buf, ptr, MODE) >= 0) {
158 parseModeLine(ptr + MODE.length, eol);
160 } else if (match(buf, ptr, NEW_FILE_MODE) >= 0) {
161 parseNewFileMode(ptr, eol);
163 } else if (match(buf, ptr, DELETED_FILE_MODE) >= 0) {
164 parseDeletedFileMode(ptr + DELETED_FILE_MODE.length, eol);
166 } else {
167 // Probably an empty patch (stat dirty).
168 break;
171 ptr = eol;
173 return ptr;
176 @Override
177 protected void parseIndexLine(int ptr, final int eol) {
178 // "index $asha1,$bsha1..$csha1"
180 final List<AbbreviatedObjectId> ids = new ArrayList<AbbreviatedObjectId>();
181 while (ptr < eol) {
182 final int comma = nextLF(buf, ptr, ',');
183 if (eol <= comma)
184 break;
185 ids.add(AbbreviatedObjectId.fromString(buf, ptr, comma - 1));
186 ptr = comma;
189 oldIds = new AbbreviatedObjectId[ids.size() + 1];
190 ids.toArray(oldIds);
191 final int dot2 = nextLF(buf, ptr, '.');
192 oldIds[ids.size()] = AbbreviatedObjectId.fromString(buf, ptr, dot2 - 1);
193 newId = AbbreviatedObjectId.fromString(buf, dot2 + 1, eol - 1);
194 oldModes = new FileMode[oldIds.length];
197 @Override
198 protected void parseNewFileMode(final int ptr, final int eol) {
199 for (int i = 0; i < oldModes.length; i++)
200 oldModes[i] = FileMode.MISSING;
201 super.parseNewFileMode(ptr, eol);
204 @Override
205 HunkHeader newHunkHeader(final int offset) {
206 return new CombinedHunkHeader(this, offset);
209 private void parseModeLine(int ptr, final int eol) {
210 // "mode $amode,$bmode..$cmode"
212 int n = 0;
213 while (ptr < eol) {
214 final int comma = nextLF(buf, ptr, ',');
215 if (eol <= comma)
216 break;
217 oldModes[n++] = parseFileMode(ptr, comma);
218 ptr = comma;
220 final int dot2 = nextLF(buf, ptr, '.');
221 oldModes[n] = parseFileMode(ptr, dot2);
222 newMode = parseFileMode(dot2 + 1, eol);
225 private void parseDeletedFileMode(int ptr, final int eol) {
226 // "deleted file mode $amode,$bmode"
228 changeType = ChangeType.DELETE;
229 int n = 0;
230 while (ptr < eol) {
231 final int comma = nextLF(buf, ptr, ',');
232 if (eol <= comma)
233 break;
234 oldModes[n++] = parseFileMode(ptr, comma);
235 ptr = comma;
237 oldModes[n] = parseFileMode(ptr, eol);
238 newMode = FileMode.MISSING;