Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java246
1 files changed, 246 insertions, 0 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java
new file mode 100644
index 0000000000..e95c026ddc
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/CombinedFileHeader.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2008, Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ * names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.patch;
+
+import static org.eclipse.jgit.lib.Constants.encodeASCII;
+import static org.eclipse.jgit.util.RawParseUtils.match;
+import static org.eclipse.jgit.util.RawParseUtils.nextLF;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jgit.lib.AbbreviatedObjectId;
+import org.eclipse.jgit.lib.FileMode;
+
+/**
+ * A file in the Git "diff --cc" or "diff --combined" format.
+ * <p>
+ * A combined diff shows an n-way comparison between two or more ancestors and
+ * the final revision. Its primary function is to perform code reviews on a
+ * merge which introduces changes not in any ancestor.
+ */
+public class CombinedFileHeader extends FileHeader {
+ private static final byte[] MODE = encodeASCII("mode ");
+
+ private AbbreviatedObjectId[] oldIds;
+
+ private FileMode[] oldModes;
+
+ CombinedFileHeader(final byte[] b, final int offset) {
+ super(b, offset);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public List<? extends CombinedHunkHeader> getHunks() {
+ return (List<CombinedHunkHeader>) super.getHunks();
+ }
+
+ /** @return number of ancestor revisions mentioned in this diff. */
+ @Override
+ public int getParentCount() {
+ return oldIds.length;
+ }
+
+ /** @return get the file mode of the first parent. */
+ @Override
+ public FileMode getOldMode() {
+ return getOldMode(0);
+ }
+
+ /**
+ * Get the file mode of the nth ancestor
+ *
+ * @param nthParent
+ * the ancestor to get the mode of
+ * @return the mode of the requested ancestor.
+ */
+ public FileMode getOldMode(final int nthParent) {
+ return oldModes[nthParent];
+ }
+
+ /** @return get the object id of the first parent. */
+ @Override
+ public AbbreviatedObjectId getOldId() {
+ return getOldId(0);
+ }
+
+ /**
+ * Get the ObjectId of the nth ancestor
+ *
+ * @param nthParent
+ * the ancestor to get the object id of
+ * @return the id of the requested ancestor.
+ */
+ public AbbreviatedObjectId getOldId(final int nthParent) {
+ return oldIds[nthParent];
+ }
+
+ @Override
+ public String getScriptText(final Charset ocs, final Charset ncs) {
+ final Charset[] cs = new Charset[getParentCount() + 1];
+ Arrays.fill(cs, ocs);
+ cs[getParentCount()] = ncs;
+ return getScriptText(cs);
+ }
+
+ /**
+ * Convert the patch script for this file into a string.
+ *
+ * @param charsetGuess
+ * optional array to suggest the character set to use when
+ * decoding each file's line. If supplied the array must have a
+ * length of <code>{@link #getParentCount()} + 1</code>
+ * representing the old revision character sets and the new
+ * revision character set.
+ * @return the patch script, as a Unicode string.
+ */
+ @Override
+ public String getScriptText(final Charset[] charsetGuess) {
+ return super.getScriptText(charsetGuess);
+ }
+
+ @Override
+ int parseGitHeaders(int ptr, final int end) {
+ while (ptr < end) {
+ final int eol = nextLF(buf, ptr);
+ if (isHunkHdr(buf, ptr, end) >= 1) {
+ // First hunk header; break out and parse them later.
+ break;
+
+ } else if (match(buf, ptr, OLD_NAME) >= 0) {
+ parseOldName(ptr, eol);
+
+ } else if (match(buf, ptr, NEW_NAME) >= 0) {
+ parseNewName(ptr, eol);
+
+ } else if (match(buf, ptr, INDEX) >= 0) {
+ parseIndexLine(ptr + INDEX.length, eol);
+
+ } else if (match(buf, ptr, MODE) >= 0) {
+ parseModeLine(ptr + MODE.length, eol);
+
+ } else if (match(buf, ptr, NEW_FILE_MODE) >= 0) {
+ parseNewFileMode(ptr, eol);
+
+ } else if (match(buf, ptr, DELETED_FILE_MODE) >= 0) {
+ parseDeletedFileMode(ptr + DELETED_FILE_MODE.length, eol);
+
+ } else {
+ // Probably an empty patch (stat dirty).
+ break;
+ }
+
+ ptr = eol;
+ }
+ return ptr;
+ }
+
+ @Override
+ protected void parseIndexLine(int ptr, final int eol) {
+ // "index $asha1,$bsha1..$csha1"
+ //
+ final List<AbbreviatedObjectId> ids = new ArrayList<AbbreviatedObjectId>();
+ while (ptr < eol) {
+ final int comma = nextLF(buf, ptr, ',');
+ if (eol <= comma)
+ break;
+ ids.add(AbbreviatedObjectId.fromString(buf, ptr, comma - 1));
+ ptr = comma;
+ }
+
+ oldIds = new AbbreviatedObjectId[ids.size() + 1];
+ ids.toArray(oldIds);
+ final int dot2 = nextLF(buf, ptr, '.');
+ oldIds[ids.size()] = AbbreviatedObjectId.fromString(buf, ptr, dot2 - 1);
+ newId = AbbreviatedObjectId.fromString(buf, dot2 + 1, eol - 1);
+ oldModes = new FileMode[oldIds.length];
+ }
+
+ @Override
+ protected void parseNewFileMode(final int ptr, final int eol) {
+ for (int i = 0; i < oldModes.length; i++)
+ oldModes[i] = FileMode.MISSING;
+ super.parseNewFileMode(ptr, eol);
+ }
+
+ @Override
+ HunkHeader newHunkHeader(final int offset) {
+ return new CombinedHunkHeader(this, offset);
+ }
+
+ private void parseModeLine(int ptr, final int eol) {
+ // "mode $amode,$bmode..$cmode"
+ //
+ int n = 0;
+ while (ptr < eol) {
+ final int comma = nextLF(buf, ptr, ',');
+ if (eol <= comma)
+ break;
+ oldModes[n++] = parseFileMode(ptr, comma);
+ ptr = comma;
+ }
+ final int dot2 = nextLF(buf, ptr, '.');
+ oldModes[n] = parseFileMode(ptr, dot2);
+ newMode = parseFileMode(dot2 + 1, eol);
+ }
+
+ private void parseDeletedFileMode(int ptr, final int eol) {
+ // "deleted file mode $amode,$bmode"
+ //
+ changeType = ChangeType.DELETE;
+ int n = 0;
+ while (ptr < eol) {
+ final int comma = nextLF(buf, ptr, ',');
+ if (eol <= comma)
+ break;
+ oldModes[n++] = parseFileMode(ptr, comma);
+ ptr = comma;
+ }
+ oldModes[n] = parseFileMode(ptr, eol);
+ newMode = FileMode.MISSING;
+ }
+}

Back to the top