Skip to content

Commit

Permalink
patch: Use reference only as an alternate obj store
Browse files Browse the repository at this point in the history
Old behavior was to use the reference repo (usually the project's
checkout repo) as a full remote that we would fetch from. However, Git
has a more direct way to reference an existing repo, using
`objects/info/alternates`. This mechanism will just let you reuse
objects that already exist in the reference repo rather than fetching
from the real remotes.

So now only origin is a remote and we just try to reuse objects from
the remote. This also simplifies things where we had to check if the
branch we cared about existed. Now, we don't care and if the objects
are relevant they get used and if not, it should be no harm, no foul.

This will hopefully address the issue that reported in #112.
  • Loading branch information
ajoberstar committed Nov 23, 2024
1 parent c7abc58 commit 2875bb5
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ gitPublish {
working.close()
}

def 'reset pulls from reference repo if available before pulling from remote'() {
def 'reset uses reference repo objects if available before pulling from remote'() {
given:
def referenceDir = new File(tempDir, 'reference')
def reference = Grgit.clone(dir: referenceDir, uri: repoPath(remote))
Expand Down Expand Up @@ -159,7 +159,6 @@ gitPublish {
remote.checkout(branch: 'gh-pages')
then:
result.task(':gitPublishPush').outcome == TaskOutcome.SUCCESS
result.output.contains('gh-pages -> reference/gh-pages')
remote.log().size() == 2
remoteFile('content.txt').text == 'published content here'
!remoteFile('newFile.txt').exists()
Expand Down Expand Up @@ -328,7 +327,6 @@ gitPublish {
}

def working = Grgit.clone(dir: "${projectDir}/build/gitPublish", uri: badRemote.repository.rootDir.toURI())
working.checkout(branch: 'gh-pages', startPoint: 'origin/master', createBranch: true)
working.close()

new File(projectDir, 'content.txt') << 'published content here'
Expand All @@ -350,9 +348,11 @@ gitPublish {
and:
remote.checkout(branch: 'gh-pages')
working = Grgit.open(dir: "${projectDir}/build/gitPublish")
working.checkout(branch: 'master')
then:
result.task(':gitPublishPush').outcome == TaskOutcome.SUCCESS
remote.log().size() == 2
working.head().fullMessage == 'bad first commit'
}

def 'when no git publish tasks are run, build completes successfully'() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.inject.Inject;

Expand Down Expand Up @@ -91,51 +94,21 @@ public void reset() throws IOException {
});
}

// set reference
// set alternate object store if reference used
if (getReferenceRepoUri().isPresent()) {
try {
getExecOperations().exec(spec -> {
spec.commandLine("git", "remote", "add", "reference", getReferenceRepoUri().get());
spec.workingDir(repoDir);
spec.setStandardOutput(OutputStream.nullOutputStream());
spec.setErrorOutput(OutputStream.nullOutputStream());
});
} catch (Exception e) {
getExecOperations().exec(spec -> {
spec.commandLine("git", "remote", "set-url", "reference", getReferenceRepoUri().get());
spec.workingDir(repoDir);
spec.setStandardOutput(OutputStream.nullOutputStream());
});
}

// check reference for branch
boolean referenceHasBranch;
try {
getExecOperations().exec(spec -> {
spec.commandLine("git", "ls-remote", "--exit-code", "reference", pubBranch);
spec.workingDir(repoDir);
spec.setStandardOutput(OutputStream.nullOutputStream());
});
referenceHasBranch = true;
} catch (Exception e) {
referenceHasBranch = false;
}

if (referenceHasBranch) {
// get local branch reset to remote state
getExecOperations().exec(spec -> {
var refSpec = String.format("+refs/heads/%s:refs/remotes/reference/%s", pubBranch, pubBranch);

spec.executable("git");
spec.args("fetch");
if (getFetchDepth().isPresent()) {
spec.args("--depth", getFetchDepth().get());
}
spec.args("reference", refSpec);

spec.workingDir(repoDir);
spec.setStandardOutput(OutputStream.nullOutputStream());
});
Path repoObjectsPath = repoDir.toPath().resolve(".git").resolve("objects");
Path alternatesPath = repoObjectsPath.resolve("info").resolve("alternates");

Path referenceRepoPath = Path.of(getReferenceRepoUri().get());

Path referenceRepoObjectsPath = referenceRepoPath.resolve(".git").resolve("objects");
Path referenceBareRepoObjectsPath = referenceRepoPath.resolve("objects");
if (Files.exists(referenceRepoObjectsPath)) {
Files.writeString(alternatesPath, referenceRepoObjectsPath + "\n", StandardCharsets.UTF_8);
} else if (Files.exists(referenceBareRepoObjectsPath)) {
Files.writeString(alternatesPath, referenceBareRepoObjectsPath + "\n", StandardCharsets.UTF_8);
} else {
getLogger().warn("Reference repo doesn't seem to have an objects database: {}", referenceRepoPath);
}
}

Expand All @@ -146,6 +119,7 @@ public void reset() throws IOException {
spec.commandLine("git", "ls-remote", "--exit-code", "origin", pubBranch);
spec.workingDir(repoDir);
spec.setStandardOutput(OutputStream.nullOutputStream());
spec.setErrorOutput(OutputStream.nullOutputStream());
});
hasBranch = true;
} catch (Exception e) {
Expand Down

0 comments on commit 2875bb5

Please sign in to comment.