This post explains how to apply a reference filter to your Git server using JGit. This might be useful if you want to filter refs, e.g. hide internal refs. This can be achieved by implementing the interface RefFilter. Once implemented, you just need to apply it to your upload-pack factory so that it can change the upload-pack creation.

If you’re not familiar with Git references, this post will be too difficult for you. I suggest you to first take a look at §10.3 Git Internals - Git References of book “Pro Git”, you’ll get a much better understanding of this subject.

Let’s code. First of all, implement the RefFilter:

/**
 * Ref filter based on regular expression.
 *
 * @author Mincong Huang
 */
public class RegexRefFilter implements RefFilter {

  private final Pattern pattern;

  public RegexRefFilter(Pattern pattern) {
    this.pattern = pattern;
  }

  @Override
  public Map<String, Ref> filter(Map<String, Ref> map) {
    return map.entrySet()
        .stream()
        .filter(e -> pattern.matcher(e.getKey()).matches())
        .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
  }
}

Then, include it in your upload-pack factory to change the upload-pack creation. For example, only takes the public refs refs/heads/public/.* in the ref database, and provide them to the client:

class MyUploadPackFactory implements UploadPackFactory<HttpServletRequest> {
  @Override
  public UploadPack create(HttpServletRequest req, Repository db) {
    UploadPack pack = new UploadPack(db);
    pack.setRefFilter(new RegexRefFilter(Pattern.compile("^refs/heads/public/.*$")));
    return pack;
  }
}

At the end, use this upload-pack factory in your GitServlet:

GitServlet gitServlet = new GitServlet();
gitServlet.setUploadPackFactory(new MyUploadPackFactory());
...

That’s it. Now it should work :)

References