YYSuni
cover

Git Variables

Integrating Git variables into a project might just spark some interesting ideas.

I want to add a .ts file to the project that includes the latest information for each commit. This would allow us to:

  • Assist with version control
  • Integrate with the page refresh mechanism
  • Track bugs
  • Monitor how bots scan different versions of the page

The first thing that came to mind was using Husky to conveniently write a pre-commit hook:

GIT_HASH=$(git rev-parse HEAD)

echo "export const currentGitHash = '$GIT_HASH';" > src/gitHash.ts

This script stores the Git hash in a .ts file. However, there are two issues here. First, the file can only be created after a commit, which means it will introduce a new file change. Second, the hash stored is not the latest hash.


Storing in the Commit

Based on AI suggestions, we could use a post-commit hook and then continue with git add + git commit --amend --no-edit. However, there are two pitfalls here:

  1. The hash after --amend is not the hash we stored, because the hash is based on the collection of files, and any file change will generate a new hash. Therefore, it is impossible to store the latest hash.
  2. The post-commit hook will cause an infinite loop and crash the Git program. If this happens, it will affect the entire Git tree. When writing the script, we need to add an if logic and specify a dynamic yet fixed value to ensure that the amend logic only occurs once.

If an infinite loop crash occurs, you must drop the commit, otherwise it will affect subsequent operations.


New Approach

Given the issues above, we cannot store the latest hash when committing the information. Instead, we can store the commit message along with a real timestamp.

The post-commit logic should include a timestamp check. If the current timestamp differs from the recorded timestamp by less than 5 seconds, we can consider it the same commit.

We can also store the previous hash to help quickly and accurately locate commits.


Encryption

Since the file will be included in the project and the commit message is considered sensitive information, we can encrypt it.

However, there is another issue: the encryption done by openssl enc is difficult to decrypt smoothly using JavaScript's crypt-js. Therefore, it is best to use openssl enc -d for decryption. Otherwise, you will need to spend time on JavaScript decryption.

./husky/pre-commit Code

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

COMMIT_MSG=$(git log -1 --pretty=format:%B)
ENCRYPTED_COMMIT_MSG=$(echo -n "$COMMIT_MSG" | openssl enc -aes-256-cbc -a -pass pass:xxx)

COMMIT_TIMESTAMP=$(date +%s)

PREV_HASH=$(git rev-parse HEAD)


if [ -z "$ENCRYPTED_COMMIT_MSG" ]; then
  echo "ENCRYPT FAIL"
  exit 1
fi


if [ -f .git/no-post-commit ]; then
  PREVIOUS_TIMESTAMP=$(cat .git/no-post-commit)


  TIMESTAMP_DIFF=$((COMMIT_TIMESTAMP - PREVIOUS_TIMESTAMP))

  TIMESTAMP_DIFF=${TIMESTAMP_DIFF#-}


  if [ "$TIMESTAMP_DIFF" -le 5 ]; then
    echo "Skipping update since it's the same commit."
    exit 0
  fi
fi

echo "export const COMMIT_MSG = '$ENCRYPTED_COMMIT_MSG'" > src/commit-info.ts
echo "export const COMMIT_TIMESTAMP = $COMMIT_TIMESTAMP" >> src/commit-info.ts
echo "export const PREV_HASH = '$PREV_HASH'" >> src/commit-info.ts

echo "$COMMIT_TIMESTAMP" > .git/no-post-commit

git add src/commit-info.ts
git commit --amend --no-edit

Quick Decryption Command:

echo 'U2FsdGVkX1xxxxxxxxxxxxxxxx'| openssl enc -aes-256-cbc -d -a -pass pass:xxx

Should I use -pbkdf2 instead?