Adds a class which can be used to calculates a SHA1 of the diff associated with a patch, similar to git patch-id. In this version whitespace is not ignored. Change-Id: I421d15ea905e23df543082786786841cbe3ef10d Signed-off-by: Stefan Lay <stefan.lay@sap.com> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>tags/v1.0.0.201106011211-rc3
@@ -0,0 +1,120 @@ | |||
/* | |||
* Copyright (C) 2011, Stefan Lay <stefan.lay@.com> | |||
* 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.diff; | |||
import static org.junit.Assert.assertEquals; | |||
import java.io.File; | |||
import org.eclipse.jgit.api.Git; | |||
import org.eclipse.jgit.dircache.DirCacheIterator; | |||
import org.eclipse.jgit.lib.RepositoryTestCase; | |||
import org.eclipse.jgit.treewalk.FileTreeIterator; | |||
import org.eclipse.jgit.treewalk.filter.PathFilter; | |||
import org.junit.Test; | |||
public class PatchIdDiffFormatterTest extends RepositoryTestCase { | |||
@Test | |||
public void testDiff() throws Exception { | |||
write(new File(db.getDirectory().getParent(), "test.txt"), "test"); | |||
File folder = new File(db.getDirectory().getParent(), "folder"); | |||
folder.mkdir(); | |||
write(new File(folder, "folder.txt"), "folder"); | |||
Git git = new Git(db); | |||
git.add().addFilepattern(".").call(); | |||
git.commit().setMessage("Initial commit").call(); | |||
write(new File(folder, "folder.txt"), "folder change"); | |||
PatchIdDiffFormatter df = new PatchIdDiffFormatter(); | |||
df.setRepository(db); | |||
df.setPathFilter(PathFilter.create("folder")); | |||
DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache()); | |||
FileTreeIterator newTree = new FileTreeIterator(db); | |||
df.format(oldTree, newTree); | |||
df.flush(); | |||
assertEquals("1ff64e0f9333e9b81967c3e8d7a81362b14d5441", df | |||
.getCalulatedPatchId().name()); | |||
} | |||
@Test | |||
public void testSameDiff() throws Exception { | |||
write(new File(db.getDirectory().getParent(), "test.txt"), "test"); | |||
File folder = new File(db.getDirectory().getParent(), "folder"); | |||
folder.mkdir(); | |||
write(new File(folder, "folder.txt"), "\n\n\n\nfolder"); | |||
Git git = new Git(db); | |||
git.add().addFilepattern(".").call(); | |||
git.commit().setMessage("Initial commit").call(); | |||
write(new File(folder, "folder.txt"), "\n\n\n\nfolder change"); | |||
PatchIdDiffFormatter df = new PatchIdDiffFormatter(); | |||
df.setRepository(db); | |||
df.setPathFilter(PathFilter.create("folder")); | |||
DirCacheIterator oldTree = new DirCacheIterator(db.readDirCache()); | |||
FileTreeIterator newTree = new FileTreeIterator(db); | |||
df.format(oldTree, newTree); | |||
df.flush(); | |||
assertEquals("08fca5ac531383eb1da8bf6b6f7cf44411281407", df | |||
.getCalulatedPatchId().name()); | |||
write(new File(folder, "folder.txt"), "a\n\n\n\nfolder"); | |||
git.add().addFilepattern(".").call(); | |||
git.commit().setMessage("Initial commit").call(); | |||
write(new File(folder, "folder.txt"), "a\n\n\n\nfolder change"); | |||
df = new PatchIdDiffFormatter(); | |||
df.setRepository(db); | |||
df.setPathFilter(PathFilter.create("folder")); | |||
oldTree = new DirCacheIterator(db.readDirCache()); | |||
newTree = new FileTreeIterator(db); | |||
df.format(oldTree, newTree); | |||
df.flush(); | |||
assertEquals("08fca5ac531383eb1da8bf6b6f7cf44411281407", df | |||
.getCalulatedPatchId().name()); | |||
} | |||
} |
@@ -1061,16 +1061,29 @@ public class DiffFormatter { | |||
} | |||
if (!ent.getOldId().equals(ent.getNewId())) { | |||
o.write(encodeASCII("index " // | |||
+ format(ent.getOldId()) // | |||
+ ".." // | |||
+ format(ent.getNewId()))); | |||
if (oldMode.equals(newMode)) { | |||
o.write(' '); | |||
newMode.copyTo(o); | |||
} | |||
o.write('\n'); | |||
formatIndexLine(o, ent); | |||
} | |||
} | |||
/** | |||
* @param o | |||
* the stream the formatter will write line data to | |||
* @param ent | |||
* the DiffEntry to create the FileHeader for | |||
* @throws IOException | |||
* writing to the supplied stream failed. | |||
*/ | |||
protected void formatIndexLine(OutputStream o, DiffEntry ent) | |||
throws IOException { | |||
o.write(encodeASCII("index " // | |||
+ format(ent.getOldId()) // | |||
+ ".." // | |||
+ format(ent.getNewId()))); | |||
if (ent.getOldMode().equals(ent.getNewMode())) { | |||
o.write(' '); | |||
ent.getNewMode().copyTo(o); | |||
} | |||
o.write('\n'); | |||
} | |||
private void formatOldNewPaths(ByteArrayOutputStream o, DiffEntry ent) |
@@ -0,0 +1,88 @@ | |||
/* | |||
* Copyright (C) 2011, Stefan Lay <stefan.lay@.com> | |||
* 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.diff; | |||
import java.io.IOException; | |||
import java.io.OutputStream; | |||
import java.security.DigestOutputStream; | |||
import java.security.MessageDigest; | |||
import org.eclipse.jgit.lib.Constants; | |||
import org.eclipse.jgit.lib.ObjectId; | |||
import org.eclipse.jgit.util.io.NullOutputStream; | |||
/** | |||
* A DiffFormatter used to calculate the patch-id of the diff. | |||
*/ | |||
public class PatchIdDiffFormatter extends DiffFormatter { | |||
private final MessageDigest digest; | |||
/** Initialize a formatter to compute a patch id. */ | |||
public PatchIdDiffFormatter() { | |||
super(new DigestOutputStream(NullOutputStream.INSTANCE, | |||
Constants.newMessageDigest())); | |||
digest = ((DigestOutputStream) getOutputStream()).getMessageDigest(); | |||
} | |||
/** | |||
* Should be called after having called one of the format methods | |||
* | |||
* @return the patch id calculated for the provided diff. | |||
*/ | |||
public ObjectId getCalulatedPatchId() { | |||
return ObjectId.fromRaw(digest.digest()); | |||
} | |||
@Override | |||
protected void writeHunkHeader(int aStartLine, int aEndLine, | |||
int bStartLine, int bEndLine) throws IOException { | |||
// The hunk header is not taken into account for patch id calculation | |||
} | |||
@Override | |||
protected void formatIndexLine(OutputStream o, DiffEntry ent) | |||
throws IOException { | |||
// The index line is not taken into account for patch id calculation | |||
} | |||
} |
@@ -0,0 +1,74 @@ | |||
/* | |||
* Copyright (C) 2011, Stefan Lay <stefan.lay@.com> | |||
* 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.util.io; | |||
import java.io.OutputStream; | |||
/** | |||
* An OutputStream which ignores everything written to it. | |||
*/ | |||
public class NullOutputStream extends OutputStream { | |||
/** The canonical instance. */ | |||
public static final NullOutputStream INSTANCE = new NullOutputStream(); | |||
private NullOutputStream() { | |||
// Do nothing, but we want to hide our constructor to prevent | |||
// more than one instance from being created. | |||
} | |||
@Override | |||
public void write(int b) { | |||
// Discard. | |||
} | |||
@Override | |||
public void write(byte[] buf) { | |||
// Discard. | |||
} | |||
@Override | |||
public void write(byte[] buf, int pos, int cnt) { | |||
// Discard. | |||
} | |||
} |