<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet type="text/xsl" href="/rss.xsl"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Open-Source · Pablo Sabater</title><link>https://pablosabater.dev/tags/open-source/</link><description>Pablo Sabater writes about what he finds interesting: compilers, low-level tools, open source and life.</description><language>en</language><managingEditor>pablo@pablosabater.dev (Pablo Sabater)</managingEditor><lastBuildDate>Mon, 24 Aug 2026 20:27:00 +0200</lastBuildDate><atom:link href="https://pablosabater.dev/tags/open-source/index.xml" rel="self" type="application/rss+xml"/><item><title>GSoC 2026 with Git</title><link>https://pablosabater.dev/posts/gsoc-2026-final-report/</link><pubDate>Mon, 24 Aug 2026 20:27:00 +0200</pubDate><guid>https://pablosabater.dev/posts/gsoc-2026-final-report/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is a quick look at the work done. I suggest getting into the threads of the two
series, reading my &lt;a href="https://pablosabater.dev"&gt;blog&lt;/a&gt; or my &lt;a href="https://pablosabater.dev/proposal.pdf"&gt;proposal&lt;/a&gt; if you want more detailed information.
I consider this a more intimate writing recapping what I did this summer.&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2 id="complete-and-extend-the-remote-object-info-command-for-git-cat-file"&gt;Complete and extend the remote-object-info command for git cat-file&lt;a class="anchor" href="#complete-and-extend-the-remote-object-info-command-for-git-cat-file" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Sometimes it is only needed to know something &lt;em&gt;about&lt;/em&gt; an object, its size, its type, etc.
Before this project, it was not possible to know that without downloading it. Git&amp;rsquo;s
v2 protocol had a server-side &lt;code&gt;object-info&lt;/code&gt; capability since 2021, but no client used it.&lt;/p&gt;
&lt;p&gt;This project finishes that. &lt;code&gt;git cat-file --batch-command&lt;/code&gt; now understands a &lt;code&gt;remote-object-info&lt;/code&gt; command that asks a remote for object metadata over the v2 protocol
and prints it, without downloading it.&lt;/p&gt;
&lt;p&gt;Two patch series came out of the summer:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Series&lt;/th&gt;
 &lt;th&gt;Patches&lt;/th&gt;
 &lt;th&gt;Final iteration&lt;/th&gt;
 &lt;th&gt;Status&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a href="https://lore.kernel.org/git/20260724-ps-eric-work-rebase-v21-0-ba67f024fdff@gmail.com/"&gt;&lt;code&gt;cat-file: add remote-object-info to batch-command&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;13&lt;/td&gt;
 &lt;td&gt;v21&lt;/td&gt;
 &lt;td&gt;merged into &lt;code&gt;master&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;a href="https://lore.kernel.org/git/20260808-objecttype-support-v6-0-e5cdaf27a49c@gmail.com/"&gt;&lt;code&gt;cat-file: extend remote-object-info to support %(objecttype)&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
 &lt;td&gt;10&lt;/td&gt;
 &lt;td&gt;v6&lt;/td&gt;
 &lt;td&gt;will merge into &lt;code&gt;master&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="about-the-project"&gt;About the project&lt;a class="anchor" href="#about-the-project" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="about-cat-file-and-object-info-protocol"&gt;About &lt;code&gt;cat-file&lt;/code&gt; and &lt;code&gt;object-info&lt;/code&gt; protocol&lt;a class="anchor" href="#about-cat-file-and-object-info-protocol" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;git cat-file&lt;/code&gt; prints information about objects in a cloned repository locally, you can get lots of
information such as the size, type, size:disk, delta. But it had no way of gathering that information from a remote,
you had to download that object beforehand using &lt;code&gt;git cat-file&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Protocol v2 already had the server half of this. Support for answering object
size requests landed in &lt;code&gt;a2ba162cda&lt;/code&gt; (object-info: support for retrieving object
info, 2021-04-20). What was missing was any client that used it.&lt;/p&gt;
&lt;h3 id="prior-work"&gt;Prior work&lt;a class="anchor" href="#prior-work" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This project continues the work of Calvin Wan and Eric Ju. They introduced &lt;code&gt;remote-object-info&lt;/code&gt; into &lt;code&gt;cat-file&lt;/code&gt;, but the work had stalled and wasn&amp;rsquo;t ready yet. The code worked in the ideal path
but lacked proper supported handling, the transport was piggy-backing on fetch and there were some
logic issues.&lt;/p&gt;
&lt;h3 id="the-problem"&gt;The problem&lt;a class="anchor" href="#the-problem" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Well, there was a lot of previous work done. This has been a multi-GSoC project,
and I had to rebase everything up to today&amp;rsquo;s &lt;code&gt;master&lt;/code&gt;. Some things were easy and some
were not, especially the ODB-related code, as there had been a lot of refactoring
related to ODB code, a lot of functions moved, and whole files removed.&lt;/p&gt;
&lt;h3 id="the-goal"&gt;The goal&lt;a class="anchor" href="#the-goal" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Get &lt;code&gt;remote-object-info&lt;/code&gt; merged with &lt;code&gt;%(objectsize)&lt;/code&gt; working end to end, then
extend it to support &lt;code&gt;%(objecttype)&lt;/code&gt; as well.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can see more about the problems if you read my blog or my proposal.&lt;/p&gt;&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="what-was-implemented"&gt;What was implemented&lt;a class="anchor" href="#what-was-implemented" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;h3 id="goal-1-series-remote-object-info-in---batch-command-v21-13-patches"&gt;Goal 1 series: &lt;code&gt;remote-object-info&lt;/code&gt; in &lt;code&gt;--batch-command&lt;/code&gt; (v21, 13 patches)&lt;a class="anchor" href="#goal-1-series-remote-object-info-in---batch-command-v21-13-patches" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Completes Eric&amp;rsquo;s work and gets it to &lt;code&gt;master&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The main contribution on top of the inherited series is a rework of placeholder
validation: instead of a hardcoded list, an allow-list is used to filter what it
supports instead of accepting the same placeholders as local. Also, with this allow-list,
placeholders known in local but unsupported by the remote will return an empty string, as suggested by Jeff King.&lt;/p&gt;
&lt;p&gt;The idea of the allow-list evolved to a list that initially accepts everything but once the
connection with the remote is established, the remote returns what it supports, and after
receiving it, the client would trim the allow-list to only contain what the server supports.
Later on, when printing the data, the requested data that had no match in the allow-list meant it
was unsupported and therefore an empty string is printed.&lt;/p&gt;
&lt;p&gt;This series was originally intended to be client-side only, but it was decided to add a server-side
patch where we would allow a request without attributes such as size, type, &amp;hellip; This would
serve as an existence check.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://lore.kernel.org/git/20260724-ps-eric-work-rebase-v21-0-ba67f024fdff@gmail.com/"&gt;https://lore.kernel.org/git/20260724-ps-eric-work-rebase-v21-0-ba67f024fdff@gmail.com/&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="goal-2-series-end-to-end-for-objecttype-v6-10-patches"&gt;Goal 2 series: end-to-end for &lt;code&gt;%(objecttype)&lt;/code&gt; (v6, 10 patches)&lt;a class="anchor" href="#goal-2-series-end-to-end-for-objecttype-v6-10-patches" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Type was the next attribute that we wanted to add support for. I thought at first that
after type the rest would follow the same path, but after working on it, I realized that
the rest of the attributes depend on how the object is packed; they are not intrinsic
to the object. So we discarded support for them.&lt;/p&gt;
&lt;p&gt;This series relies heavily on the previous one &lt;em&gt;obviously&lt;/em&gt;, but I didn&amp;rsquo;t want to make it &lt;strong&gt;just&lt;/strong&gt; work.
Of the 10 patches, 6 are preparatory patches that clean, trim ambiguity and fix
the current work.&lt;/p&gt;
&lt;p&gt;This series extends the object-info protocol to support the type attribute, and handles it both on the server
and the client: advertising it, parsing it, sending the data, &amp;hellip; To later, in the last patch, unify the
default format to match the local &lt;code&gt;info&lt;/code&gt; command one.&lt;/p&gt;
&lt;p&gt;For this patch I could count on the expertise of Jeff King and Junio, who noted that the use of an array of
object_info was not good. This structure is used to mark what the user wants to get and to later hold the
object being printed, so using an array of it breaks the intended use of it. Instead, this new structure
was created:&lt;/p&gt;

&lt;div class="codeblock"&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;fetch_object_info_results&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;object_type&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;uint8_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;unrecognized&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;nr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="nl"&gt;wants_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="nl"&gt;wants_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;p&gt;Instead of having the indirections of having to allocate object_info and then for each field, we have the data contiguously in its own attribute array, we also split from using object_info marked pointer to bit fields that mark what the user wants.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://lore.kernel.org/git/20260808-objecttype-support-v6-0-e5cdaf27a49c@gmail.com/"&gt;https://lore.kernel.org/git/20260808-objecttype-support-v6-0-e5cdaf27a49c@gmail.com/&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="backward-compatibility"&gt;Backward compatibility&lt;a class="anchor" href="#backward-compatibility" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The server-side needed to have backward compatibility with the 2021 work, and we
also had to think about different client versions and different servers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the client knows it but the server does not (new client vs old server)&lt;/li&gt;
&lt;li&gt;the client does not know it but the server does (old client vs new server)&lt;/li&gt;
&lt;li&gt;both know it (everyone is new)&lt;/li&gt;
&lt;li&gt;neither knows it (unsupported capability)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="learning-from-git"&gt;Learning from git&lt;a class="anchor" href="#learning-from-git" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Well, TBH it has been a very rewarding experience. I&amp;rsquo;ve learned a lot and imma skip the
obvious: better logic, a broader perspective, etc.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I learned how to work on a mailing list and with people. I always code alone, so this was
a new experience for me.&lt;/li&gt;
&lt;li&gt;I learned how git works under the hood.&lt;/li&gt;
&lt;li&gt;I went through review loops and learned to review other people&amp;rsquo;s code.&lt;/li&gt;
&lt;li&gt;I learned protocol stuff, like not being ambiguous (yes, I know that it is obvious). This comes
from the number parsing function: I made a function that was too broad, you could parse HEX
when there was no need, we only wanted to parse the size in base 10.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="could-it-have-been-done-better"&gt;Could it have been done better?&lt;a class="anchor" href="#could-it-have-been-done-better" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Hummmmm, yes I do think that. I have two itches. The first is the object-info protocol, having to rely
on the previous protocol and not starting from the beginning of it made the protocol with type look like:&lt;/p&gt;

&lt;div class="codeblock plain"&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt;command=object-info
object-format=$(test_oid algo)
0001
size
type
oid $two_oid
oid $two_oid
0000
EOF&lt;/code&gt;&lt;/pre&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;p&gt;The new line after size, although not something to cry about, ideally should be &lt;code&gt;size type&lt;/code&gt; on the same line.&lt;/p&gt;

&lt;div class="codeblock"&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;fetch_object_info_results&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;object_type&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;uint8_t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;unrecognized&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;nr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="nl"&gt;wants_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;	&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="nl"&gt;wants_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;p&gt;For this same data structure mentioned before, unrecognized could be optimized to be a true bit array, instead of wasting 7 bits for each one.&lt;/p&gt;
&lt;h2 id="how-do-i-plan-to-keep-working"&gt;How do I plan to keep working&lt;a class="anchor" href="#how-do-i-plan-to-keep-working" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Right now I have the idea to add the &lt;code&gt;dry-run&lt;/code&gt; option for &lt;code&gt;git backfill&lt;/code&gt;, the object-info protocol could be used to fetch
the size of those objects to give the user the number of objects to be fetched with an estimate of the size that they will
take.&lt;/p&gt;
&lt;p&gt;I have also read that it could be interesting for VFS, but for that, sadly, I&amp;rsquo;m completely ignorant and I will have to study it.&lt;/p&gt;
&lt;h2 id="not-just-gsoc"&gt;Not just GSoC&lt;a class="anchor" href="#not-just-gsoc" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This summer I didn&amp;rsquo;t just make the project, in fact I worked on other areas such as the graph one. I really like this one because what I did was very visual and cool looking:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git log --graph&lt;/code&gt; had a problem with visual roots that made the graph &lt;em&gt;sometimes&lt;/em&gt; ambiguous, as two completely unrelated commits could be rendered one below the other seeming that they are related when in reality they are not:&lt;/p&gt;
&lt;p&gt;The idea is to indent/shift the visual roots that can cause that given ambiguity, fixing a long-known rule: &lt;em&gt;vertically contiguous commits don&amp;rsquo;t have to mean a relation between them&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Before indentation:&lt;/p&gt;

&lt;div class="codeblock plain"&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt;* A
* B1
* B2
* C1
* C2&lt;/code&gt;&lt;/pre&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;p&gt;After indentation:&lt;/p&gt;

&lt;div class="codeblock plain"&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt; * A
* B1
 \
 * B2
* C1
* C2&lt;/code&gt;&lt;/pre&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;p&gt;You can see more about how this works at:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://lore.kernel.org/git/20260714-ps-pre-commit-indent-v12-0-d50938e006df@gmail.com/"&gt;https://lore.kernel.org/git/20260714-ps-pre-commit-indent-v12-0-d50938e006df@gmail.com/&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;And lastly, at the end of this GSoC period I wanted to do a favour for the next contributors that come to
Git and maybe not that new but curious, a tool called &lt;a href="https://github.com/pabloosabaterr/WhatToGit"&gt;WhatToGit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This tool gathers all the markers in the codebase such as &lt;code&gt;TODO&lt;/code&gt;, &lt;code&gt;NEEDSWORK&lt;/code&gt;, etc., and &lt;code&gt;#leftoverbits&lt;/code&gt; on the mailing list into documents so it is easier to know literal pieces of wanted work.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;This is the part for which I wanted to write this whole thing instead of just sending a link
to the work.&lt;/p&gt;
&lt;p&gt;I cannot express how grateful I am to Karthik and Chandra. This summer has been &amp;ldquo;un antes y un
después&amp;rdquo; for me, a turning point forward. They have been great mentors and have helped me as much
as I needed. More than that, they have been friends this summer.&lt;/p&gt;
&lt;p&gt;I consider myself to be very intense and passionate about what I do, so I was worried about spamming too
much, talking too much, etc. Those are things I tend to do when I&amp;rsquo;m nervous. I liked that they had
no problems with it. (Also, my idea brainstorms at 3am have been for the good.)&lt;/p&gt;
&lt;p&gt;I also want to be thankful to Tian Yuchen, another GSoC contributor this summer along with me at
Git. He&amp;rsquo;s been someone I&amp;rsquo;ve talked to a lot throughout this summer and I&amp;rsquo;m sad that I won&amp;rsquo;t be
seeing him at the Git Merge this year, maybe one day.&lt;/p&gt;
&lt;p&gt;I also want to thank everyone who has reviewed my work or helped in any way, and Paco, my friend who told
me about GSoC.&lt;/p&gt;</description></item><item><title>GSoC Week 11</title><link>https://pablosabater.dev/posts/week-11/</link><pubDate>Fri, 07 Aug 2026 21:08:11 +0200</pubDate><guid>https://pablosabater.dev/posts/week-11/</guid><description>&lt;p&gt;Tic Tac, Tic, Tac&amp;hellip; I am already getting emails from GSoC warning me that there
is little time left.&lt;/p&gt;
&lt;p&gt;Picking up where I left it last week, a few hours later I sent the v3 and out of
this version came some nits and a small ordering problem.&lt;/p&gt;
&lt;p&gt;The past series, the client already had &lt;code&gt;%(objecttype)&lt;/code&gt; in its list and I did this
for a simple reason, there are 4 possible cases:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the client knows it but the server does not (new client vs old server)&lt;/li&gt;
&lt;li&gt;the client does not know it but the server does (old client vs new server)&lt;/li&gt;
&lt;li&gt;both know it (everyone is new)&lt;/li&gt;
&lt;li&gt;neither knows it (unsupported capability)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From what we have been building, invented placeholders like &lt;code&gt;%(IJustInventedThis)&lt;/code&gt;
simply die(), for the placeholders that exist locally there is another behavior:
If it is not supported by the client or the server, the output of these when
expanding them will be an empty string.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;p&gt;we ask for &amp;ldquo;%(objectname) %(objectsize) %(objecttype)&amp;rdquo;
but our server does not support type.&lt;/p&gt;
&lt;p&gt;therefore our result will be:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;&amp;lt;OID&amp;gt; &amp;lt;size&amp;gt; &amp;quot;&lt;/p&gt;
&lt;p&gt;The list was designed so that even if new placeholders were added it would be
idempotent, because nothing would happen until a server did advertise that
attribute, that&amp;rsquo;s why having type in there changed no behavior at all.&lt;/p&gt;
&lt;p&gt;It was there because it was interesting for the tests, a client did not know how
to parse if a server offered type and it did not know how to ask for it either,
but it did know how to understand if a user wanted it. This way we had tested:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;unknown + unsupported, as &lt;code&gt;%(deltabase)&lt;/code&gt; is&lt;/li&gt;
&lt;li&gt;known + unsupported, as &lt;code&gt;%(objecttype)&lt;/code&gt; was (that&amp;rsquo;s why it was on the list)&lt;/li&gt;
&lt;li&gt;known + supported, as &lt;code&gt;%(objectsize)&lt;/code&gt; is&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However with the back and forth of the type series that I am taking advantage of
to leave things clean, this stopped making sense. Using &lt;code&gt;object_info&lt;/code&gt; and the list
worked because &lt;code&gt;object_info&lt;/code&gt; already had a type field, so listing type cost
nothing. Now that we dedicate an array per attribute it would mean carrying a
types array that nobody fills, so I preferred to drop it there and implement type
fully later in the series.&lt;/p&gt;
&lt;p&gt;Patches 1-5 are preparatory. They don&amp;rsquo;t change what the command does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[1/9] is a test cleanup.&lt;/li&gt;
&lt;li&gt;[2/9] fixes a possible bug in case of a malformed response.&lt;/li&gt;
&lt;li&gt;[3/9] and [4/9] refactor how the object data is stored and handled. The
why about this refactor comes from [1].&lt;/li&gt;
&lt;li&gt;[5/9] drops the last error return left in fetch_object_info().&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Patches 6-9 are the actual objecttype support:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[6/9] teaches the server to answer type.&lt;/li&gt;
&lt;li&gt;[7/9] teaches the client to parse it.&lt;/li&gt;
&lt;li&gt;[8/9] advertises the capability so the client can start asking it.&lt;/li&gt;
&lt;li&gt;[9/9] unifies the default format.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and for the v5 there will be one more preparatory patch that Jeff King made, for a
total of 10 where 6 are prep.&lt;/p&gt;
&lt;p&gt;The shape has changed quite a bit, there is no longer an allow-list that we filter
but something simpler which is having our own struct where we have flags if the
client wants X attribute of an object and these are saved in a new struct:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;struct fetch_object_info_results {
 size_t *sizes;
 enum object_type *types;
 uint8_t *unrecognized;
 size_t nr;
 unsigned wants_size:1;
 unsigned wants_type:1;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;instead of having an array of &lt;code&gt;struct object_info&lt;/code&gt; we save all our data here so we
do not have an array of &lt;code&gt;object_info&lt;/code&gt; that was not made for that.&lt;/p&gt;
&lt;p&gt;The truth is that it has been quiet and there is not much more, I will put in Jeff
King&amp;rsquo;s patch, but there is nothing for now that I have to change.&lt;/p&gt;
&lt;p&gt;I think this has been the briefest week of all (taking into account that the last
one I published on Sunday) but it has been very quiet.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Saturday edit&lt;/strong&gt;
on friday night I sent the v5 and the static test failed, while all the others
were fine, look, I usually wait for the tests to pass but I was already seeing
everything green and I assumed the rest would go the same way.&lt;/p&gt;
&lt;p&gt;However, it was not like that, strangely everything was fine except the static,
which was a bit odd to me because I thought that at least on some platform or
something it should fail too, but no, everything green except the static.&lt;/p&gt;
&lt;p&gt;The solution was easy, two forward declarations and fixed.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Outside of GSoC these weeks I have been tying up loose ends to go live in Lisbon
this year and everything is going smoothly, for now I already have all the
paperwork done, so by the first days of September I will be there already since
university starts.&lt;/p&gt;
&lt;p&gt;I also did a couple of streams programming, I like it quite a lot and I talk, but
to concentrate well I need to be in silence which is a bit counterproductive for
streaming. But well, I have to improve.&lt;/p&gt;
&lt;p&gt;I have bought a new book which is a well known one:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.oreilly.com/library/view/designing-data-intensive-applications/9781491903063/"&gt;Designing Data-Intensive Applications&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It will arrive next week.&lt;/p&gt;
&lt;p&gt;See you next week,&lt;/p&gt;
&lt;p&gt;Pablo&lt;/p&gt;
&lt;p&gt;[1] &lt;a href="https://lore.kernel.org/git/xmqqzez67yg1.fsf@gitster.g/"&gt;https://lore.kernel.org/git/xmqqzez67yg1.fsf@gitster.g/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>GSoC Week 10</title><link>https://pablosabater.dev/posts/gsoc-week-10/</link><pubDate>Sun, 02 Aug 2026 23:51:31 +0200</pubDate><guid>https://pablosabater.dev/posts/gsoc-week-10/</guid><description>
&lt;figure&gt;
 &lt;img src="https://pablosabater.dev/posts/gsoc-week-10/last-meeting_hu_ad829ad02d37db19.webp" srcset="https://pablosabater.dev/posts/gsoc-week-10/last-meeting_hu_5289ff77b2ce65e6.webp 640w, https://pablosabater.dev/posts/gsoc-week-10/last-meeting_hu_8b374c351859a4c6.webp 960w, https://pablosabater.dev/posts/gsoc-week-10/last-meeting_hu_ad829ad02d37db19.webp 1400w"
 sizes="(min-width: 1024px) 42rem, 100vw"
 width="1400" height="788"
 alt="A laptop showing a video call with the Git GSoC students and mentors, with a grey cat lying next to it" loading="eager" decoding="async"
 data-zoom="/posts/gsoc-week-10/last-meeting_hu_340f1f84650920dd.webp"&gt;
 &lt;figcaption&gt;Last group meeting&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;I&amp;rsquo;m trying out new techniques for writing, the way I&amp;rsquo;m going to write this week
consists of writing in my native language (Spanish) and then translating it, I
hope to be able to show more of my personality.&lt;/p&gt;
&lt;p&gt;This week I think has been the last of the meetings we&amp;rsquo;ve had as a group, these
group meetings we&amp;rsquo;ve had one a month, where the 4 GSoC in Git participants and
mentors get together and talk about how our projects are going.&lt;/p&gt;
&lt;p&gt;It makes me a bit sad to see that this is coming to an end and at the same time
I look back and feel that I&amp;rsquo;ve learned a lot; even though I still make basic
junior mistakes, even if I think I&amp;rsquo;m cool, at the end of the day I&amp;rsquo;m still in my
second year of my degree and I have a lot left to learn, I&amp;rsquo;m not going to become
a genius overnight &lt;em&gt;I wish&amp;hellip;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This week started off quiet, my mentors Karthik and Chandra are both tied up
each with their own things, Karthik became a father a few weeks ago and Chandra
is tied up with academic stuff. But it doesn&amp;rsquo;t worry me much, I think I&amp;rsquo;m
already &amp;ldquo;independent&amp;rdquo;, I still make mistakes, but I&amp;rsquo;m able to keep putting out
series on my own. However the mentors&amp;rsquo; work is fundamental for the rerolls to
move forward quickly and that the two of them have found time to do reviews&amp;hellip;
I&amp;rsquo;m very grateful.&lt;/p&gt;
&lt;p&gt;A few days after the v1 I got feedback and got down to work.&lt;/p&gt;
&lt;p&gt;Hey, I still have to say that the goal1 series has finally been merged and now
I&amp;rsquo;m going full throttle with the goal2 series, this series is in principle
muuuuch shorter, because all that infrastructure I needed for goal2 came in
goal1 which took an eternity to get merged, for now I&amp;rsquo;m forgetting about it but
not for long, I&amp;rsquo;ll tell you why in a bit&amp;hellip;.&lt;/p&gt;
&lt;p&gt;Well, &lt;em&gt;carrying on since I get distracted even writing on my own&lt;/em&gt;, goal 2 got
feedback and following the usual flow, I fix and send a reroll, afterwards there
were still some nits and fixes left, but it worked, however:&lt;/p&gt;
&lt;p&gt;Junio pointed out that there was something about it that didn&amp;rsquo;t work for him,
the way the data moves between the functions wasn&amp;rsquo;t correct. I was using &lt;code&gt;struct object_info&lt;/code&gt; to store what the server answers. It&amp;rsquo;s the structure that
&lt;code&gt;read_object_info()&lt;/code&gt; uses, and, well, I saw sense in it, it has size, type, OID.
But fitting isn&amp;rsquo;t the same as being the right type. The pointers of that
structure exist to tell &lt;code&gt;read_object_info()&lt;/code&gt; where to write the values; they
aren&amp;rsquo;t the place where the values stay. Since &lt;code&gt;fetch_object_info()&lt;/code&gt; doesn&amp;rsquo;t call
&lt;code&gt;read_object_info()&lt;/code&gt;, those pointers weren&amp;rsquo;t telling anyone anything, I was using
them as storage. What gave it away was having an array of &lt;code&gt;struct object_info&lt;/code&gt;,
one per object. You never need more than one, if you&amp;rsquo;re going to read N objects,
you reuse the same structure pointing it at the N-th variable on each pass of
the loop. An array of them means you&amp;rsquo;ve confused &amp;ldquo;where to write the answer&amp;rdquo;
with &amp;ldquo;the answer&amp;rdquo;. The solution is a type of its own for the results, one array
per attribute, plus one flag per attribute saying whether the server answered
it, because the server responds with the same set of attributes for all the
OIDs. That forces changing the signature of &lt;code&gt;fetch_object_info()&lt;/code&gt;, making
&lt;code&gt;parse_cmd_remote_object_info()&lt;/code&gt; copy the values into &lt;code&gt;expand_data&lt;/code&gt;, and along the
way &lt;code&gt;free_object_info_contents()&lt;/code&gt; is left without its only caller and disappears.&lt;/p&gt;
&lt;p&gt;Part of this I inherited from how the code was before I got here and I hadn&amp;rsquo;t
read criticism about that code, so with it working and me understanding it, it
seemed correct to me but when Junio mentioned it, the truth is that what I was
doing really wasn&amp;rsquo;t very correct, although I think I&amp;rsquo;d probably still fall into
the same thing if I found myself in a similar situation. BUT LET IT BE CLEAR, I
know that I&amp;rsquo;m the one who takes responsibility for the project and that it isn&amp;rsquo;t
an excuse, but it is a difficulty, and well that&amp;rsquo;s what the review is for, I&amp;rsquo;m
glad it was questioned and now I do it right.&lt;/p&gt;
&lt;p&gt;In case anyone is interested in that thread:
&lt;a href="https://lore.kernel.org/git/xmqqzez67yg1.fsf@gitster.g/#t"&gt;https://lore.kernel.org/git/xmqqzez67yg1.fsf@gitster.g/#t&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This means that I&amp;rsquo;m going to have to do a couple of prep commits to make a
struct of my own for how the information moves along the transport path up to
&lt;code&gt;fetch_object_info()&lt;/code&gt; but well, today I&amp;rsquo;ve put a few hours into it and I have a
big part of it done, a bit of frustration because if I had done it right from
the start this wouldn&amp;rsquo;t have to be in this series, but well, time to suck it up
and leave it right.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll probably have the v3 by tomorrow, but I still have to write the commits
properly and give one last look over whether I&amp;rsquo;ve done everything they asked me
for, I keep trying things like using a notebook, notion, or just remembering,
none of them quite wins me over but well, I have to organize myself somehow.&lt;/p&gt;
&lt;p&gt;Since it&amp;rsquo;s coming to an end I&amp;rsquo;ve been thinking about whether to sign up for some
internship or something more afterwards but I don&amp;rsquo;t know how I&amp;rsquo;m going to manage
university life (partying, yes, I love going out), programming which is what I
usually do in my free time and having to go to university. For now, I don&amp;rsquo;t
think I&amp;rsquo;ll apply to any internship until I know I can juggle things, but, stop
programming? nah, that for sure not.&lt;/p&gt;
&lt;p&gt;I hope that for next week&amp;rsquo;s post I can say that v3 is looking good and is
almost finished, there are approximately 2 weeks left and I trust that I can
finish in time.&lt;/p&gt;
&lt;p&gt;See you next week,
Pablo&lt;/p&gt;</description></item><item><title>GSoC Week 9</title><link>https://pablosabater.dev/posts/gsoc-week-9/</link><pubDate>Fri, 24 Jul 2026 13:09:11 +0200</pubDate><guid>https://pablosabater.dev/posts/gsoc-week-9/</guid><description>&lt;p&gt;This last week has probably been the one with the least work to do from all the
GSoC period.&lt;/p&gt;
&lt;p&gt;Last post I had sent v20 and thought that would be it, two tiny nits appeared
but nothing &amp;ldquo;relevant&amp;rdquo;. This week has been waiting for any other review or
further issues with the series, but seems that&amp;rsquo;s it.&lt;/p&gt;
&lt;p&gt;But if something I&amp;rsquo;ve learned is that there can always be something else.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Let&amp;rsquo;s hope that there&amp;rsquo;s not&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;While it seems that there&amp;rsquo;s nothing else, v21 is already sent. Maybe this week
will be &lt;em&gt;THE WEEK&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;To have things prepared, I have the second series updated to v21 so as soon as
I have green light, I&amp;rsquo;ll send the goal2 series.&lt;/p&gt;
&lt;p&gt;I have a lot of ideas to keep working on things (on Git outside of GSoC)&amp;hellip;
For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;there are optimizations to the server-side that would be its own series.&lt;/li&gt;
&lt;li&gt;I have my already started work with a &lt;code&gt;--dry-run&lt;/code&gt; option for &lt;code&gt;git backfill&lt;/code&gt; which
I&amp;rsquo;m kinda gatekeeping because I don&amp;rsquo;t want to affect the ongoing of the
GSoC project series.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But be sure that there will be an &lt;code&gt;[RFC PATCH]&lt;/code&gt; sooner or later about
the &lt;code&gt;dry-run&lt;/code&gt; option haha.&lt;/p&gt;
&lt;p&gt;I reviewed a few patches this week while waiting, and I still have to check out Siddharth&amp;rsquo;s
series, but for that I want contiguous time to understand things, as I did with
Yuchen&amp;rsquo;s series.&lt;/p&gt;
&lt;p&gt;Other than that, this week has been brief. I&amp;rsquo;m really liking the experience and
definitely I&amp;rsquo;ll keep contributing after GSoC.&lt;/p&gt;
&lt;p&gt;I bought a book:&lt;/p&gt;

&lt;figure&gt;
 &lt;img src="https://pablosabater.dev/posts/gsoc-week-9/a-philosophy-of-software-design_hu_3076b9bb3422481.webp" srcset="https://pablosabater.dev/posts/gsoc-week-9/a-philosophy-of-software-design_hu_dd7e713c5964894f.webp 640w, https://pablosabater.dev/posts/gsoc-week-9/a-philosophy-of-software-design_hu_3076b9bb3422481.webp 960w"
 sizes="(min-width: 1024px) 26rem, 100vw"
 width="960" height="1280"
 alt="Cover of the book A Philosophy of Software Design by John Ousterhout on a wooden table" loading="eager" decoding="async" class="portrait"
 data-zoom="/posts/gsoc-week-9/a-philosophy-of-software-design_hu_3076b9bb3422481.webp"&gt;
 &lt;figcaption&gt;A Philosophy of Software Design&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;For now I&amp;rsquo;m liking it, it would have been good to have read it before GSoC&amp;hellip; haha
but nice book, I recommend it.&lt;/p&gt;
&lt;p&gt;I have on my wanna-read list: Designing Data-Intensive Applications.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m building the habit of reading to avoid doomscrolling hours and it seems that it
works.&lt;/p&gt;
&lt;p&gt;Yuchen recommended a game called Turing Complete that looks cool, I&amp;rsquo;ll try it.
I think it&amp;rsquo;s about building your own CPU starting from NAND gates.&lt;/p&gt;
&lt;p&gt;One of my dream projects is to build physically my own CPU, designing its
own ISA and then an assembler for it.&lt;/p&gt;
&lt;p&gt;I have been talking with Yuchen these last weeks, sad he lives sooooo far, but I hope
to keep talking with him after GSoC, same for Chandra and Karthik, my mentors :).&lt;/p&gt;
&lt;p&gt;I think I&amp;rsquo;ve met cool people throughout this summer.&lt;/p&gt;</description></item><item><title>GSoC Weeks 7 and 8</title><link>https://pablosabater.dev/posts/gsoc-week-half-7-and-8/</link><pubDate>Thu, 16 Jul 2026 00:20:57 +0200</pubDate><guid>https://pablosabater.dev/posts/gsoc-week-half-7-and-8/</guid><description>&lt;p&gt;This past week and a half has been exhausting; I still don&amp;rsquo;t have the Goal1
series merged into &lt;code&gt;next&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This weekend, I had both my graph and Goal1 series pushed to the mailing list,
and since the list is less active on weekends, I had some spare time.&lt;/p&gt;
&lt;p&gt;I had been meaning to review
&lt;a href="https://lore.kernel.org/git/20260714032525.1611141-1-cat@malon.dev/"&gt;Tian&amp;rsquo;s series&lt;/a&gt;
from a while ago, but I hadn&amp;rsquo;t found the time to do it properly. This weekend
was finally the time.&lt;/p&gt;
&lt;p&gt;I wanted to do a thorough review, but until now, I had never reviewed further
than just reading the code, maybe pulling it locally, and testing on the tip of
the series. This time, I wanted to review it commit by commit.&lt;/p&gt;
&lt;p&gt;My first (and not very clever) thought was to run &lt;code&gt;git rebase -i $base&lt;/code&gt; and mark
everything as &lt;code&gt;edit&lt;/code&gt;. But that sounded very impractical, and having to type
&lt;code&gt;edit&lt;/code&gt; manually&amp;hellip; No, it couldn&amp;rsquo;t be that.&lt;/p&gt;
&lt;p&gt;What I ended up doing was running &lt;code&gt;git switch --detach &amp;lt;commit&amp;gt;&lt;/code&gt;. This way, I
could break and mess around with Tian&amp;rsquo;s commits as much as I wanted to get to
the bottom of everything.&lt;/p&gt;
&lt;p&gt;The experience&amp;hellip; was tricky. I think it&amp;rsquo;s a very intricate topic where you must
be very careful about what you&amp;rsquo;re doing. I originally meant to spend just one
evening on it, but I ended up needing the next morning as well.&lt;/p&gt;
&lt;p&gt;I really enjoyed that, now that I feel much more comfortable with the Git
codebase, I can actually do deep reviews. It&amp;rsquo;s something I like because I get to
see how others code, and I always end up learning new stuff.&lt;/p&gt;
&lt;p&gt;After the weekend, some more nits landed on the graph series, but other than
that, the series seems to be done. I hope to see a &amp;ldquo;Will merge to next&amp;rdquo; at next
&lt;strong&gt;What&amp;rsquo;s cooking on Git&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You can check out the graph series here:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://lore.kernel.org/git/20260714-ps-pre-commit-indent-v12-0-d50938e006df@gmail.com/"&gt;graph series&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We went from one commit to seven, but I&amp;rsquo;m very proud of how the final result
turned out.&lt;/p&gt;
&lt;p&gt;The rest of the week was dedicated mainly to two series:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;I &amp;ldquo;finished&amp;rdquo; the &lt;code&gt;git backfill --dry-run&lt;/code&gt; option series (it&amp;rsquo;s on GitHub).
There might still be some edge cases, and some of the code is rough, but it
is RFC material—which is exactly what I wanted. The happy path works, along
with some edge cases that I caught while testing.
&lt;a href="https://github.com/pabloosabaterr/git/pull/7/changes"&gt;github series&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The rest of my effort and the main focus this week, has been fast-tracking
Goal1 to try and finish it once and for all.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m a bit worried about time; there&amp;rsquo;s only one month left, and this series is
blocking Goal2, which has been sitting on my GitHub for many weeks. I&amp;rsquo;m a bit
frustrated about that, though I can&amp;rsquo;t say it&amp;rsquo;s unfair because the feedback
I&amp;rsquo;m getting is spot-on regarding things I actually need to fix.&lt;/p&gt;
&lt;p&gt;Anyway, it does what it&amp;rsquo;s supposed to do. The remaining things to cover are
just nits, making the protocol less ambiguous and not overly trusting.&lt;/p&gt;
&lt;p&gt;In the last version, Junio suggested there should be a cheap way of requesting
a bare OID so we could have an existence test, if you want to know if there&amp;rsquo;s
an object on the remote, you could just send a bare OID.&lt;/p&gt;
&lt;p&gt;However, the server side wasn&amp;rsquo;t ready for this. it was designed to always
work with at least one requested attribute (&amp;ldquo;size&amp;rdquo; in this case). Because of
that, I had to add a new patch to get the server side behaving how we want.
Now the series is a mix of server-side and client-side changes, sadly.&lt;/p&gt;
&lt;p&gt;As of today, I spent the whole
day (and by whole day, I mean &lt;em&gt;the whole day&lt;/em&gt;, haha) reviewing and cleaning up
the Goal1 series so the next reroll can (hopefully!) be the last. I&amp;rsquo;m almost
done, but I still have to finish the last two commits of the series. That
will definitely be a task for tomorrow because today I&amp;rsquo;m so f* tired. After
that, I&amp;rsquo;m really confident it will be ready or &lt;em&gt;como muchísimo&lt;/em&gt; (exagerated
&amp;ldquo;at most&amp;rdquo;), just some tiny nits.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This morning while I was coding, I&amp;rsquo;ve been in a voice channel on the Git
Discord server talking with whoever wanted to join. Tian and Siddharth joined :).&lt;/p&gt;
&lt;p&gt;To sum up, this week has been tough, I&amp;rsquo;ve been coding non-stop, but I think it
will all be worth it.&lt;/p&gt;
&lt;p&gt;See you next Thursday,
Pablo&lt;/p&gt;</description></item><item><title>GSoC Week 6 and Half 7</title><link>https://pablosabater.dev/posts/gsoc-week-6-and-half-7/</link><pubDate>Fri, 10 Jul 2026 23:49:31 +0200</pubDate><guid>https://pablosabater.dev/posts/gsoc-week-6-and-half-7/</guid><description>&lt;p&gt;This week I was at a campsite for a few days, but that doesn&amp;rsquo;t mean that I stopped :).&lt;/p&gt;

&lt;figure&gt;
 &lt;img src="https://pablosabater.dev/posts/gsoc-week-6-and-half-7/campsite_hu_2c9f0784ac656653.webp" srcset="https://pablosabater.dev/posts/gsoc-week-6-and-half-7/campsite_hu_83aa18fea8cb984a.webp 640w, https://pablosabater.dev/posts/gsoc-week-6-and-half-7/campsite_hu_79cf3b23ffca1651.webp 960w, https://pablosabater.dev/posts/gsoc-week-6-and-half-7/campsite_hu_2c9f0784ac656653.webp 1400w"
 sizes="(min-width: 1024px) 42rem, 100vw"
 width="1400" height="840"
 alt="Pablo working on a laptop at a campsite" loading="eager" decoding="async"
 data-zoom="/posts/gsoc-week-6-and-half-7/campsite_hu_9bb0fef47e16f1d2.webp"&gt;
 &lt;figcaption&gt;Me coding at a campsite&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;It is already the &lt;em&gt;mid term evaluation&lt;/em&gt;, this means that we are half done with
the project time.&lt;/p&gt;
&lt;p&gt;I strongly think that I will be able to finish the whole project on time and
even have some extra time to work on an idea I have related to my GSoC
project&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m waiting for the Goal 1 series which is finishing the end to end of the
object-info protocol and the %(objectsize) placeholder. Once this series is
at least on &amp;ldquo;next&amp;rdquo; I will send the next one which is the %(objecttype)
support. This series will have a much more fast pace because it is muuuuch
smaller than the Goal 1 series.&lt;/p&gt;
&lt;h2 id="objecttype-support-series"&gt;%(objecttype) support series&lt;a class="anchor" href="#objecttype-support-series" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Because the object-info protocol infrastructure is already built from the Goal
1 series this only has to focus on gathering the type and parsing it.&lt;/p&gt;
&lt;p&gt;If you want to compare Goal 2 series is &lt;em&gt;~150&lt;/em&gt; lines vs the &lt;em&gt;~1000&lt;/em&gt; lines of
the Goal 1 series.&lt;/p&gt;
&lt;p&gt;at &lt;code&gt;protocol-caps.c&lt;/code&gt; only size was supported and to get the size, &lt;code&gt;odb_read_object_info()&lt;/code&gt;
is called and size gets filled through a pointer, but the return type was actually the
type.&lt;/p&gt;
&lt;p&gt;We can also know through the type if the object is not recognized by the server in case
of the type being &amp;lt;0.&lt;/p&gt;

&lt;div class="codeblock"&gt;
 &lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;strbuf_addstr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;send_buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;oid_str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;object_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;odb_read_object_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;oid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;object_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;failed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;object_type&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;strbuf_addch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;send_buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sc"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;goto&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;strbuf_addf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;send_buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; %&amp;#34;&lt;/span&gt;&lt;span class="n"&gt;PRIuMAX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uintmax_t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;object_size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nf"&gt;strbuf_addf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;send_buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; %s&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;type_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object_type&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;p&gt;After that we just need to append to the buffer the type if it was asked. This was
a very trivial change. The overhead is barely anything but at most 6 extra bytes
from the &amp;ldquo;commit&amp;rdquo; string appended to the buffer.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why I think that the hard part of the project is not actually the coding
but rather knowing what everything around it means.&lt;/p&gt;
&lt;p&gt;At the project description it was explicitly said to be cautious about the backward
compatibility and I thought of four different cases:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The server doesn&amp;rsquo;t support type (updated client but old server):&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;After we get the server capabilities, the client sees that&amp;rsquo;s type is not
advertised, filters out type from the request if it was asked by the client
and returns an empty string where the type would be.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The server supports type but the client doesn&amp;rsquo;t (updated server but old client):&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The client would get the server capabilities where type will show, I chose
to let the client know type for testing purposes on the Goal 1 but the client
doesn&amp;rsquo;t know how to parse the type capability.&lt;/p&gt;
&lt;p&gt;So as far as the client knows type is never advertised and will only ask for
what it knows. What it doesn&amp;rsquo;t know results in an empty string.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Both support type (everyone is updated)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Everything works as expected, the client asks for the type the server supports it
and sends it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Both support type but a middleware strips type:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This might happen but it will become case 1. or 2. depending of which side
is affected by the middleware:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In case of affecting the client, the client can&amp;rsquo;t ask for type and the
server won&amp;rsquo;t get the type request.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In case of affecting the server, the client never gets the type capability
advertised and the client never asks for it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What makes the client-server object-info protocol robust is that is negotiation
based, the server advertises and the client always adapts to what the server
can provide, no one assumes anything.&lt;/p&gt;
&lt;p&gt;After this series, we need to discuss the need of supporting more placeholders
like %(deltabase), %(size:disk), %(objectmode)&amp;hellip; These options, delta and disk
size, I think that they are not useful to be supported&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;why?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Because the delta or the disk size that you retrieve from the server are not
reliably the exact same that once fetched onto your local.
others like %(objectmode) need Tree context which is not even thought of yet
for the object-info protocol.&lt;/p&gt;
&lt;p&gt;The only intrinsic metadata that doesn&amp;rsquo;t change once fetched is size and type.
That&amp;rsquo;s because size and type are object properties while delta and disk size
depend on the way they are packed or your local objects.&lt;/p&gt;
&lt;p&gt;Implementing their support is not hard, is just the same as type, but the hard
part is to justify their support and usefulness.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;However I have not only worked on the GSoC project during these six and a half
weeks I have another series active and I have started with a sketch for my
idea after the project.&lt;/p&gt;
&lt;h2 id="graph-indentation-series"&gt;Graph indentation series&lt;a class="anchor" href="#graph-indentation-series" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This series comes from the bonding period it ended up being messier than
what I initially thought that it would be but now is close to be done.&lt;/p&gt;
&lt;p&gt;Before this series graphs had a warning: &amp;ldquo;vertically adjacent commits DO NOT
mean that they are related&amp;rdquo; and now after it this rule makes it that vertically
adjacent commits are always related.&lt;/p&gt;
&lt;p&gt;Because we are talking about graphs, some visual examples will help:&lt;/p&gt;

&lt;div class="codeblock plain"&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt;* A
* A
 \
 * A
* B
* B&lt;/code&gt;&lt;/pre&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;p&gt;A and B are two unrelated branches that would be rendered in the same column,
this has the problem that you would be confused to know if A and B are related
if you saw them like:&lt;/p&gt;

&lt;div class="codeblock plain"&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt;* A
* B&lt;/code&gt;&lt;/pre&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;p&gt;Now the last commit of a branch that it is a visual root, that means, that it is
an actual root or a commit that looks like a root (have its parents filtered out)
will be indented to remove the ambiguous graph.&lt;/p&gt;

&lt;div class="codeblock plain"&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt; * A
* B&lt;/code&gt;&lt;/pre&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;p&gt;A bigger example could be with two unrelated branches with merges:&lt;/p&gt;

&lt;div class="codeblock plain"&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt;* C
|\
| * D
| * D
|/
 \
 * C &amp;lt;- indented
* A
|\
| * B
| * B
|/
* A&lt;/code&gt;&lt;/pre&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;p&gt;This series has become tricky because there are a lot of edge cases to care about.&lt;/p&gt;
&lt;h2 id="extending-other-commands-with-object-info-protocol"&gt;Extending other commands with object-info protocol&lt;a class="anchor" href="#extending-other-commands-with-object-info-protocol" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now that after Goal 1 we will have the infrastructure for making object-info
requests from the client many commands could make use of it. For example
what I thought is &lt;code&gt;git backfill&lt;/code&gt;, I&amp;rsquo;m not a git backfill user, the biggest
project I&amp;rsquo;ve coded at is Git, but I believe that if you use &lt;code&gt;git backfill&lt;/code&gt; is
because you work at something massive and you care about the size and you may
be interested in an option to preview what will happen after backfilling:&lt;/p&gt;
&lt;p&gt;I want to add a &lt;code&gt;git backfill --dry-run&lt;/code&gt; option for that purpose.&lt;/p&gt;
&lt;p&gt;To make it output how many objects will be fetched is easily done because the number
is already known by the current infrastructure, we just need to make the path
where we avoid fetching and we print the preview.&lt;/p&gt;
&lt;p&gt;The interesting part is mixing it with object-info to know the total size of those
objects. Sadly the total size may not be the actual size once fetched because of the
deltas and disk size that depends on your local but it works as a limit, we can be sure
that it will not be more than the total size.&lt;/p&gt;
&lt;p&gt;To make this possible some of the logic of the transport setup needs to be extracted
from &amp;lsquo;cat-file.c&amp;rsquo; &lt;code&gt;get_remote_info()&lt;/code&gt; so other commands can reuse it.&lt;/p&gt;
&lt;p&gt;Some things that I should care of but I don&amp;rsquo;t really know how to take care of them
is:&lt;/p&gt;
&lt;p&gt;For &lt;code&gt;remote-object-info&lt;/code&gt; the maximum number of OIDs to be sent in a single request is
10k this was previously chosen before I got into the &lt;code&gt;remote-object-info&lt;/code&gt; series but
should we respect this? given that &lt;code&gt;git backfill&lt;/code&gt; nature is to be used in massive
repositories is 10k enough to not become dozens if not hundreds of requests?&lt;/p&gt;
&lt;p&gt;After adding the &amp;ndash;dry-run option it will look similar to:&lt;/p&gt;

&lt;div class="codeblock plain"&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt;$ git backfill --dry-run
After backfill X objects would be fetched (Y total size)&lt;/code&gt;&lt;/pre&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;p&gt;These are the four series I&amp;rsquo;m working on currently. I wanna try &lt;code&gt;git worktree&lt;/code&gt;
to be more chill about swapping between them but I haven&amp;rsquo;t done it yet.&lt;/p&gt;
&lt;p&gt;I usually work at one, then push it to run CI tests, work for an hour on another branch
or so while the tests run and then come back. I can sometimes be forgetful or get
distracted easily so I bought a small notebook to take notes for when I get back
to it.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I think that the work left to do for the remaining GSoC time is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For Goal 1 series:&lt;/p&gt;
&lt;p&gt;Send rerolls faster because I think it&amp;rsquo;s close to be done and this series is
gatekeeping the %(objecttype) support series and the backfill &amp;ndash;dry-run series
because they both depend on the object-info infrastructure.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For %(objecttype) support series:&lt;/p&gt;
&lt;p&gt;I think this one is very simple there&amp;rsquo;s not much else to do but once at
the mailing list I&amp;rsquo;m sure that there will be something to discuss.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For the graph indentation series:&lt;/p&gt;
&lt;p&gt;Same as Goal 1 series, it is close to be done, keep making fast rerolls and
addressing the feedback quickly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For the backfill &amp;ndash;dry-run series:&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t finished this series yet, I have only up to printing the number of
objects that will be fetched and extracted the transport logic but it lacks
the integration with object-info to retrieve the total size.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See you next Thursday 16th :)).&lt;/p&gt;</description></item><item><title>GSoC Week 4 &amp; 5 Coding Period</title><link>https://pablosabater.dev/posts/gsoc-week-4-and-5-coding-period/</link><pubDate>Wed, 01 Jul 2026 14:34:54 +0200</pubDate><guid>https://pablosabater.dev/posts/gsoc-week-4-and-5-coding-period/</guid><description>&lt;p&gt;The first part of the project which consisted of finishing what Eric Ju
started, adding &lt;code&gt;remote-object-info&lt;/code&gt; to &lt;code&gt;--batch-command&lt;/code&gt; on &lt;code&gt;git cat-file&lt;/code&gt;.
We started with a v11 and we are at a v15 currently, where things are actually
working.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s close to midterm so let&amp;rsquo;s do a quick summary of how this first part works:&lt;/p&gt;
&lt;h2 id="what-does-remote-object-info-do"&gt;What does &lt;code&gt;remote-object-info&lt;/code&gt; do?&lt;a class="anchor" href="#what-does-remote-object-info-do" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Sometimes you want to know metadata about an object but you do not like having
to download them. The server support for object-info was already merged in 2021
with the &lt;code&gt;object-info&lt;/code&gt; capability in v2 protocol but there is no client-side
implementation currently.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s where we come in with our new &lt;code&gt;remote-object-info&lt;/code&gt;, this new command will
let you query remotes for object info, similar to what you can do locally with
&lt;code&gt;info&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The way you would do this is:&lt;/p&gt;

&lt;div class="codeblock plain"&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt;$ git cat-file --batch-command=&amp;#34;%(objectname) %(objectsize)&amp;#34;
 remote-object-info &amp;#34;https://example.com/repo&amp;#34; &amp;lt;oid&amp;gt;&lt;/code&gt;&lt;/pre&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;h2 id="where-did-i-start-and-what-has-been-done"&gt;Where did I start and what has been done&lt;a class="anchor" href="#where-did-i-start-and-what-has-been-done" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Eric and Calvin made the foundation: the transport, the plumbing, the protocol
handshake, etc. Their work covered most of the end to end for the client side
and &lt;code&gt;%(objectsize)&lt;/code&gt; atom.&lt;/p&gt;
&lt;p&gt;However there were things to work at before calling it a day:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Segfault on uninitialized data. Atoms like &lt;code&gt;%(objecttype)&lt;/code&gt; were recognized by
&lt;code&gt;expand_atom()&lt;/code&gt; but the remote never gave data for them.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Local queries were being blocked. Unknown atoms returned with 0 and died
killing the whole process even if other commands like &lt;code&gt;info&lt;/code&gt; could handle
those placeholders.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My first fix (talked about in previous posts) was to add a static allow-list.
A hardcoded array of supported atoms, so when we were in &amp;ldquo;remote&amp;rdquo; mode we
would check this list, unsupported atoms return 1 with an empty string.&lt;/p&gt;
&lt;p&gt;But as we talked about this hardcoded solution didn&amp;rsquo;t quite complete the job
as good as I wanted. It works today because the only option is a server
supporting object-info with size or it doesn&amp;rsquo;t support it at all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;But what about the future?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We need to think about cases like a server with a version that supports size
and a version that supports size + more metadata. Then how do we handle these?
we need to support up to what the newest server supports but if we allow the
client to request metadata that it does not support we end up failing.&lt;/p&gt;
&lt;p&gt;What I needed for the solution was already there, on the handshake, the server
tells us already the metadata that object-info supports. Knowing this we
jump to the last commit of the series:&lt;/p&gt;
&lt;p&gt;Making the allow-list dynamic.&lt;/p&gt;
&lt;p&gt;Knowing what the server supports, we filter what the client asks to only
request to the server what it supports. If we end up having nothing to
request we can completely skip requesting the server.&lt;/p&gt;
&lt;h2 id="what-do-we-have-to-do-to-support-objecttype"&gt;What do we have to do to support %(objecttype)?&lt;a class="anchor" href="#what-do-we-have-to-do-to-support-objecttype" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The process after the allow-list has become very trivial, we need to teach
the server how to get the metadata that it needs, how to advertise it and
for the client, teach it how to parse the server response and add our new
atom to the allow-list.&lt;/p&gt;
&lt;h2 id="how-will-the-object-info-protocol-look"&gt;How will the object-info protocol look?&lt;a class="anchor" href="#how-will-the-object-info-protocol-look" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For the more formal guys this is how I plan to leave the object-info
protocol:&lt;/p&gt;
&lt;p&gt;The response of object-info is a list of the requested object ids and associated requested information, each separated by a single space.&lt;/p&gt;

&lt;div class="codeblock plain"&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt;output = info flush-pkt

info = PKT-LINE(attrs LF)
 *PKT-LINE(obj-info LF)

attrs = attr | attrs SP attrs

obj-type = &amp;#34;blob&amp;#34; | &amp;#34;tree&amp;#34; | &amp;#34;commit&amp;#34; | &amp;#34;tag&amp;#34;

obj-size = 1*DIGIT

obj-val = obj-size | obj-type

attr = &amp;#34;size&amp;#34; | &amp;#34;type&amp;#34;

obj-info = obj-id SP [obj-val *(SP obj-val)]&lt;/code&gt;&lt;/pre&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;p&gt;If the server does not recognize the object id, the response will be obj-id SP
regardless of the number of attributes requested.&lt;/p&gt;
&lt;h2 id="what-ive-learned"&gt;What I&amp;rsquo;ve learned&lt;a class="anchor" href="#what-ive-learned" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Well, when I started all my code was a solo-job this means I used the PRs
because I knew it was the &amp;ldquo;correct&amp;rdquo; way and I felt cool like &amp;ldquo;oh wow, this
looks like a real job&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Working with Karthik and Chandra has taught me a lot, &lt;strong&gt;consistency matters
a lot&lt;/strong&gt; and have I said that &lt;strong&gt;consistency matters a lot&lt;/strong&gt;?
Most of my doubts were answered with:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;What do other relevant areas do?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I learned to read code and understand it faster, working solo, (unless you
turbo vibe code things) you know all the codebase, so having to work on an already
started series has made me read code that I didn&amp;rsquo;t write nor I was familiar with,
and that&amp;rsquo;s without talking about that I had to bring this series up to master
dealing with conflicts.&lt;/p&gt;
&lt;p&gt;These are things that were new to me.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve had to &amp;ldquo;learn&amp;rdquo; how to investigate about how the things I&amp;rsquo;m dealing with
work, read others&amp;rsquo; series to understand their changes and how they
affect my series.&lt;/p&gt;
&lt;p&gt;Now I think that if I had to start over again, it wouldn&amp;rsquo;t take me as long as it
took me on the first time.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m still &amp;ldquo;wow&amp;rdquo; with how others on the mailing list are able to review and
understand code as fast as they do, that makes me want to improve to get to their
level.&lt;/p&gt;
&lt;h2 id="what-will-come-next"&gt;What will come next?&lt;a class="anchor" href="#what-will-come-next" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I think everything&amp;rsquo;s going as the timeline expects. Hopefully the first part gets
the OK this v15, maybe a v16 because of some nits, but it&amp;rsquo;s close to being &amp;ldquo;done&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;After that the next series is the end to end &lt;code&gt;%(objecttype)&lt;/code&gt; support which after
the first series which is big, this second one is far smaller.&lt;/p&gt;
&lt;p&gt;If there is time to do more we would need to discuss some things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Are more atoms like &lt;code&gt;%(size:disk)&lt;/code&gt; worth implementing? I&amp;rsquo;m not saying that
implementing them is challenging, it&amp;rsquo;s the exact same process as the one
done for &lt;code&gt;%(objecttype)&lt;/code&gt;. But other atoms and their metadata are server-intrinsic,
What I mean is that it is metadata that once fetched it will change,
differently from name, size and type the rest of them are not guaranteed to
be the same after being fetched.
If the motivation is to check before fetching for example, why would we
want to check something that will become meaningless.
I&amp;rsquo;m just not sure about them.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Firstly, I&amp;rsquo;m not a &lt;code&gt;git backfill&lt;/code&gt; user but I saw a series about it some
months ago and thought that this &lt;code&gt;object-info&lt;/code&gt; infrastructure that we are
building here could be used for a &lt;code&gt;git backfill &amp;lt;path&amp;gt; --dry-run&lt;/code&gt; option.
It would work similarly but instead of fetching the missing blobs it would
tell you how much space it would take and how many blobs would be fetched:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="codeblock plain"&gt;
 &lt;pre tabindex="0"&gt;&lt;code&gt;$ git backfill src/ --dry-run
 backfilling src/ would take 47 MiB and would fetch 50 blobs&lt;/code&gt;&lt;/pre&gt;
 &lt;button class="copy" type="button" aria-label="Copy code" hidden&gt;Copy&lt;/button&gt;
&lt;/div&gt;&lt;h2 id="apart-from-gsoc"&gt;Apart from GSoC&lt;a class="anchor" href="#apart-from-gsoc" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I still feel a bit intimidated by the mailing list, even if I now like it, I still
feel that what I send needs to be serious and perfect (even though I make the
most stupid mistakes like failing to remove cc from trailers)&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been talking with Yuchen, another GSoC at Git contributor and he&amp;rsquo;s very
nice. &lt;em&gt;Now I can send him CS memes&lt;/em&gt; ;)).&lt;/p&gt;
&lt;p&gt;We talked about our GSoC projects and a project I have which is a search
engine for git&amp;rsquo;s commits using singular value decomposition. I have to study
some more linear algebra to implement the known optimizations but I like the
idea where it is going.&lt;/p&gt;
&lt;p&gt;I also want to see Siddhart and Jayatheerth at Lisboa where Git Merge will
be held.&lt;/p&gt;
&lt;p&gt;These last weeks I&amp;rsquo;ve been busy with the paperwork of Erasmus because my next
year I&amp;rsquo;ll be studying abroad at Lisboa for a whole year.&lt;/p&gt;
&lt;p&gt;I also want to start grinding LeetCodes to get better at DSA.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Well, see you next week with more about my GSoC journey. As always any idea,
feedback or opinion is always welcome.&lt;/p&gt;</description></item><item><title>GSoC Week 2 First Feedback Round</title><link>https://pablosabater.dev/posts/gsoc-week-2-coding-period/</link><pubDate>Tue, 09 Jun 2026 20:07:19 +0200</pubDate><guid>https://pablosabater.dev/posts/gsoc-week-2-coding-period/</guid><description>&lt;p&gt;This week I finally sent what I consider my first version to the mailing
list, well technically it&amp;rsquo;s &lt;strong&gt;v12&lt;/strong&gt;, but it&amp;rsquo;s the first one for me.&lt;/p&gt;
&lt;h2 id="getting-to-v12"&gt;Getting to v12&lt;a class="anchor" href="#getting-to-v12" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The process was more tedious than what I expected, not because of the code itself, but
because I&amp;rsquo;m starting from someone else&amp;rsquo;s commits and it hits different
than starting from scratch. When it&amp;rsquo;s my own patch I know what to
do but here it was reading what was done and the feedback from previous versions.&lt;/p&gt;
&lt;p&gt;Karthik gave me his first private review of last week&amp;rsquo;s work and I started working
on it.
Saturday night I almost lost half my changes&amp;hellip; it wasn&amp;rsquo;t very funny at that
moment but my face after realizing I had obliterated half the rebase by mistake
must have been worth to see.&lt;/p&gt;
&lt;p&gt;At the end, starting from 8 commits we landed on 12, wanting to keep it concise and
focused on end-to-end support for &lt;code&gt;%(objectsize)&lt;/code&gt;. The commits I added are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A memory leak fix.&lt;/li&gt;
&lt;li&gt;Splitting a move + refactor into two separate commits.&lt;/li&gt;
&lt;li&gt;My two commits for the allow-list.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="what-do-we-have-now"&gt;What do we have now&lt;a class="anchor" href="#what-do-we-have-now" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If you read last week&amp;rsquo;s post, this is (very simplified) how it&amp;rsquo;s behaving now:&lt;/p&gt;

&lt;figure&gt;
 &lt;img src="https://pablosabater.dev/posts/gsoc-week-2-coding-period/size-only-server_hu_6081da751af9e22d.webp" srcset="https://pablosabater.dev/posts/gsoc-week-2-coding-period/size-only-server_hu_5d83b02aa48548a5.webp 640w, https://pablosabater.dev/posts/gsoc-week-2-coding-period/size-only-server_hu_10ad007bd884674e.webp 960w, https://pablosabater.dev/posts/gsoc-week-2-coding-period/size-only-server_hu_6081da751af9e22d.webp 1400w"
 sizes="(min-width: 1024px) 42rem, 100vw"
 width="1400" height="389"
 alt="Diagram: the user asks for size and type, the server only supports size, so the output is the size followed by an empty string" loading="eager" decoding="async"
 data-zoom="/posts/gsoc-week-2-coding-period/size-only-server_hu_37752f0167bc641e.webp"&gt;
&lt;/figure&gt;&lt;p&gt;The client asks for size and type, the server only supports size, so it returns
the size and an empty string for the unsupported placeholder.&lt;/p&gt;
&lt;h2 id="new-problems-unsupported-vs-empty-valued"&gt;New problems: unsupported vs empty-valued&lt;a class="anchor" href="#new-problems-unsupported-vs-empty-valued" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Karthik had a point: we&amp;rsquo;re building end-to-end support for
&lt;code&gt;%(objecttype)&lt;/code&gt; and &lt;code&gt;%(objectsize)&lt;/code&gt;, and the empty string behavior
works fine for both of them but &lt;em&gt;what about other placeholders?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The short answer is that is not great for all of them. &lt;code&gt;%(objectmode)&lt;/code&gt;
and &lt;code&gt;%(rest)&lt;/code&gt; can return an empty string. So now we have a conflict between:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A placeholder the server &lt;strong&gt;doesn&amp;rsquo;t support&lt;/strong&gt; -&amp;gt; returns empty string.&lt;/li&gt;
&lt;li&gt;A placeholder the server &lt;strong&gt;supports&lt;/strong&gt;, but its value &lt;strong&gt;is empty&lt;/strong&gt; -&amp;gt; returns empty string.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The empty string approach was suggested by &lt;a href="https://lore.kernel.org/git/20250313060250.GH94015@coredump.intra.peff.net/"&gt;Jeff King&lt;/a&gt; and
it honors what &lt;code&gt;for-each-ref&lt;/code&gt; does for known but inapplicable atoms, but it
seems like it might not be the right fit here, other thing that we could do is to
use a placeholder, something like &lt;code&gt;&amp;quot;???&amp;quot;&lt;/code&gt;, the placeholder needs to be noticeable and can&amp;rsquo;t
be a plausible value for any other placeholders.&lt;/p&gt;
&lt;p&gt;This first round to the mailing list comes with the empty string behavior
anyway. We thought it would be better to get more eyes on the series, but I&amp;rsquo;ve
left this open question in the cover letter &lt;a href="https://lore.kernel.org/git/20260608-ps-eric-work-rebase-v12-0-5338b766e658@gmail.com/"&gt;1&lt;/a&gt; in case someone has a better idea
or thinks that the placeholder would be better.
Hearing opinions would be great.&lt;/p&gt;
&lt;h2 id="apart-from-gsoc"&gt;Apart from GSoC&lt;a class="anchor" href="#apart-from-gsoc" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I also updated my Git this week.&lt;/p&gt;
&lt;p&gt;I like to code and make &amp;ldquo;empty&amp;rdquo; commits maybe a word or two to distinguish them
to later come and write them properly, with all this rebasing I was doing I wanted a
way to edit commits directly without having to get into the interactive rebase every time.
Turns out there&amp;rsquo;s a new command, &lt;code&gt;git history&lt;/code&gt;, that does exactly that, &lt;em&gt;how have you
guys survived without it?&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;As for the graph patch I mentioned last week, it&amp;rsquo;s almost done but I&amp;rsquo;m a bit
frustated with it, some flags affect the rendering order and makes me hard
to write the expect on tests to show what I want. And then there&amp;rsquo;s Windows&amp;hellip; some tests there
seem to just ignore my patch entirely. Oh, I love Windows so much&amp;hellip; I&amp;rsquo;ll try
to wrap it up this week.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;See you next week,&lt;/p&gt;
&lt;p&gt;Pablo.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://lore.kernel.org/git/20260608-ps-eric-work-rebase-v12-0-5338b766e658@gmail.com/"&gt;v12 cover letter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>GSoC Week 1 Coding Period</title><link>https://pablosabater.dev/posts/gsoc-week-1-coding-period/</link><pubDate>Tue, 02 Jun 2026 14:51:28 +0200</pubDate><guid>https://pablosabater.dev/posts/gsoc-week-1-coding-period/</guid><description>&lt;p&gt;I believe that being able to see something helps a lot with the comprehension
so expect a lot of schemas about what I do from now on.&lt;/p&gt;
&lt;p&gt;First, I&amp;rsquo;ll explain what this project consists of in simple terms.&lt;/p&gt;
&lt;p&gt;This project is the continuation of Eric Ju&amp;rsquo;s and Calvin Wan&amp;rsquo;s work on
&lt;code&gt;remote-object-info&lt;/code&gt; for the &lt;code&gt;cat-file&lt;/code&gt; command &lt;em&gt;plus&lt;/em&gt; extending it to support
&lt;code&gt;%(objecttype)&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="what-does-remote-object-info-do"&gt;What does &lt;code&gt;remote-object-info&lt;/code&gt; do?&lt;a class="anchor" href="#what-does-remote-object-info-do" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you use &lt;code&gt;git cat-file --batch-command&lt;/code&gt; with &lt;code&gt;info&lt;/code&gt;, it only queries locally.
If the OID doesn&amp;rsquo;t exist in your local repo it returns &lt;code&gt;&amp;lt;OID&amp;gt; missing&lt;/code&gt; and
doesn&amp;rsquo;t fetch anything. &lt;code&gt;remote-object-info&lt;/code&gt; aims to extend this to make fetching
the object metadata remotely from the server viable, without having to download
them beforehand. &lt;em&gt;Why fetch the full object when you just want its size or type?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The project goes back to 2021 with &lt;a href="https://lore.kernel.org/git/20220728230210.2952731-1-calvinwan@google.com/#t"&gt;Calvin&amp;rsquo;s protocol v2 extension&lt;/a&gt; for
&lt;code&gt;object-info&lt;/code&gt; and last year &lt;a href="https://lore.kernel.org/git/20250221190451.12536-1-eric.peijian@gmail.com/"&gt;Eric&amp;rsquo;s series&lt;/a&gt; that brings that extension up to the
client side at the &lt;code&gt;cat-file --batch-command&lt;/code&gt;. Eric&amp;rsquo;s work never got merged due
to unresolved issues. Here is where I start.&lt;/p&gt;
&lt;h2 id="what-i-did-this-week"&gt;What I did this week&lt;a class="anchor" href="#what-i-did-this-week" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Well Git is always very active and from last year until today, a lot has
happened and Eric&amp;rsquo;s series had some conflicts that needed to be resolved before
starting with the project.&lt;/p&gt;
&lt;p&gt;I had already started some days ahead of the coding period because I wanted to
resolve all the conflicts to start from day 0 coding and thinking what I have
to do.&lt;/p&gt;
&lt;p&gt;The first part of my project consists of addressing the feedback left
from Eric&amp;rsquo;s v11, mostly style, but one important part about how the unsupported
placeholders are handled.&lt;/p&gt;
&lt;h3 id="static-allow-list-for-remote-placeholders"&gt;Static allow-list for remote placeholders&lt;a class="anchor" href="#static-allow-list-for-remote-placeholders" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Eric&amp;rsquo;s code used &lt;code&gt;strstr()&lt;/code&gt; to validate the placeholders, which was not enough.
Unsupported placeholders like &lt;code&gt;%(objecttype)&lt;/code&gt; &lt;a href="https://lore.kernel.org/git/20250224234720.GC729825@coredump.intra.peff.net/"&gt;caused segfaults&lt;/a&gt; or dies directly.
The idea is to replace this with an allow-list in &lt;code&gt;expand_atom()&lt;/code&gt; that returns
an empty string for unsupported placeholders, &lt;a href="https://lore.kernel.org/git/20250313060250.GH94015@coredump.intra.peff.net/"&gt;as Jeff King suggested&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I first thought of a simple static list where the supported placeholders were.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;But this static allow-list has a problem&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The backward and future compatibility of this approach is very poor if not
non-existent.&lt;/p&gt;

&lt;figure&gt;
 &lt;img src="https://pablosabater.dev/posts/gsoc-week-1-coding-period/allow-list-failure_hu_3f45d98e0763d889.webp" srcset="https://pablosabater.dev/posts/gsoc-week-1-coding-period/allow-list-failure_hu_823be9ae3fbbcf7e.webp 640w, https://pablosabater.dev/posts/gsoc-week-1-coding-period/allow-list-failure_hu_54b65973b945751f.webp 960w, https://pablosabater.dev/posts/gsoc-week-1-coding-period/allow-list-failure_hu_3f45d98e0763d889.webp 1400w"
 sizes="(min-width: 1024px) 42rem, 100vw"
 width="1400" height="795"
 alt="Diagram: the client asks a server that only supports name and size for name, size and type; the server answers with an unexpected type error and the client dies" loading="eager" decoding="async"
 data-zoom="/posts/gsoc-week-1-coding-period/allow-list-failure_hu_668ae45d3090652a.webp"&gt;
&lt;/figure&gt;&lt;p&gt;This static approach is only reliable if the client and the server support
the same capabilities.&lt;/p&gt;
&lt;h3 id="dynamic-allow-list"&gt;Dynamic allow-list&lt;a class="anchor" href="#dynamic-allow-list" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h3&gt;

&lt;figure&gt;
 &lt;img src="https://pablosabater.dev/posts/gsoc-week-1-coding-period/client-server-negotiation_hu_78c3c4d996902b6b.webp" srcset="https://pablosabater.dev/posts/gsoc-week-1-coding-period/client-server-negotiation_hu_f05eb4db3f581db2.webp 640w, https://pablosabater.dev/posts/gsoc-week-1-coding-period/client-server-negotiation_hu_9b8fecbed1a8d5c7.webp 960w, https://pablosabater.dev/posts/gsoc-week-1-coding-period/client-server-negotiation_hu_78c3c4d996902b6b.webp 1400w"
 sizes="(min-width: 1024px) 42rem, 100vw"
 width="1400" height="614"
 alt="Diagram of the object-info negotiation: the client drops the placeholders the server does not advertise, fetches only the size and prints an empty string for the type" loading="lazy" decoding="async"
 data-zoom="/posts/gsoc-week-1-coding-period/client-server-negotiation_hu_1cc8a7cad76e06ce.webp"&gt;
&lt;/figure&gt;&lt;p&gt;We have to think about the client as an &lt;strong&gt;&amp;ldquo;all-knower&amp;rdquo;&lt;/strong&gt; it knows every
placeholder option and it can ask whatever it wants and the server as an
&lt;strong&gt;&amp;ldquo;authority&amp;rdquo;&lt;/strong&gt; that the client has to obey.&lt;/p&gt;
&lt;p&gt;So the client is the one who needs to adapt to what the server can provide
without the need of the user to know what the server advertises.&lt;/p&gt;
&lt;p&gt;This approach solves the &lt;em&gt;client vs different servers&lt;/em&gt; making servers that
only support size and future ones that support more options can be fetched
by the same client.&lt;/p&gt;
&lt;p&gt;This hasn&amp;rsquo;t been posted on the mailing list yet so it might change. But I really
think this is the right approach, though with the empty strings we now have a
problem: &lt;em&gt;known but unsupported vs empty data&lt;/em&gt;. Placeholders like &lt;code&gt;%(rest)&lt;/code&gt; and
&lt;code&gt;%(objectmode)&lt;/code&gt; can return an empty string, so, how do we differentiate unsupported
placeholders that return an empty string vs the ones which their data is
genuinely empty?
Even if these placeholders are out of the scope currently, they will be implemented
in the future so we have to think about this, as this will be the foundation for
the rest of the placeholders.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Also, I still have a pending patch about indentation of visual roots
at &lt;code&gt;git log --graph&lt;/code&gt;, which I&amp;rsquo;m giving its final tweaks with the help of my
great mentors Karthik and Chandra but I&amp;rsquo;ll keep this post focused on GSoC.&lt;/p&gt;
&lt;p&gt;I enjoy making reviews also, it&amp;rsquo;s really cool to discuss and learn, so I try to
read what is sent to the mailing list.&lt;/p&gt;
&lt;h2 id="what-to-expect"&gt;What to expect&lt;a class="anchor" href="#what-to-expect" aria-label="Link to this section"&gt;§&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;If this continues, the client could fill the allow-list to handle every
placeholder as if it was local leaving only the server side work to implement
for &lt;code&gt;%(objecttype)&lt;/code&gt; and the rest of options that will come in the future.&lt;/p&gt;
&lt;p&gt;Once we have the client side done, I&amp;rsquo;ll start with the server side to implement
&lt;code&gt;%(objecttype)&lt;/code&gt;, and who knows, if there is time I want to add more support for
more metadata.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I&amp;rsquo;m having lots of fun already and I&amp;rsquo;m very thankful to both my mentors
Karthik and Chandra who are very supportive and helpful.&lt;/p&gt;
&lt;p&gt;See you next week,&lt;/p&gt;
&lt;p&gt;Pablo.&lt;/p&gt;</description></item><item><title>GSoC Week 1 Community Bonding</title><link>https://pablosabater.dev/posts/week-1-community-bonding/</link><pubDate>Tue, 05 May 2026 15:52:13 +0200</pubDate><guid>https://pablosabater.dev/posts/week-1-community-bonding/</guid><description>&lt;p&gt;Last april 30th I started my GSoC at Git, and it&amp;rsquo;s been a few days already.
This week has been more about what I&amp;rsquo;m gonna do rather than doing, but I think
that having a clear plan will be worth.&lt;/p&gt;
&lt;p&gt;This week I had the GSoC 2026 welcome meeting, I also have scheduled meetings with
my mentors and the other three Git GSoC students. I&amp;rsquo;m excited about it :).&lt;/p&gt;
&lt;p&gt;As part of my work is rebasing previous work, I&amp;rsquo;ve been reading what is left to do,
good thing that most of what I have to do I had it already noted on my proposal.
Rebasing was harder than what I expected, but mostly because I&amp;rsquo;m not used to
having to deal with manual conflicts as most of the time I code alone, I knew
one file got deleted so I had to trace what had happened with it.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;d like to say that I&amp;rsquo;ve improved, with who I was before starting GSoC because
tracing the history was an easy part, I could say I&amp;rsquo;m liking the mailing list.
As it is community bonding I&amp;rsquo;m trying to be more active at the mailing list
rather than patches I&amp;rsquo;m trying to review other&amp;rsquo;s work with what I know.&lt;/p&gt;
&lt;p&gt;Even though it&amp;rsquo;s still community bonding, I&amp;rsquo;ve already started with the rebase
and feedback left to do. But I need to read more docs to be sure that I
understand everything and make sure I&amp;rsquo;m doing it correctly.&lt;/p&gt;</description></item><item><title>Pre GSoC</title><link>https://pablosabater.dev/posts/pre-gsoc/</link><pubDate>Sat, 02 May 2026 10:33:00 +0200</pubDate><guid>https://pablosabater.dev/posts/pre-gsoc/</guid><description>&lt;p&gt;This post might be longer than others because it summarizes ~2 months of thoughts
and the process of applying to GSoC.&lt;/p&gt;
&lt;p&gt;Around 2 months before the GSoC opening for proposals submissions a friend of mine
&lt;a href="https://www.linkedin.com/in/francisco-albacete-chicano/"&gt;Paco&lt;/a&gt; told me about GSoC
and encouraged me to apply. I&amp;rsquo;ve never heard about it before, but it sounded
&lt;strong&gt;really&lt;/strong&gt; interesting. I started looking for organizations and projects where I
could fit, I thought about &lt;a href="https://llvm.org/"&gt;Llvm&lt;/a&gt; due to my interest in
compilers sounded like a good fit, but I haven&amp;rsquo;t got into llvm as much as I&amp;rsquo;d
like to and the projects weren&amp;rsquo;t something I felt a deep interest in.&lt;/p&gt;
&lt;p&gt;Then I found Git, a few months before this I tried to start contributing to it,
it is something I wanted because it is something I use everyday and contributing
to it sounds so cool. But I didn&amp;rsquo;t because when I started looking into it, it
felt massive and overwhelming, at that time I didn&amp;rsquo;t know what a mailing list was
and the project felt intimidating.&lt;/p&gt;
&lt;p&gt;Seeing Git as a GSoC organization was a &lt;em&gt;click&lt;/em&gt; moment, I thought &amp;ndash;This is it&amp;ndash;
Git has some &lt;a href="https://git.github.io/General-Application-Information/"&gt;requirements&lt;/a&gt;
before sending a valid proposal, so I left choosing the project for later and
focused on doing the requirements.&lt;/p&gt;
&lt;p&gt;The coding itself in the microproject isn&amp;rsquo;t hard, the hard part was to know
how things work in Git, making a patch, committing with &lt;code&gt;git commit -s&lt;/code&gt; expressing
correctly the git commit message and then sending it to the mailing list, &lt;em&gt;which
looked like the hell of designers&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;First time I sent the patch multiple times to myself to make sure it was correct,
I thought &amp;ndash;These guys must be so serious, one error and I&amp;rsquo;m &lt;strong&gt;out&lt;/strong&gt;&amp;ndash; Jokes on me,
&lt;a href="https://www.linkedin.com/in/gitster/"&gt;Junio Hamano&lt;/a&gt; replied to my patch very
quickly and helped me with everything I had wrong. After that, I felt more
confident, once I got the patch accepted after a few rounds of review, I searched
for more small parts to contribute to. I wanted to show that I wanted this and
I wasn&amp;rsquo;t just a guy who does the bare minimum and then applies hoping for the
best, I wanted to show that I was really &lt;strong&gt;interested&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I made some more contributions that weren&amp;rsquo;t just updating tests and after I
felt confident I started looking at what the proposed projects for GSoC were.
I chose the last one
&lt;code&gt;Complete and extend the remote-object-info command for git cat-file&lt;/code&gt;
because it involved networking, something I had just studied at university, and I
think it&amp;rsquo;s really cool.&lt;/p&gt;
&lt;p&gt;This project was continuing work of two previous GSoC students, so I had a lot
of things to read about before writing anything. I read all the cover letters
for each version they sent noting what they&amp;rsquo;ve done in each one and for the last
one I read what was left to do (bugs, features, style, etc). Once I knew what
I was getting into, luckily, there were other proposals with feedback in the
mailing list which helped me to know how I should write the proposal and what
I should include in it. Writing the proposal took about a whole week having it as my main
priority. I wrote it a few times before liking it. I could say that the hardest
part was to write the timeline, at university you are given a deadline and that&amp;rsquo;s
it, you don&amp;rsquo;t need to think what you will do in each week and how much time will
it take. The second hardest part was the problem and solution, those parts are where you
show that you&amp;rsquo;ve understood the problem, what&amp;rsquo;s already done and what I will do.
For me, this being a continuation there was a lot of feedback about what was left
to do, so I had to understand it for my proposed solution.&lt;/p&gt;
&lt;p&gt;Sending the proposal v1 the day the application was open (16th March) was a mental
checkpoint, I believe first impressions are important and I was proud of what I
did, I got feedback for it and wrote a few versions during the application period
16th March - 30 March, while waiting for feedback about my proposal I kept contributing
to Git to become more familiar with it and to have a stronger proposal.
I didn&amp;rsquo;t just make patches, I also got involved in RFCs, made a few reviews and
helped newcomers with their microproject for GSoC as Junio helped me.&lt;/p&gt;
&lt;p&gt;After the application period, I was really proud of what my proposal was, I
believe I was a strong candidate. I must say that the nervousness was real and even
being more confident about what I can do I couldn&amp;rsquo;t get rid of the fear. I have
no words to describe it but, this fear worked for me to be motivated to give
the best of me until the results. After 30th March I had a whole month until
the results, I kept contributing to Git, and I&amp;rsquo;m still doing it as there are still
some weeks until the coding period starts. I kept up with my projects and
studying for university.&lt;/p&gt;
&lt;p&gt;30th April, &lt;strong&gt;The day had come&lt;/strong&gt;. The results weren&amp;rsquo;t out until 20:00 (Spain is
UTC+2 after the clocks change in spring). Once the results were out, and I received
the email where it said that I was accepted, I was at the gym and I probably had
the best workout of my life. I told my friends and family about it, I was
really really happy, the next day I sent an email to my mentors
&lt;a href="https://www.linkedin.com/in/karthik-nayak/"&gt;Karthik&lt;/a&gt; who works at
&lt;a href="https://www.linkedin.com/company/gitlab-com/"&gt;Gitlab&lt;/a&gt; and
&lt;a href="https://www.linkedin.com/in/chand-ra/"&gt;Chandra&lt;/a&gt; to thank them for selecting me
and asking about the next steps which brings us here writing this blog post.&lt;/p&gt;
&lt;p&gt;Summarizing, I believe that the process of applying to GSoC even if you are
not selected still teaches you a lot and it&amp;rsquo;s worth all the time you spend on
it. I think that applying to GSoC isn&amp;rsquo;t an excluding process where you need to
be an expert or the best of your university, I think it&amp;rsquo;s doable by anyone who
is interested and willing to put the effort to do it, and I&amp;rsquo;ll encourage more
of my friends to apply next year.&lt;/p&gt;</description></item><item><title>Introduction</title><link>https://pablosabater.dev/posts/introduction/</link><pubDate>Sat, 02 May 2026 09:42:53 +0200</pubDate><guid>https://pablosabater.dev/posts/introduction/</guid><description>&lt;p&gt;Hi!&lt;/p&gt;
&lt;p&gt;My name is Pablo, this is my first time blogging, so&amp;hellip; don&amp;rsquo;t expect amazing writing
skills but I&amp;rsquo;ll do my best to try to share my experience through my journey at GSoC
Git 2026 mentored by &lt;a href="https://www.linkedin.com/in/karthik-nayak/"&gt;Karthik&lt;/a&gt;
who works at &lt;a href="https://www.linkedin.com/company/gitlab-com/"&gt;Gitlab&lt;/a&gt; and
&lt;a href="https://www.linkedin.com/in/chand-ra/"&gt;Chandra&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m 19 years old and a second year Computer Science student at the University of
Murcia, Spain. I love programming and I&amp;rsquo;m really interested about compilers and
how things work under the hood. I mostly program in C but I also have experience
with Java and typescript.&lt;/p&gt;
&lt;p&gt;I started programming some years ago, close to 15 when I wanted to make a discord
bot for my friends and me.&lt;/p&gt;
&lt;p&gt;Besides programming, I love to cook and going to the gym.&lt;/p&gt;
&lt;p&gt;The last project I&amp;rsquo;m working on is a compiler for my own programming language called
&lt;a href="https://github.com/pabloosabaterr/orn-rework"&gt;Orn&lt;/a&gt;. Orn is a low level systems
programming language that brings a Typescript inspired syntax and a soft learning
curve so developers coming from high level languages can easily get into it.&lt;/p&gt;
&lt;p&gt;Orn is not finished yet, but it is close to a v1.&lt;/p&gt;</description></item></channel></rss>