Skip to content

Instantly share code, notes, and snippets.

@porcelli
Created May 26, 2020 19:10
Show Gist options
  • Save porcelli/d36a2b78c909c35fb628033a07e6fdbc to your computer and use it in GitHub Desktop.
Save porcelli/d36a2b78c909c35fb628033a07e6fdbc to your computer and use it in GitHub Desktop.
Code for blog post: How to automatically push every change to an external repository
public class GitHook {
public static void main(String[] args) throws IOException, GitAPIException {
// collect the repository location <1>
final Path currentPath = new File("").toPath().toAbsolutePath();
final String parentFolderName = currentPath.getParent().getName(currentPath.getParent().getNameCount() - 1).toString();
// ignoring system space <2>
if (parentFolderName.equalsIgnoreCase("system")) {
return;
}
// setup GitHub credentials and integration <3>
final GitHubCredentials ghCredentials = new GitHubCredentials();
final GitHubIntegration integration = new GitHubIntegration();
// setup the JGit repository access <4>
final Repository repo = new FileRepositoryBuilder()
.setGitDir(currentPath.toFile())
.build();
final Git git = new Git(repo);
// collect all remotes for the current repository <5>
final StoredConfig storedConfig = repo.getConfig();
final Set<String> remotes = storedConfig.getSubsections("remote");
if (remotes.isEmpty()) {
//create a remote repository, if it does not exist <6>
new SetupRemote(ghCredentials, integration).execute(git, currentPath);
}
// mechanism to find the latest commit <7>
final List<Ref> branches = git.branchList().setListMode(ListBranchCommand.ListMode.ALL).call();
final RevWalk revWalk = new RevWalk(git.getRepository()); <8>
branches.stream()
.map(branch -> {
try {
return revWalk.parseCommit(branch.getObjectId());
} catch (Exception e) {
throw new RuntimeException(e);
}
})
.max(comparing((RevCommit commit) -> commit.getAuthorIdent().getWhen()))
.ifPresent(latestCommit -> {
// the integration here <9>
});
}
}
//get the branches where this commit is referenced <1>
final Map<ObjectId, String> branchesAffected = git
.nameRev()
.addPrefix("refs/heads")
.add(latestCommit)
.call();
//iterate over all remote repositories <2>
for (String remoteName : remotes) {
final String remoteURL = storedConfig.getString("remote", remoteName, "url");
for (String ref : branchesAffected.values()) { <3>
// push changes to the remote repository <4>
git.push()
.setRefSpecs(new RefSpec(ref + ":" + ref))
.setRemote(remoteURL)
.setCredentialsProvider(ghCredentials.getCredentials())
.call();
//check if the branch has a remote config <5>
final String remote = storedConfig.getString("branch", ref, "remote");
if (remote == null) {
//branch had no remote info, now needs to be update <6>
storedConfig.setString("branch", ref, "remote", remoteName);
storedConfig.setString("branch", ref, "merge", "refs/heads/" + ref);
storedConfig.save();
}
}
}
#!/bin/bash
java -jar $APP_SERVER_HOME/hooks/git-push-1.0-SNAPSHOT.jar // <1>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment