Skip to content
Permalink
Browse files
Proper parsing of git diff --raw lines
Reviewed-by: rwestberg
  • Loading branch information
edvbld committed Aug 16, 2019
1 parent d2e6beb commit f9979b0730fafa752550173680008557e4b1c2a7
@@ -82,30 +82,29 @@ public static PatchHeader fromRawLine(String line) {
if (line == null || line.isEmpty() || line.charAt(0) != ':') {
throw new IllegalArgumentException("Raw line does not start with colon: " + line);
}
line = line.substring(1); // skip the first ':' char
var sourceType = FileType.fromOctal(line.substring(1, 7));
var targetType = FileType.fromOctal(line.substring(8, 14));

var words = line.split("\\s");
var sourceType = FileType.fromOctal(words[0]);
var targetType = FileType.fromOctal(words[1]);
var sourceHash = new Hash(line.substring(15, 55));
var targetHash = new Hash(line.substring(56, 96));

var sourceHash = new Hash(words[2]);
var targetHash = new Hash(words[3]);

var status = Status.from(words[4]);
var rest = line.substring(97);
var parts = rest.split("\t");
var status = Status.from(parts[0]);

Path sourcePath = null;
Path targetPath = null;
if (status.isModified()) {
sourcePath = Path.of(words[5]);
sourcePath = Path.of(parts[1]);
targetPath = sourcePath;
} else if (status.isAdded()) {
targetPath = Path.of(words[5]);
targetPath = Path.of(parts[1]);
} else if (status.isDeleted()) {
sourcePath = Path.of(words[5]);
sourcePath = Path.of(parts[1]);
} else {
// either copied or renamed
sourcePath = Path.of(words[5]);
targetPath = Path.of(words[6]);
sourcePath = Path.of(parts[1]);
targetPath = Path.of(parts[2]);
}

return new PatchHeader(sourcePath, sourceType, sourceHash, targetPath, targetType, targetHash, status);
@@ -67,11 +67,11 @@ def _diff_git_raw(repo, ctx1, ctx2, modified, added, removed):
for path in sorted(modified | added | removed_copy):
if path in modified:
fctx = ctx2.filectx(path)
writeln(':{} {} {} {} M {}'.format(mode(ctx1.filectx(path)), mode(fctx), nullHash, nullHash, fctx.path()))
writeln(':{} {} {} {} M\t{}'.format(mode(ctx1.filectx(path)), mode(fctx), nullHash, nullHash, fctx.path()))
elif path in added:
fctx = ctx2.filectx(path)
if not fctx.renamed():
writeln(':000000 {} {} {} A {}'.format(mode(fctx), nullHash, nullHash, fctx.path()))
writeln(':000000 {} {} {} A\t{}'.format(mode(fctx), nullHash, nullHash, fctx.path()))
else:
parent = fctx.p1()
score = int(ratio(parent.data(), fctx.data(), 0.5) * 100)
@@ -82,10 +82,10 @@ def _diff_git_raw(repo, ctx1, ctx2, modified, added, removed):
else:
operation = 'C'

writeln(':{} {} {} {} {}{} {} {}'.format(mode(parent), mode(fctx), nullHash, nullHash, operation, score, old_path, path))
writeln(':{} {} {} {} {}{}\t{}\t{}'.format(mode(parent), mode(fctx), nullHash, nullHash, operation, score, old_path, path))
elif path in removed_copy:
fctx = ctx1.filectx(path)
writeln(':{} 000000 {} {} D {}'.format(mode(fctx), nullHash, nullHash, path))
writeln(':{} 000000 {} {} D\t{}'.format(mode(fctx), nullHash, nullHash, path))

writeln('')

@@ -1438,4 +1438,28 @@ void testGetAndExistsOnNonExistingDirectory() throws IOException {
assertEquals(Optional.empty(), Repository.get(nonExistingDirectory));
assertEquals(false, Repository.exists(nonExistingDirectory));
}

@ParameterizedTest
@EnumSource(VCS.class)
void testDiffOnFilenamesWithSpace(VCS vcs) throws IOException {
try (var dir = new TemporaryDirectory()) {
var r = Repository.init(dir.path(), vcs);
assertTrue(r.isClean());

var fileWithSpaceInName = dir.path().resolve("hello world.txt");
Files.writeString(fileWithSpaceInName, "Hello world\n");
r.add(fileWithSpaceInName);
var hash1 = r.commit("Added file with space in name", "duke", "duke@openjdk.java.net");
Files.writeString(fileWithSpaceInName, "Goodbye world\n");
r.add(fileWithSpaceInName);
var hash2 = r.commit("Modified file with space in name", "duke", "duke@openjdk.java.net");
var diff = r.diff(hash1, hash2);
var patches = diff.patches();
assertEquals(1, patches.size());
var patch = patches.get(0);
assertTrue(patch.target().path().isPresent());
var path = patch.target().path().get();
assertEquals(Path.of("hello world.txt"), path);
}
}
}

0 comments on commit f9979b0

Please sign in to comment.