Skip to content

Instantly share code, notes, and snippets.

@hackape
Forked from masak/explanation.md
Created January 21, 2022 03:23
Show Gist options
  • Select an option

  • Save hackape/8c4c2fa88b6623cdd0aaca1005d5496f to your computer and use it in GitHub Desktop.

Select an option

Save hackape/8c4c2fa88b6623cdd0aaca1005d5496f to your computer and use it in GitHub Desktop.

Revisions

  1. @masak masak revised this gist Oct 18, 2021. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions explanation.md
    Original file line number Diff line number Diff line change
    @@ -13,7 +13,7 @@ So that's the sha1 I want to reproduce. `d6cd1e2bd19e03a81132a23b2025920577f84e3

    When I started my investigations, I *thought* it was something like these things that went into a commit:

    $ git cat-file commit HEAD
    $ git --no-replace-objects cat-file commit HEAD
    tree 9bedf67800b2923982bdf60c89c57ce6fd2d9a1c
    parent de1eaf515ebea46dedea7b3ae0e5ebe3e1818971
    author jnthn <[email protected]> 1334500503 +0200
    @@ -31,14 +31,14 @@ That is

    But it turns out there is also a NUL-terminated header that gets appended to this, containing the word "commit", and the length in bytes of all of the above information:

    $ printf "commit %s\0" $(git cat-file commit HEAD | wc -c)
    $ printf "commit %s\0" $(git --no-replace-objects cat-file commit HEAD | wc -c)
    commit 327

    (No, you can't see the NUL byte.)

    Put this header and the rest of the information together:

    $ (printf "commit %s\0" $(git cat-file commit HEAD | wc -c); git cat-file commit HEAD)
    $ (printf "commit %s\0" $(git --no-replace-objects cat-file commit HEAD | wc -c); git cat-file commit HEAD)
    commit 327tree 9bedf67800b2923982bdf60c89c57ce6fd2d9a1c
    parent de1eaf515ebea46dedea7b3ae0e5ebe3e1818971
    author jnthn <[email protected]> 1334500503 +0200
    @@ -48,5 +48,5 @@ Put this header and the rest of the information together:

    ...and what you get hashes to the right sha1!

    $ (printf "commit %s\0" $(git cat-file commit HEAD | wc -c); git cat-file commit HEAD) | sha1sum
    $ (printf "commit %s\0" $(git --no-replace-objects cat-file commit HEAD | wc -c); git cat-file commit HEAD) | sha1sum
    d6cd1e2bd19e03a81132a23b2025920577f84e37 -
  2. Carl Mäsak created this gist Apr 18, 2012.
    52 changes: 52 additions & 0 deletions explanation.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,52 @@
    Ok, I geeked out, and this is probably more information than you need. But it *completely* answers the question. Sorry. ☺

    Locally, I'm at this commit:

    $ git show
    commit d6cd1e2bd19e03a81132a23b2025920577f84e37
    Author: jnthn <[email protected]>
    Date: Sun Apr 15 16:35:03 2012 +0200

    When I added FIRST/NEXT/LAST, it was idiomatic but not quite so fast. This makes it faster. Another little bit of masak++'s program.

    So that's the sha1 I want to reproduce. `d6cd1e2bd19e03a81132a23b2025920577f84e37`

    When I started my investigations, I *thought* it was something like these things that went into a commit:

    $ git cat-file commit HEAD
    tree 9bedf67800b2923982bdf60c89c57ce6fd2d9a1c
    parent de1eaf515ebea46dedea7b3ae0e5ebe3e1818971
    author jnthn <[email protected]> 1334500503 +0200
    committer jnthn <[email protected]> 1334500545 +0200

    When I added FIRST/NEXT/LAST, it was idiomatic but not quite so fast. This makes it faster. Another little bit of masak++'s program.

    That is

    * The source tree of the commit (which unravels to all the subtrees and blobs)
    * The parent commit sha1
    * The author info
    * The committer info (right, those are different!)
    * The commit message

    But it turns out there is also a NUL-terminated header that gets appended to this, containing the word "commit", and the length in bytes of all of the above information:

    $ printf "commit %s\0" $(git cat-file commit HEAD | wc -c)
    commit 327

    (No, you can't see the NUL byte.)

    Put this header and the rest of the information together:

    $ (printf "commit %s\0" $(git cat-file commit HEAD | wc -c); git cat-file commit HEAD)
    commit 327tree 9bedf67800b2923982bdf60c89c57ce6fd2d9a1c
    parent de1eaf515ebea46dedea7b3ae0e5ebe3e1818971
    author jnthn <[email protected]> 1334500503 +0200
    committer jnthn <[email protected]> 1334500545 +0200

    When I added FIRST/NEXT/LAST, it was idiomatic but not quite so fast. This makes it faster. Another little bit of masak++'s program.

    ...and what you get hashes to the right sha1!

    $ (printf "commit %s\0" $(git cat-file commit HEAD | wc -c); git cat-file commit HEAD) | sha1sum
    d6cd1e2bd19e03a81132a23b2025920577f84e37 -