git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [IGNORETHIS/PATCH] Choosing the sha1 prefix of your commits

From
Jeff King <peff@peff.net>
Date
Oct 19, 2011, 19:01 UTC
Message-ID
<20111019190114.GA4670@sigill.intra.peff.net>
In-Reply-To
<CACBZZX5PqYa0uWiGgs952rk2cy+QRCU95kF63qzSi3fKK-YrCQ@mail.gmail.com>
On Wed, Oct 19, 2011 at 08:03:24PM +0200, Ævar Arnfjörð Bjarmason wrote:
> This is quick hack I wrote just before leaving work to show that I
> could indeed push patches to our main repository starting with
> 31337. Names hidden to protect the innocent.
Clever and amusing.
Show 9 quoted lines
> Which in just over a minute will generate, in my case:
> 
>     $ git show --pretty=raw 313375d995e6f8b7773c6ed1ee165e5a9e15690b | head -n 7
>     commit 313375d995e6f8b7773c6ed1ee165e5a9e15690b
>     tree c9bebc99c05dfe61cccf02ebdf442945c8ff8b3c
>     parent 0dce2d45a79d26a593f0e12301cdfeb7eb23c17a
>     author Ævar Arnfjörð Bjarmason <avar@example.com> <censored> <censored>
>     committer Ævar Arnfjörð Bjarmason <avar@example.com> <censored> <censored>
>     lulz 697889
Nice header name.
Show 5 quoted lines
> I also think it's interesting that we seemingly don't have (in my
> brief search, maybe I missed it) an API for writing a complete commit
> object into a strbuf, so I had to write a lot of commit objects to
> disk, and keep unlinking the unacceptable candidates so the repository
> wouldn't balloon in size.

Calculating an object sha1 is pretty straightforward. I think you could just tack the "commit <size>" header in front of the commit strbuf, and sha1 that, and then just send the "winner" to actually be written.

Too bad it won't work in an append only way. The internal state of sha1 after a certain set of bytes is deterministic, so you could do something like:

  void leetify_object(struct strbuf *data)
  {
          SHA_CTX base, guess;
          int len = data->len;
          int i = 0;
          /* come up with a base internal state representing
           * the commit */
          SHA1_Init(&base);
          SHA1_Update(&base, data->buf, data->len);
          while (1) {
                  char append[64];
                  int n = snprintf(append, sizeof(append),
                                   "x-lulz-by: %d\n", i);
                  unsigned char sha1[20];
                  /* and then from that state, see what the sha1 would
                   * be if we add our few new bytes */
                  memcpy(&guess, &base, sizeof(guess));
                  SHA1_Update(&guess, append, n);
                  SHA1_Final(sha1, &guess);
                  /* did we pick a winner? */
                  if (sha1[0] == 0x31 &&
                      sha1[1] == 0x33 &&
                      &sha1[2] & 0xf0) == 0x70) {
                            strbuf_addstr(data, append);
                            return;
                  }
                  i++;
          }
  }
There are two problems with this:
  1. The x-lulz-by header is visible in the commit message. I think you
     can actually get around this by appending a NUL character, and "git
     log" and friends will stop processing the commit message there.
  2. The object header will actually have the length of the object at
     the beginning. So as your lulz number grows, the length of the
     object will change, and invalidate your earlier sha1. You could get
     around this by using a fixed-size guess (e.g., start with 20 bytes
     of zeroes, and then just keep incrementing).
-Peff
Previous: Ævar Arnfjörð BjarmasonNext: Jeff King
Message 2 of 24 in “Choosing the sha1 prefix of your commits”
  1. Choosing the sha1 prefix of your commitsÆvar Arnfjörð Bjarmason, Oct 19, 2011
  2. Jeff KingOct 19, 2011
  3. Jeff KingOct 19, 2011
  4. Jeff KingOct 20, 2011
  5. Kyle MoffettOct 20, 2011
  6. Jeff KingOct 20, 2011
  7. Junio C HamanoOct 20, 2011
  8. Kyle MoffettOct 20, 2011
  9. Jeff KingOct 24, 2011
  10. Junio C HamanoOct 20, 2011
  11. Jeff KingOct 20, 2011
  12. Junio C HamanoOct 20, 2011
  13. Jeff KingOct 20, 2011
  14. Ted Ts'oOct 20, 2011
  15. Jeff KingOct 20, 2011
  16. Drew NorthupOct 25, 2011
  17. Re* [IGNORETHIS/PATCH] Choosing the sha1 prefix of your commitsJunio C Hamano, Oct 20, 2011
  18. Jeff KingOct 20, 2011
  19. Nguyen Thai Ngoc DuyOct 20, 2011
  20. Nguyen Thai Ngoc DuyOct 20, 2011
  21. Jeff KingOct 20, 2011
  22. Mikael MagnussonOct 20, 2011
  23. Elijah NewrenOct 20, 2011
  24. Jonathan NiederOct 19, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.