<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged jgit</title>
    <link href="https://passingcuriosity.com/tags/jgit/jgit.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/jgit/jgit.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2020-04-01T00:00:00Z</updated>
    <entry>
    <title>Using jgit in-memory with local file system repositories</title>
    <link href="https://passingcuriosity.com/2020/jgit-in-memory-local-file-system/" />
    <id>https://passingcuriosity.com/2020/jgit-in-memory-local-file-system/</id>
    <published>2020-04-01T00:00:00Z</published>
    <updated>2020-04-01T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>I’ve recently worked on a project that used <a href="https://github.com/eclipse/jgit/">jgit</a> to access configuration
files in repositories hosted on a GitHub. For various reasons we’re using
<code>jgit</code>’s in-memory support with code that looks a little bit like
<code>CloneRemoteRepositoryIntoMemoryAndReadFile.java</code> from <a href="https://github.com/centic9/jgit-cookbook/">jgit-cookbook</a>:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode .java"><code class="sourceCode java"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>DfsRepositoryDescription repoDesc <span class="op">=</span> <span class="kw">new</span> <span class="fu">DfsRepositoryDescription</span><span class="op">();</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>InMemoryRepository repo <span class="op">=</span> <span class="kw">new</span> <span class="fu">InMemoryRepository</span><span class="op">(</span>repoDesc<span class="op">);</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>Git git <span class="op">=</span> <span class="kw">new</span> <span class="fu">Git</span><span class="op">(</span>repo<span class="op">);</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>git<span class="op">.</span><span class="fu">fetch</span><span class="op">()</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">setRemote</span><span class="op">(</span>REMOTE_URL<span class="op">)</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">setRefSpecs</span><span class="op">(</span><span class="kw">new</span> <span class="fu">RefSpec</span><span class="op">(</span><span class="st">&quot;+refs/heads/*:refs/heads/*&quot;</span><span class="op">))</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>        <span class="op">.</span><span class="fu">call</span><span class="op">();</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>repo<span class="op">.</span><span class="fu">getObjectDatabase</span><span class="op">();</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>ObjectId lastCommitId <span class="op">=</span> repo<span class="op">.</span><span class="fu">resolve</span><span class="op">(</span><span class="st">&quot;refs/heads/&quot;</span> <span class="op">+</span> BRANCH<span class="op">);</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>RevWalk revWalk <span class="op">=</span> <span class="kw">new</span> <span class="fu">RevWalk</span><span class="op">(</span>repo<span class="op">);</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>RevCommit commit <span class="op">=</span> revWalk<span class="op">.</span><span class="fu">parseCommit</span><span class="op">(</span>lastCommitId<span class="op">);</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>RevTree tree <span class="op">=</span> commit<span class="op">.</span><span class="fu">getTree</span><span class="op">();</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>TreeWalk treeWalk <span class="op">=</span> <span class="kw">new</span> <span class="fu">TreeWalk</span><span class="op">(</span>repo<span class="op">);</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>treeWalk<span class="op">.</span><span class="fu">addTree</span><span class="op">(</span>tree<span class="op">);</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>treeWalk<span class="op">.</span><span class="fu">setRecursive</span><span class="op">(</span><span class="kw">true</span><span class="op">);</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>treeWalk<span class="op">.</span><span class="fu">setFilter</span><span class="op">(</span>PathFilter<span class="op">.</span><span class="fu">create</span><span class="op">(</span>FILE_TO_READ<span class="op">));</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> <span class="op">(!</span>treeWalk<span class="op">.</span><span class="fu">next</span><span class="op">())</span> <span class="op">{</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span><span class="op">;</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>ObjectId objectId <span class="op">=</span> treeWalk<span class="op">.</span><span class="fu">getObjectId</span><span class="op">(</span><span class="dv">0</span><span class="op">);</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>ObjectLoader loader <span class="op">=</span> repo<span class="op">.</span><span class="fu">open</span><span class="op">(</span>objectId<span class="op">);</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>loader<span class="op">.</span><span class="fu">copyTo</span><span class="op">(</span><span class="bu">System</span><span class="op">.</span><span class="fu">out</span><span class="op">);</span></span></code></pre></div>
<p>This works more or less how you would expect when <code>REMOTE_URL</code> is genuinely
remote (e.g. <code>https://</code> or <code>user@host:path</code> or similar) but results in
<code>NullPointerExceptions</code> with a local repository (e.g. <code>file://</code>, <code>/path</code>,
etc.) We are using local repositories in our integration tests (so that we
don’t need to add yet more fragile, uninteresting network service mocking).</p>
<p>The problem is that <code>Repository</code> subclasses use an instance of <code>FS</code> to access
the local file system when required but <code>InMemoryRepository</code>, for superficially
understandable reasons, leaves that field <code>null</code>. If you want your
<code>InMemoryRepository</code> to be able to operate with on-disk remotes, you need to
supply that <code>FS</code> instance during construction:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode .java"><code class="sourceCode java"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>DfsRepositoryDescription repoDesc <span class="op">=</span> <span class="kw">new</span> <span class="fu">DfsRepositoryDescription</span><span class="op">();</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>InMemoryRepository repo <span class="op">=</span> <span class="kw">new</span> InMemoryRepository<span class="op">.</span><span class="fu">Builder</span><span class="op">()</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">setRepositoryDescription</span><span class="op">(</span>repoDesc<span class="op">)</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">setFS</span><span class="op">(</span>FS<span class="op">.</span><span class="fu">detect</span><span class="op">())</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">build</span><span class="op">();</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>Git git <span class="op">=</span> <span class="kw">new</span> <span class="fu">Git</span><span class="op">(</span>repo<span class="op">);</span></span></code></pre></div>
<p>Then any subsequent operations on those <code>Repository</code> or <code>Git</code> objects that
that need to access the local file system will be able to do so (even though
the repository itself is in-memory).</p>]]></summary>
</entry>

</feed>
