Enable calling of smudge filters when checking out paths

When checking out commits/branches JGit was triggering correctly
configured smudge filters. But when checking out paths (either from
index or from commits) JGit was not triggering smudge filters. Fix
CheckoutCommand to properly call filters.

Bug: 486560
Also-by: Pascal Krause <pascal.krausek@sap.com>
Change-Id: I5ff893054defe57ab12e201d901fe74e1376efea
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
Christian Halstrick 2016-04-05 16:04:39 +02:00 committed by Matthias Sohn
parent 46bef2bcb6
commit 47dd98e362
2 changed files with 115 additions and 4 deletions

View File

@ -632,6 +632,113 @@ public void testSmudgeFilter_createNew()
assertEquals("fee\n", read("src/a.txt"));
}
@Test
public void testSmudgeFilter_deleteFileAndRestoreFromCommit()
throws IOException, GitAPIException {
File script = writeTempFile("sed s/o/e/g");
StoredConfig config = git.getRepository().getConfig();
config.setString("filter", "tstFilter", "smudge",
"sh " + slashify(script.getPath()));
config.save();
writeTrashFile("foo", "foo");
git.add().addFilepattern("foo").call();
git.commit().setMessage("initial").call();
writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
git.add().addFilepattern(".gitattributes").call();
git.commit().setMessage("add filter").call();
writeTrashFile("src/a.tmp", "foo");
// Caution: we need a trailing '\n' since sed on mac always appends
// linefeeds if missing
writeTrashFile("src/a.txt", "foo\n");
git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
.call();
RevCommit content = git.commit().setMessage("added content").call();
deleteTrashFile("src/a.txt");
git.checkout().setStartPoint(content.getName()).addPath("src/a.txt")
.call();
assertEquals(
"[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
indexState(CONTENT));
assertEquals("foo", read("src/a.tmp"));
assertEquals("fee\n", read("src/a.txt"));
}
@Test
public void testSmudgeFilter_deleteFileAndRestoreFromIndex()
throws IOException, GitAPIException {
File script = writeTempFile("sed s/o/e/g");
StoredConfig config = git.getRepository().getConfig();
config.setString("filter", "tstFilter", "smudge",
"sh " + slashify(script.getPath()));
config.save();
writeTrashFile("foo", "foo");
git.add().addFilepattern("foo").call();
git.commit().setMessage("initial").call();
writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
git.add().addFilepattern(".gitattributes").call();
git.commit().setMessage("add filter").call();
writeTrashFile("src/a.tmp", "foo");
// Caution: we need a trailing '\n' since sed on mac always appends
// linefeeds if missing
writeTrashFile("src/a.txt", "foo\n");
git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
.call();
git.commit().setMessage("added content").call();
deleteTrashFile("src/a.txt");
git.checkout().addPath("src/a.txt").call();
assertEquals(
"[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
indexState(CONTENT));
assertEquals("foo", read("src/a.tmp"));
assertEquals("fee\n", read("src/a.txt"));
}
@Test
public void testSmudgeFilter_deleteFileAndCreateBranchAndRestoreFromCommit()
throws IOException, GitAPIException {
File script = writeTempFile("sed s/o/e/g");
StoredConfig config = git.getRepository().getConfig();
config.setString("filter", "tstFilter", "smudge",
"sh " + slashify(script.getPath()));
config.save();
writeTrashFile("foo", "foo");
git.add().addFilepattern("foo").call();
git.commit().setMessage("initial").call();
writeTrashFile(".gitattributes", "*.txt filter=tstFilter");
git.add().addFilepattern(".gitattributes").call();
git.commit().setMessage("add filter").call();
writeTrashFile("src/a.tmp", "foo");
// Caution: we need a trailing '\n' since sed on mac always appends
// linefeeds if missing
writeTrashFile("src/a.txt", "foo\n");
git.add().addFilepattern("src/a.tmp").addFilepattern("src/a.txt")
.call();
RevCommit content = git.commit().setMessage("added content").call();
deleteTrashFile("src/a.txt");
git.checkout().setName("newBranch").setCreateBranch(true)
.setStartPoint(content).addPath("src/a.txt").call();
assertEquals(
"[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]",
indexState(CONTENT));
assertEquals("foo", read("src/a.tmp"));
assertEquals("fee\n", read("src/a.txt"));
}
@Test
@Ignore
public void testSmudgeAndClean() throws IOException, GitAPIException {

View File

@ -430,6 +430,8 @@ private void checkoutPathsFromIndex(TreeWalk treeWalk, DirCache dc)
continue;
final EolStreamType eolStreamType = treeWalk.getEolStreamType();
final String filterCommand = treeWalk
.getFilterCommand(Constants.ATTR_FILTER_TYPE_SMUDGE);
editor.add(new PathEdit(path) {
public void apply(DirCacheEntry ent) {
int stage = ent.getStage();
@ -437,15 +439,15 @@ public void apply(DirCacheEntry ent) {
if (checkoutStage != null) {
if (stage == checkoutStage.number)
checkoutPath(ent, r, new CheckoutMetadata(
eolStreamType, null));
eolStreamType, filterCommand));
} else {
UnmergedPathException e = new UnmergedPathException(
ent);
throw new JGitInternalException(e.getMessage(), e);
}
} else {
checkoutPath(ent, r,
new CheckoutMetadata(eolStreamType, null));
checkoutPath(ent, r, new CheckoutMetadata(eolStreamType,
filterCommand));
}
}
});
@ -464,12 +466,14 @@ private void checkoutPathsFromCommit(TreeWalk treeWalk, DirCache dc,
final ObjectId blobId = treeWalk.getObjectId(0);
final FileMode mode = treeWalk.getFileMode(0);
final EolStreamType eolStreamType = treeWalk.getEolStreamType();
final String filterCommand = treeWalk
.getFilterCommand(Constants.ATTR_FILTER_TYPE_SMUDGE);
editor.add(new PathEdit(treeWalk.getPathString()) {
public void apply(DirCacheEntry ent) {
ent.setObjectId(blobId);
ent.setFileMode(mode);
checkoutPath(ent, r,
new CheckoutMetadata(eolStreamType, null));
new CheckoutMetadata(eolStreamType, filterCommand));
}
});
}