Rename hooks to standard git hook names
- Rename post-commit-ots → post-commit - Rename pre-commit-ots → pre-commit - Remove legacy post-commit and pre-commit symlinks - Update install.sh and documentation - Simplified: only 2 hook files with standard names Hooks are now named exactly as git expects them, making manual installation more intuitive.
This commit is contained in:
parent
b4e2eb3c12
commit
948e7d9d70
8 changed files with 44 additions and 291 deletions
|
|
@ -31,8 +31,8 @@ git commit -m "Add OpenTimestamp proofs for commit history"
|
||||||
## Manual Installation
|
## Manual Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp hooks/post-commit-ots .git/hooks/post-commit
|
cp hooks/post-commit .git/hooks/post-commit
|
||||||
cp hooks/pre-commit-ots .git/hooks/pre-commit
|
cp hooks/pre-commit .git/hooks/pre-commit
|
||||||
chmod +x .git/hooks/post-commit .git/hooks/pre-commit
|
chmod +x .git/hooks/post-commit .git/hooks/pre-commit
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -45,8 +45,8 @@ chmod +x .git/hooks/post-commit .git/hooks/pre-commit
|
||||||
|
|
||||||
| File | Purpose | Version? |
|
| File | Purpose | Version? |
|
||||||
|------|---------|----------|
|
|------|---------|----------|
|
||||||
| `hooks/post-commit-ots` | Post-commit hook | Yes |
|
| `hooks/post-commit` | Post-commit hook | Yes |
|
||||||
| `hooks/pre-commit-ots` | Backfill hook | Yes |
|
| `hooks/pre-commit` | Backfill hook | Yes |
|
||||||
| `hooks/install.sh` | Installer (checks ots) | Yes |
|
| `hooks/install.sh` | Installer (checks ots) | Yes |
|
||||||
| `.ots/*.ots` | Individual proofs | Yes |
|
| `.ots/*.ots` | Individual proofs | Yes |
|
||||||
| `.ots/proof.ots` | Latest proof reference | Yes |
|
| `.ots/proof.ots` | Latest proof reference | Yes |
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ That's it! Every commit will now be timestamped and anchored to Bitcoin.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Copy hooks
|
# Copy hooks
|
||||||
cp hooks/post-commit-ots .git/hooks/post-commit
|
cp hooks/post-commit .git/hooks/post-commit
|
||||||
cp hooks/pre-commit-ots .git/hooks/pre-commit
|
cp hooks/pre-commit .git/hooks/pre-commit
|
||||||
chmod +x .git/hooks/post-commit .git/hooks/pre-commit
|
chmod +x .git/hooks/post-commit .git/hooks/pre-commit
|
||||||
|
|
||||||
# Setup .gitignore
|
# Setup .gitignore
|
||||||
|
|
|
||||||
4
SKILL.md
4
SKILL.md
|
|
@ -73,8 +73,8 @@ repo/
|
||||||
If you prefer manual setup:
|
If you prefer manual setup:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp hooks/post-commit-ots .git/hooks/post-commit
|
cp hooks/post-commit .git/hooks/post-commit
|
||||||
cp hooks/pre-commit-ots .git/hooks/pre-commit
|
cp hooks/pre-commit .git/hooks/pre-commit
|
||||||
chmod +x .git/hooks/post-commit .git/hooks/pre-commit
|
chmod +x .git/hooks/post-commit .git/hooks/pre-commit
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,9 @@ HOOKS_DIR="$(git rev-parse --git-dir)/hooks"
|
||||||
|
|
||||||
echo "Installing hooks to: $HOOKS_DIR"
|
echo "Installing hooks to: $HOOKS_DIR"
|
||||||
|
|
||||||
# Copy ots hooks
|
# Copy hooks
|
||||||
cp "$SCRIPT_DIR/post-commit-ots" "$HOOKS_DIR/post-commit"
|
cp "$SCRIPT_DIR/post-commit" "$HOOKS_DIR/post-commit"
|
||||||
cp "$SCRIPT_DIR/pre-commit-ots" "$HOOKS_DIR/pre-commit"
|
cp "$SCRIPT_DIR/pre-commit" "$HOOKS_DIR/pre-commit"
|
||||||
|
|
||||||
chmod +x "$HOOKS_DIR/post-commit" "$HOOKS_DIR/pre-commit"
|
chmod +x "$HOOKS_DIR/post-commit" "$HOOKS_DIR/pre-commit"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,91 +1,41 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Git OpenTimestamp Post-Commit Hook
|
# Git OpenTimestamp Post-Commit Hook (ots CLI version)
|
||||||
# Self-contained - no external dependencies
|
# Requires: opentimestamps-client (pipx install opentimestamps-client)
|
||||||
# Generates cryptographic proof for each commit using OpenTimestamp
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Configuration
|
|
||||||
OUTPUT_DIR=".ots"
|
OUTPUT_DIR=".ots"
|
||||||
OUTPUT_FILE="$OUTPUT_DIR/proof.ots"
|
OUTPUT_FILE="$OUTPUT_DIR/proof.ots"
|
||||||
|
|
||||||
# Ensure output directory exists
|
|
||||||
mkdir -p "$OUTPUT_DIR"
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
# Get the current commit hash
|
|
||||||
COMMIT_HASH=$(git rev-parse HEAD)
|
COMMIT_HASH=$(git rev-parse HEAD)
|
||||||
|
|
||||||
# Function to generate proof using ots CLI
|
# Generate proof using ots CLI
|
||||||
generate_with_ots_cli() {
|
temp_file=$(mktemp)
|
||||||
local hash="$1"
|
temp_ots="${temp_file}.ots"
|
||||||
local output="$2"
|
|
||||||
|
|
||||||
# Create a temporary file with the hash (convert hex to binary)
|
|
||||||
local temp_file=$(mktemp)
|
|
||||||
local temp_ots="${temp_file}.ots"
|
|
||||||
|
|
||||||
# Use python3 for hex to binary conversion (more portable than xxd)
|
|
||||||
python3 -c "import sys; sys.stdout.buffer.write(bytes.fromhex('$hash'))" > "$temp_file"
|
|
||||||
|
|
||||||
# Generate timestamp - ots creates .ots file alongside the original
|
|
||||||
ots stamp "$temp_file" 2>/dev/null
|
|
||||||
|
|
||||||
# Move the generated .ots file to the desired location
|
|
||||||
if [ -f "$temp_ots" ]; then
|
|
||||||
mv "$temp_ots" "$output"
|
|
||||||
rm -f "$temp_file"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
rm -f "$temp_file"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to generate proof using nodejs fallback
|
python3 -c "import sys; sys.stdout.buffer.write(bytes.fromhex('$COMMIT_HASH'))" > "$temp_file"
|
||||||
generate_with_node() {
|
ots stamp "$temp_file" 2>/dev/null
|
||||||
local hash="$1"
|
|
||||||
local output="$2"
|
|
||||||
|
|
||||||
node -e "
|
|
||||||
const ots = require('@opentimestamps/ots');
|
|
||||||
const fs = require('fs');
|
|
||||||
const hash = '$hash';
|
|
||||||
const output = '$output';
|
|
||||||
const hashBuffer = Buffer.from(hash, 'hex');
|
|
||||||
ots.Timestamp.hash(hashBuffer).then(timestamp => {
|
|
||||||
const proof = { hash: hash, timestamp: new Date().toISOString(), status: 'pending' };
|
|
||||||
fs.writeFileSync(output, JSON.stringify(proof, null, 2));
|
|
||||||
console.log('Generated local proof (nodejs fallback)');
|
|
||||||
}).catch(err => { console.error('Error:', err); process.exit(1); });
|
|
||||||
"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check for available tools and generate proof
|
if [ -f "$temp_ots" ]; then
|
||||||
if command -v ots &> /dev/null; then
|
mv "$temp_ots" "$OUTPUT_FILE"
|
||||||
if generate_with_ots_cli "$COMMIT_HASH" "$OUTPUT_FILE"; then
|
rm -f "$temp_file"
|
||||||
echo "[ots] Generated proof with ots CLI: ${COMMIT_HASH:0:8}"
|
echo "[ots] Generated proof: ${COMMIT_HASH:0:8}"
|
||||||
else
|
|
||||||
echo "[ots] Warning: ots CLI failed" >&2
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
elif command -v node &> /dev/null && node -e "require('@opentimestamps/ots')" &> /dev/null 2>&1; then
|
|
||||||
generate_with_node "$COMMIT_HASH" "$OUTPUT_FILE"
|
|
||||||
echo "[ots] Generated proof with nodejs fallback: ${COMMIT_HASH:0:8}"
|
|
||||||
else
|
else
|
||||||
echo "[ots] Warning: Neither ots CLI nor @opentimestamps/ots found, skipping proof" >&2
|
rm -f "$temp_file"
|
||||||
|
echo "[ots] Warning: Failed to generate proof" >&2
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Save previous commit hash for chaining
|
# Save previous commit for chaining
|
||||||
PREV_COMMIT=$(git rev-parse HEAD^1 2>/dev/null || echo "")
|
PREV_COMMIT=$(git rev-parse HEAD^1 2>/dev/null || echo "")
|
||||||
if [ -n "$PREV_COMMIT" ]; then
|
if [ -n "$PREV_COMMIT" ]; then
|
||||||
echo "$PREV_COMMIT" > "$OUTPUT_DIR/prev-commit.txt"
|
echo "$PREV_COMMIT" > "$OUTPUT_DIR/prev-commit.txt"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create individual proof file for this commit
|
# Create individual proof file
|
||||||
INDIVIDUAL_PROOF="$OUTPUT_DIR/${COMMIT_HASH}.ots"
|
INDIVIDUAL_PROOF="$OUTPUT_DIR/${COMMIT_HASH}.ots"
|
||||||
if [ -f "$OUTPUT_FILE" ]; then
|
cp "$OUTPUT_FILE" "$INDIVIDUAL_PROOF"
|
||||||
cp "$OUTPUT_FILE" "$INDIVIDUAL_PROOF"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[ots] Proof generated successfully"
|
echo "[ots] Proof generated successfully"
|
||||||
|
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Git OpenTimestamp Post-Commit Hook (ots CLI version)
|
|
||||||
# Requires: opentimestamps-client (pipx install opentimestamps-client)
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
OUTPUT_DIR=".ots"
|
|
||||||
OUTPUT_FILE="$OUTPUT_DIR/proof.ots"
|
|
||||||
|
|
||||||
mkdir -p "$OUTPUT_DIR"
|
|
||||||
|
|
||||||
COMMIT_HASH=$(git rev-parse HEAD)
|
|
||||||
|
|
||||||
# Generate proof using ots CLI
|
|
||||||
temp_file=$(mktemp)
|
|
||||||
temp_ots="${temp_file}.ots"
|
|
||||||
|
|
||||||
python3 -c "import sys; sys.stdout.buffer.write(bytes.fromhex('$COMMIT_HASH'))" > "$temp_file"
|
|
||||||
ots stamp "$temp_file" 2>/dev/null
|
|
||||||
|
|
||||||
if [ -f "$temp_ots" ]; then
|
|
||||||
mv "$temp_ots" "$OUTPUT_FILE"
|
|
||||||
rm -f "$temp_file"
|
|
||||||
echo "[ots] Generated proof: ${COMMIT_HASH:0:8}"
|
|
||||||
else
|
|
||||||
rm -f "$temp_file"
|
|
||||||
echo "[ots] Warning: Failed to generate proof" >&2
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Save previous commit for chaining
|
|
||||||
PREV_COMMIT=$(git rev-parse HEAD^1 2>/dev/null || echo "")
|
|
||||||
if [ -n "$PREV_COMMIT" ]; then
|
|
||||||
echo "$PREV_COMMIT" > "$OUTPUT_DIR/prev-commit.txt"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create individual proof file
|
|
||||||
INDIVIDUAL_PROOF="$OUTPUT_DIR/${COMMIT_HASH}.ots"
|
|
||||||
cp "$OUTPUT_FILE" "$INDIVIDUAL_PROOF"
|
|
||||||
|
|
||||||
echo "[ots] Proof generated successfully"
|
|
||||||
|
|
@ -1,24 +1,19 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Git OpenTimestamp Pre-Commit Backfill Hook
|
# Git OpenTimestamp Pre-Commit Backfill Hook (ots CLI version)
|
||||||
# Self-contained - no external dependencies
|
# Requires: opentimestamps-client (pipx install opentimestamps-client)
|
||||||
# Upgrades all historical proofs before each new commit
|
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Configuration
|
|
||||||
OUTPUT_DIR=".ots"
|
OUTPUT_DIR=".ots"
|
||||||
STATUS_CACHE="$OUTPUT_DIR/.attestation-cache"
|
STATUS_CACHE="$OUTPUT_DIR/.attestation-cache"
|
||||||
|
|
||||||
# Ensure output directory exists
|
|
||||||
mkdir -p "$OUTPUT_DIR"
|
mkdir -p "$OUTPUT_DIR"
|
||||||
|
|
||||||
# Initialize cache file if it doesn't exist
|
# Initialize cache
|
||||||
if [ ! -f "$STATUS_CACHE" ]; then
|
if [ ! -f "$STATUS_CACHE" ]; then
|
||||||
echo "# Attestation status cache" > "$STATUS_CACHE"
|
echo "# Format: commit-hash:status:timestamp" > "$STATUS_CACHE"
|
||||||
echo "# Format: commit-hash:status:timestamp" >> "$STATUS_CACHE"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Function to get cached status
|
|
||||||
get_cached_status() {
|
get_cached_status() {
|
||||||
local commit="$1"
|
local commit="$1"
|
||||||
local cache_line=$(grep "^$commit:" "$STATUS_CACHE" 2>/dev/null | tail -1)
|
local cache_line=$(grep "^$commit:" "$STATUS_CACHE" 2>/dev/null | tail -1)
|
||||||
|
|
@ -26,9 +21,7 @@ get_cached_status() {
|
||||||
local status=$(echo "$cache_line" | cut -d: -f2)
|
local status=$(echo "$cache_line" | cut -d: -f2)
|
||||||
local timestamp=$(echo "$cache_line" | cut -d: -f3)
|
local timestamp=$(echo "$cache_line" | cut -d: -f3)
|
||||||
local now=$(date +%s)
|
local now=$(date +%s)
|
||||||
local age=$((now - timestamp))
|
if [ "$((now - timestamp))" -lt 3600 ]; then
|
||||||
# Cache valid for 1 hour (3600 seconds)
|
|
||||||
if [ "$age" -lt 3600 ]; then
|
|
||||||
echo "$status"
|
echo "$status"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
@ -36,19 +29,15 @@ get_cached_status() {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to cache status
|
|
||||||
cache_status() {
|
cache_status() {
|
||||||
local commit="$1"
|
local commit="$1"
|
||||||
local status="$2"
|
local status="$2"
|
||||||
local now=$(date +%s)
|
echo "$commit:$status:$(date +%s)" >> "$STATUS_CACHE"
|
||||||
echo "$commit:$status:$now" >> "$STATUS_CACHE"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to generate proof using ots CLI
|
|
||||||
generate_proof() {
|
generate_proof() {
|
||||||
local hash="$1"
|
local hash="$1"
|
||||||
local output="$2"
|
local output="$2"
|
||||||
|
|
||||||
local temp_file=$(mktemp)
|
local temp_file=$(mktemp)
|
||||||
local temp_ots="${temp_file}.ots"
|
local temp_ots="${temp_file}.ots"
|
||||||
|
|
||||||
|
|
@ -59,20 +48,17 @@ generate_proof() {
|
||||||
mv "$temp_ots" "$output"
|
mv "$temp_ots" "$output"
|
||||||
rm -f "$temp_file"
|
rm -f "$temp_file"
|
||||||
return 0
|
return 0
|
||||||
else
|
|
||||||
rm -f "$temp_file"
|
|
||||||
return 1
|
|
||||||
fi
|
fi
|
||||||
|
rm -f "$temp_file"
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to check if proof is attested
|
|
||||||
is_attested() {
|
is_attested() {
|
||||||
local proof_file="$1"
|
local proof_file="$1"
|
||||||
local pending_count=$(ots info "$proof_file" 2>&1 | grep -c "PendingAttestation" || echo "0")
|
local pending_count=$(ots info "$proof_file" 2>&1 | grep -c "PendingAttestation" || echo "0")
|
||||||
[ "$pending_count" -eq 0 ]
|
[ "$pending_count" -eq 0 ]
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to upgrade proof
|
|
||||||
upgrade_proof() {
|
upgrade_proof() {
|
||||||
local proof_file="$1"
|
local proof_file="$1"
|
||||||
ots upgrade "$proof_file" 2>/dev/null
|
ots upgrade "$proof_file" 2>/dev/null
|
||||||
|
|
@ -80,7 +66,6 @@ upgrade_proof() {
|
||||||
|
|
||||||
echo "[ots] Backfilling proofs..."
|
echo "[ots] Backfilling proofs..."
|
||||||
|
|
||||||
# Get all commit hashes (oldest to newest)
|
|
||||||
COMMITS=$(git rev-list --reverse HEAD)
|
COMMITS=$(git rev-list --reverse HEAD)
|
||||||
TOTAL=$(echo "$COMMITS" | wc -l)
|
TOTAL=$(echo "$COMMITS" | wc -l)
|
||||||
CURRENT=0
|
CURRENT=0
|
||||||
|
|
@ -90,47 +75,35 @@ for COMMIT in $COMMITS; do
|
||||||
CURRENT=$((CURRENT + 1))
|
CURRENT=$((CURRENT + 1))
|
||||||
PROOF_FILE="$OUTPUT_DIR/${COMMIT}.ots"
|
PROOF_FILE="$OUTPUT_DIR/${COMMIT}.ots"
|
||||||
|
|
||||||
# Skip verbose output for brevity
|
|
||||||
if [ $CURRENT -le 3 ] || [ $CURRENT -eq $TOTAL ]; then
|
if [ $CURRENT -le 3 ] || [ $CURRENT -eq $TOTAL ]; then
|
||||||
echo "[ots] Processing commit $CURRENT/$TOTAL: ${COMMIT:0:8}"
|
echo "[ots] Processing $CURRENT/$TOTAL: ${COMMIT:0:8}"
|
||||||
elif [ $CURRENT -eq 4 ]; then
|
elif [ $CURRENT -eq 4 ]; then
|
||||||
echo "[ots] ... processing remaining commits ..."
|
echo "[ots] ... processing remaining ..."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -f "$PROOF_FILE" ]; then
|
if [ -f "$PROOF_FILE" ]; then
|
||||||
# Check cached status first
|
|
||||||
CACHED_STATUS=$(get_cached_status "$COMMIT" || echo "")
|
CACHED_STATUS=$(get_cached_status "$COMMIT" || echo "")
|
||||||
|
|
||||||
if [ "$CACHED_STATUS" = "attested" ]; then
|
[ "$CACHED_STATUS" = "attested" ] && continue
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if already attested
|
|
||||||
if is_attested "$PROOF_FILE"; then
|
if is_attested "$PROOF_FILE"; then
|
||||||
cache_status "$COMMIT" "attested"
|
cache_status "$COMMIT" "attested"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Cache as pending
|
|
||||||
cache_status "$COMMIT" "pending"
|
cache_status "$COMMIT" "pending"
|
||||||
|
|
||||||
# Skip upgrade if cache is fresh (< 10 min old)
|
|
||||||
CACHE_LINE=$(grep "^$COMMIT:" "$STATUS_CACHE" | tail -1)
|
CACHE_LINE=$(grep "^$COMMIT:" "$STATUS_CACHE" | tail -1)
|
||||||
CACHE_TIME=$(echo "$CACHE_LINE" | cut -d: -f3)
|
CACHE_TIME=$(echo "$CACHE_LINE" | cut -d: -f3)
|
||||||
NOW=$(date +%s)
|
CACHE_AGE=$(($(date +%s) - CACHE_TIME))
|
||||||
CACHE_AGE=$((NOW - CACHE_TIME))
|
|
||||||
|
|
||||||
if [ "$CACHE_AGE" -lt 600 ]; then
|
[ "$CACHE_AGE" -lt 600 ] && continue
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Try to upgrade
|
|
||||||
if upgrade_proof "$PROOF_FILE"; then
|
if upgrade_proof "$PROOF_FILE"; then
|
||||||
cache_status "$COMMIT" "attested"
|
cache_status "$COMMIT" "attested"
|
||||||
UPDATED=$((UPDATED + 1))
|
UPDATED=$((UPDATED + 1))
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# Generate new proof
|
|
||||||
if generate_proof "$COMMIT" "$PROOF_FILE"; then
|
if generate_proof "$COMMIT" "$PROOF_FILE"; then
|
||||||
cache_status "$COMMIT" "pending"
|
cache_status "$COMMIT" "pending"
|
||||||
UPDATED=$((UPDATED + 1))
|
UPDATED=$((UPDATED + 1))
|
||||||
|
|
@ -138,19 +111,15 @@ for COMMIT in $COMMITS; do
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# Update latest proof symlink
|
# Update latest proof
|
||||||
LATEST_COMMIT=$(git rev-parse HEAD)
|
LATEST_COMMIT=$(git rev-parse HEAD)
|
||||||
if [ -f "$OUTPUT_DIR/${LATEST_COMMIT}.ots" ]; then
|
[ -f "$OUTPUT_DIR/${LATEST_COMMIT}.ots" ] && cp "$OUTPUT_DIR/${LATEST_COMMIT}.ots" "$OUTPUT_DIR/proof.ots"
|
||||||
cp "$OUTPUT_DIR/${LATEST_COMMIT}.ots" "$OUTPUT_DIR/proof.ots"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Save commit chain
|
# Save commit chain
|
||||||
rm -f "$OUTPUT_DIR/commit-chain.txt"
|
rm -f "$OUTPUT_DIR/commit-chain.txt"
|
||||||
git rev-list HEAD | while read COMMIT; do
|
git rev-list HEAD | while read COMMIT; do
|
||||||
PREV=$(git rev-parse ${COMMIT}^1 2>/dev/null || echo "")
|
PREV=$(git rev-parse ${COMMIT}^1 2>/dev/null || echo "")
|
||||||
if [ -n "$PREV" ]; then
|
[ -n "$PREV" ] && echo "$COMMIT:$PREV" >> "$OUTPUT_DIR/commit-chain.txt"
|
||||||
echo "$COMMIT:$PREV" >> "$OUTPUT_DIR/commit-chain.txt"
|
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "[ots] Backfill complete: $UPDATED proofs updated"
|
echo "[ots] Backfill complete: $UPDATED updated"
|
||||||
|
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# Git OpenTimestamp Pre-Commit Backfill Hook (ots CLI version)
|
|
||||||
# Requires: opentimestamps-client (pipx install opentimestamps-client)
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
OUTPUT_DIR=".ots"
|
|
||||||
STATUS_CACHE="$OUTPUT_DIR/.attestation-cache"
|
|
||||||
|
|
||||||
mkdir -p "$OUTPUT_DIR"
|
|
||||||
|
|
||||||
# Initialize cache
|
|
||||||
if [ ! -f "$STATUS_CACHE" ]; then
|
|
||||||
echo "# Format: commit-hash:status:timestamp" > "$STATUS_CACHE"
|
|
||||||
fi
|
|
||||||
|
|
||||||
get_cached_status() {
|
|
||||||
local commit="$1"
|
|
||||||
local cache_line=$(grep "^$commit:" "$STATUS_CACHE" 2>/dev/null | tail -1)
|
|
||||||
if [ -n "$cache_line" ]; then
|
|
||||||
local status=$(echo "$cache_line" | cut -d: -f2)
|
|
||||||
local timestamp=$(echo "$cache_line" | cut -d: -f3)
|
|
||||||
local now=$(date +%s)
|
|
||||||
if [ "$((now - timestamp))" -lt 3600 ]; then
|
|
||||||
echo "$status"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
cache_status() {
|
|
||||||
local commit="$1"
|
|
||||||
local status="$2"
|
|
||||||
echo "$commit:$status:$(date +%s)" >> "$STATUS_CACHE"
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_proof() {
|
|
||||||
local hash="$1"
|
|
||||||
local output="$2"
|
|
||||||
local temp_file=$(mktemp)
|
|
||||||
local temp_ots="${temp_file}.ots"
|
|
||||||
|
|
||||||
python3 -c "import sys; sys.stdout.buffer.write(bytes.fromhex('$hash'))" > "$temp_file"
|
|
||||||
ots stamp "$temp_file" 2>/dev/null
|
|
||||||
|
|
||||||
if [ -f "$temp_ots" ]; then
|
|
||||||
mv "$temp_ots" "$output"
|
|
||||||
rm -f "$temp_file"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
rm -f "$temp_file"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
is_attested() {
|
|
||||||
local proof_file="$1"
|
|
||||||
local pending_count=$(ots info "$proof_file" 2>&1 | grep -c "PendingAttestation" || echo "0")
|
|
||||||
[ "$pending_count" -eq 0 ]
|
|
||||||
}
|
|
||||||
|
|
||||||
upgrade_proof() {
|
|
||||||
local proof_file="$1"
|
|
||||||
ots upgrade "$proof_file" 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "[ots] Backfilling proofs..."
|
|
||||||
|
|
||||||
COMMITS=$(git rev-list --reverse HEAD)
|
|
||||||
TOTAL=$(echo "$COMMITS" | wc -l)
|
|
||||||
CURRENT=0
|
|
||||||
UPDATED=0
|
|
||||||
|
|
||||||
for COMMIT in $COMMITS; do
|
|
||||||
CURRENT=$((CURRENT + 1))
|
|
||||||
PROOF_FILE="$OUTPUT_DIR/${COMMIT}.ots"
|
|
||||||
|
|
||||||
if [ $CURRENT -le 3 ] || [ $CURRENT -eq $TOTAL ]; then
|
|
||||||
echo "[ots] Processing $CURRENT/$TOTAL: ${COMMIT:0:8}"
|
|
||||||
elif [ $CURRENT -eq 4 ]; then
|
|
||||||
echo "[ots] ... processing remaining ..."
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$PROOF_FILE" ]; then
|
|
||||||
CACHED_STATUS=$(get_cached_status "$COMMIT" || echo "")
|
|
||||||
|
|
||||||
[ "$CACHED_STATUS" = "attested" ] && continue
|
|
||||||
|
|
||||||
if is_attested "$PROOF_FILE"; then
|
|
||||||
cache_status "$COMMIT" "attested"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
cache_status "$COMMIT" "pending"
|
|
||||||
|
|
||||||
CACHE_LINE=$(grep "^$COMMIT:" "$STATUS_CACHE" | tail -1)
|
|
||||||
CACHE_TIME=$(echo "$CACHE_LINE" | cut -d: -f3)
|
|
||||||
CACHE_AGE=$(($(date +%s) - CACHE_TIME))
|
|
||||||
|
|
||||||
[ "$CACHE_AGE" -lt 600 ] && continue
|
|
||||||
|
|
||||||
if upgrade_proof "$PROOF_FILE"; then
|
|
||||||
cache_status "$COMMIT" "attested"
|
|
||||||
UPDATED=$((UPDATED + 1))
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if generate_proof "$COMMIT" "$PROOF_FILE"; then
|
|
||||||
cache_status "$COMMIT" "pending"
|
|
||||||
UPDATED=$((UPDATED + 1))
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Update latest proof
|
|
||||||
LATEST_COMMIT=$(git rev-parse HEAD)
|
|
||||||
[ -f "$OUTPUT_DIR/${LATEST_COMMIT}.ots" ] && cp "$OUTPUT_DIR/${LATEST_COMMIT}.ots" "$OUTPUT_DIR/proof.ots"
|
|
||||||
|
|
||||||
# Save commit chain
|
|
||||||
rm -f "$OUTPUT_DIR/commit-chain.txt"
|
|
||||||
git rev-list HEAD | while read COMMIT; do
|
|
||||||
PREV=$(git rev-parse ${COMMIT}^1 2>/dev/null || echo "")
|
|
||||||
[ -n "$PREV" ] && echo "$COMMIT:$PREV" >> "$OUTPUT_DIR/commit-chain.txt"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "[ots] Backfill complete: $UPDATED updated"
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue