blob: 3b60e1b5c0d50d7756e7c8b226c4220da0d4f962 [file] [log] [blame]
/*
* Copyright (C) 2024, Broadcom and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.api;
import static org.eclipse.jgit.lib.Constants.HEAD;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Iterator;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.junit.JGitTestUtil;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ReflogEntry;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FS.ExecutionResult;
import org.eclipse.jgit.util.RawParseUtils;
import org.eclipse.jgit.util.TemporaryBuffer;
import org.junit.Test;
public class LinkedWorktreeTest extends RepositoryTestCase {
@Override
public void setUp() throws Exception {
super.setUp();
try (Git git = new Git(db)) {
git.commit().setMessage("Initial commit").call();
}
}
@Test
public void testWeCanReadFromLinkedWorktreeFromBare() throws Exception {
FS fs = db.getFS();
File directory = trash.getParentFile();
String dbDirName = db.getWorkTree().getName();
cloneBare(fs, directory, dbDirName, "bare");
File bareDirectory = new File(directory, "bare");
worktreeAddExisting(fs, bareDirectory, "master");
File worktreesDir = new File(bareDirectory, "worktrees");
File masterWorktreesDir = new File(worktreesDir, "master");
FileRepository repository = new FileRepository(masterWorktreesDir);
try (Git git = new Git(repository)) {
ObjectId objectId = repository.resolve(HEAD);
assertNotNull(objectId);
Iterator<RevCommit> log = git.log().all().call().iterator();
assertTrue(log.hasNext());
assertTrue("Initial commit".equals(log.next().getShortMessage()));
// we have reflog entry
// depending on git version we either have one or
// two entries where extra is zeroid entry with
// same message or no message
Collection<ReflogEntry> reflog = git.reflog().call();
assertNotNull(reflog);
assertTrue(reflog.size() > 0);
ReflogEntry[] reflogs = reflog.toArray(new ReflogEntry[0]);
assertEquals(reflogs[reflogs.length - 1].getComment(),
"reset: moving to HEAD");
// index works with file changes
File masterDir = new File(directory, "master");
File testFile = new File(masterDir, "test");
Status status = git.status().call();
assertTrue(status.getUncommittedChanges().size() == 0);
assertTrue(status.getUntracked().size() == 0);
JGitTestUtil.write(testFile, "test");
status = git.status().call();
assertTrue(status.getUncommittedChanges().size() == 0);
assertTrue(status.getUntracked().size() == 1);
git.add().addFilepattern("test").call();
status = git.status().call();
assertTrue(status.getUncommittedChanges().size() == 1);
assertTrue(status.getUntracked().size() == 0);
}
}
@Test
public void testWeCanReadFromLinkedWorktreeFromNonBare() throws Exception {
FS fs = db.getFS();
worktreeAddNew(fs, db.getWorkTree(), "wt");
File worktreesDir = new File(db.getDirectory(), "worktrees");
File masterWorktreesDir = new File(worktreesDir, "wt");
FileRepository repository = new FileRepository(masterWorktreesDir);
try (Git git = new Git(repository)) {
ObjectId objectId = repository.resolve(HEAD);
assertNotNull(objectId);
Iterator<RevCommit> log = git.log().all().call().iterator();
assertTrue(log.hasNext());
assertTrue("Initial commit".equals(log.next().getShortMessage()));
// we have reflog entry
Collection<ReflogEntry> reflog = git.reflog().call();
assertNotNull(reflog);
assertTrue(reflog.size() > 0);
ReflogEntry[] reflogs = reflog.toArray(new ReflogEntry[0]);
assertEquals(reflogs[reflogs.length - 1].getComment(),
"reset: moving to HEAD");
// index works with file changes
File directory = trash.getParentFile();
File wtDir = new File(directory, "wt");
File testFile = new File(wtDir, "test");
Status status = git.status().call();
assertTrue(status.getUncommittedChanges().size() == 0);
assertTrue(status.getUntracked().size() == 0);
JGitTestUtil.write(testFile, "test");
status = git.status().call();
assertTrue(status.getUncommittedChanges().size() == 0);
assertTrue(status.getUntracked().size() == 1);
git.add().addFilepattern("test").call();
status = git.status().call();
assertTrue(status.getUncommittedChanges().size() == 1);
assertTrue(status.getUntracked().size() == 0);
}
}
private static void cloneBare(FS fs, File directory, String from, String to) throws IOException, InterruptedException {
ProcessBuilder builder = fs.runInShell("git",
new String[] { "clone", "--bare", from, to });
builder.directory(directory);
builder.environment().put("HOME", fs.userHome().getAbsolutePath());
StringBuilder input = new StringBuilder();
ExecutionResult result = fs.execute(builder, new ByteArrayInputStream(
input.toString().getBytes(StandardCharsets.UTF_8)));
String stdOut = toString(result.getStdout());
String errorOut = toString(result.getStderr());
assertNotNull(stdOut);
assertNotNull(errorOut);
}
private static void worktreeAddExisting(FS fs, File directory, String name) throws IOException, InterruptedException {
ProcessBuilder builder = fs.runInShell("git",
new String[] { "worktree", "add", "../" + name, name });
builder.directory(directory);
builder.environment().put("HOME", fs.userHome().getAbsolutePath());
StringBuilder input = new StringBuilder();
ExecutionResult result = fs.execute(builder, new ByteArrayInputStream(
input.toString().getBytes(StandardCharsets.UTF_8)));
String stdOut = toString(result.getStdout());
String errorOut = toString(result.getStderr());
assertNotNull(stdOut);
assertNotNull(errorOut);
}
private static void worktreeAddNew(FS fs, File directory, String name) throws IOException, InterruptedException {
ProcessBuilder builder = fs.runInShell("git",
new String[] { "worktree", "add", "-b", name, "../" + name, "master"});
builder.directory(directory);
builder.environment().put("HOME", fs.userHome().getAbsolutePath());
StringBuilder input = new StringBuilder();
ExecutionResult result = fs.execute(builder, new ByteArrayInputStream(
input.toString().getBytes(StandardCharsets.UTF_8)));
String stdOut = toString(result.getStdout());
String errorOut = toString(result.getStderr());
assertNotNull(stdOut);
assertNotNull(errorOut);
}
private static String toString(TemporaryBuffer b) throws IOException {
return RawParseUtils.decode(b.toByteArray());
}
}