Skip to content

Instantly share code, notes, and snippets.

@kkirsche
Last active August 24, 2022 13:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kkirsche/da640d34217cb70e0f79132407d14bf4 to your computer and use it in GitHub Desktop.
Save kkirsche/da640d34217cb70e0f79132407d14bf4 to your computer and use it in GitHub Desktop.
Writing Git Blob Objects
package main
import (
"bytes"
"compress/zlib"
"crypto/sha1"
"encoding/hex"
"fmt"
"io"
"os"
"path/filepath"
)
func main() {
content := "what is up, doc?"
header := fmt.Sprintf("blob %d", len(content))
store := fmt.Sprintf("%s\x00%s", header, content)
hash := sha1.New()
io.WriteString(hash, store)
digestBytes := hash.Sum(nil)
digest := hex.EncodeToString(digestBytes)
var zlibContent bytes.Buffer
writer := zlib.NewWriter(&zlibContent)
writer.Write([]byte(store))
writer.Close()
path := fmt.Sprintf(".git/objects/%s/%s", digest[0:2], digest[2:38])
os.Mkdir(filepath.Dir(path), 0644)
os.WriteFile(path, zlibContent.Bytes(), 0644)
fmt.Println(path)
fmt.Println(digest)
}
#!/usr/bin/env ts-node
const buffer = require("node:buffer");
const crypto = require("node:crypto");
const fs = require("node:fs");
const path = require("node:path");
const zlib = require("node:zlib");
const content = "what is up, doc?";
const byteSize = buffer.Buffer.byteLength(content, "utf-8");
const header = `blob ${byteSize}\0`;
const store = `${header}${content}`;
const shasum = crypto.createHash("sha1");
shasum.update(store);
const digest = shasum.digest("hex");
const zlibContent = zlib.deflateSync(store);
const gitPath = `.git/objects/${digest.slice(0, 2)}/${digest.slice(2, 28)}`;
fs.mkdirSync(path.dirname(gitPath), { recursive: true });
try {
fs.writeFileSync(gitPath, zlibContent);
} catch (e) {
console.error(`Failed to write file with error: ${e}`);
}
console.log(gitPath);
console.log(digest);
#!/usr/bin/env python
from pathlib import Path
from hashlib import sha1
from os import makedirs
from zlib import compress
# first, capture the content to store in git
content = "what is up, doc?"
byte_size = len(content.encode("utf-8"))
# create the file header used by zlib when storing git data
header = f"blob {byte_size}\0"
store = f"{header}{content}".encode("utf-8")
# create the digest of the object, so we know where to put it
digest = sha1(store, usedforsecurity=False).hexdigest()
# git compresses content with zlib
zlib_content = compress(store)
# now, let's store the data
path = Path(f".git/objects/{digest[:2]}/{digest[2:38]}")
makedirs(path.parent)
with open((path), "wb") as f:
f.write(zlib_content)
print(path)
print(digest)
require "digest/sha1"
require 'fileutils'
require 'zlib'
content = "what is up, doc?"
header = "blob #{content.bytesize}\0"
store = header + content
sha1 = Digest::SHA1.hexdigest(store)
zlib_content = Zlib::Deflate.deflate(store)
path = '.git/objects/' + sha1[0,2] + '/' + sha1[2,38]
FileUtils.mkdir_p(File.dirname(path))
File.open(path, 'w') { |f| f.write zlib_content }
puts path
puts sha1
#!/usr/bin/env sh
echo "what is up, doc?" | git hash-object --stdin -w
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment