[vcs]: create sha1 constructor with tests for future usages and reuse not_committed hash constant

This commit is contained in:
Nadya Zabrodina
2016-08-23 17:06:59 +03:00
committed by Nadya Zabrodina
parent 27b5a44213
commit 8f6e63de37
3 changed files with 150 additions and 2 deletions
@@ -0,0 +1,79 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.vcs.changes.patch;
import com.google.common.base.Charsets;
import com.google.common.hash.Hashing;
import com.google.common.io.Files;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.BinaryContentRevision;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import static com.intellij.util.ArrayUtil.EMPTY_BYTE_ARRAY;
public class BlobIndexUtil {
public static final String NOT_COMMITTED_HASH = StringUtil.repeat("0", 40);
@NotNull
public static String getSha1(@NotNull File file) throws IOException {
return getSha1(Files.toByteArray(file));
}
/**
* Generate sha1 for file content using git-like algorithm
*/
@NotNull
public static String getSha1(@NotNull byte[] bytes) {
String prefix = "blob " + bytes.length + '\u0000';
return Hashing.sha1().newHasher().putBytes(prefix.getBytes(Charsets.UTF_8)).putBytes(bytes).hash().toString();
}
@NotNull
public static Couple<String> getBeforeAfterSha1(@NotNull Change change) throws VcsException {
ContentRevision beforeRevision = change.getBeforeRevision();
ContentRevision afterRevision = change.getAfterRevision();
//noinspection ConstantConditions
Charset detectCharset = ObjectUtils.chooseNotNull(afterRevision, beforeRevision).getFile().getCharset();
String before = beforeRevision == null ? NOT_COMMITTED_HASH : getSha1(getContentBytes(beforeRevision, detectCharset));
String after = afterRevision == null ? NOT_COMMITTED_HASH : getSha1(getContentBytes(afterRevision, detectCharset));
return new Couple<>(before, after);
}
@NotNull
private static byte[] getContentBytes(@NotNull ContentRevision revision, @NotNull Charset charset) throws VcsException {
byte[] binaryContent;
if (revision instanceof BinaryContentRevision) {
binaryContent = ((BinaryContentRevision)revision).getBinaryContent();
}
else {
String stringContent = revision.getContent();
binaryContent = stringContent != null ? stringContent.getBytes(charset) : EMPTY_BYTE_ARRAY;
}
return binaryContent != null ? binaryContent : EMPTY_BYTE_ARRAY;
}
}
@@ -18,8 +18,8 @@ package git4idea;
import com.intellij.dvcs.DvcsUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.patch.BlobIndexUtil;
import com.intellij.openapi.vcs.history.ShortVcsRevisionNumber;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vfs.VirtualFile;
@@ -38,7 +38,7 @@ public class GitRevisionNumber implements ShortVcsRevisionNumber {
/**
* the hash from 40 zeros representing not yet created commit
*/
public static final String NOT_COMMITTED_HASH = StringUtil.repeat("0", 40);
public static final String NOT_COMMITTED_HASH = BlobIndexUtil.NOT_COMMITTED_HASH;
public static final GitRevisionNumber HEAD = new GitRevisionNumber("HEAD");
@@ -0,0 +1,69 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package git4idea.log
import com.intellij.openapi.vcs.Executor.cd
import com.intellij.openapi.vcs.Executor.touch
import com.intellij.openapi.vcs.changes.patch.BlobIndexUtil
import git4idea.test.GitExecutor.*
import git4idea.test.GitSingleRepoTest
import git4idea.test.GitTestUtil
class GitSha1Test : GitSingleRepoTest() {
var A_FILE = "a.txt"
@Throws(Exception::class)
override fun setUp() {
super.setUp()
GitTestUtil.createFileStructure(myProjectRoot, A_FILE)
addCommit("initial")
}
fun `test sha for add`() {
cd(myProjectPath)
val newFile = "newFile.txt"
touch(newFile, "Hello World!")
add(newFile)
checkSha1ForSingleChange(BlobIndexUtil.NOT_COMMITTED_HASH, git("hash-object $newFile"))
}
fun `test sha for del`() {
cd(myProjectPath)
val path = myProjectRoot.findChild(A_FILE)!!.path
val expectedBefore = git("hash-object $path")
git("rm $path")
checkSha1ForSingleChange(expectedBefore, BlobIndexUtil.NOT_COMMITTED_HASH)
}
fun `test sha for modified`() {
cd(myProjectPath)
val virtualFile = myProjectRoot.findChild(A_FILE)
val path = virtualFile!!.path
val expectedBefore = git("hash-object $path")
setFileText(virtualFile, "echo content\n with line separator")
checkSha1ForSingleChange(expectedBefore, git("hash-object $path"))
}
private fun checkSha1ForSingleChange(expectedBefore: String?, expectedAfter: String?) {
updateChangeListManager()
val changes = changeListManager.allChanges
assertTrue(changes.size == 1)
val beforeAfterSha1 = BlobIndexUtil.getBeforeAfterSha1(changes.first())
assertEquals(expectedBefore, beforeAfterSha1.first)
assertEquals(expectedAfter, beforeAfterSha1.second)
}
}