2 - Presenting Git Changes

2 - Presenting Git Changes

Result #

#! /run/current-system/sw/bin/bash

cd ..

# Get the total number of commits
commit_count=$(git rev-list --count HEAD)

# Loop through each commit in reverse order (last to first)
for (( i=1; i<=$commit_count; i++ )); do
    # Calculate commit hash for the current iteration
    commit_hash=$(git rev-list --max-count=1 --skip=$((commit_count - i)) HEAD)
    
    # Get the hash of the previous commit (or an empty string if it's the first commit)
    if [ $i -eq 1 ]; then
        previous_commit=""
    else
        previous_commit=$(git rev-list --max-count=1 --skip=$((commit_count - i + 1)) HEAD)
    fi

    # Generate the diff, using the empty tree for the initial commit if necessary
    if [ -z "$previous_commit" ]; then
        git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 $commit_hash > "commit_$(printf "%03d" $i)_$(git rev-parse --short $commit_hash).diff"
    else
        git diff $previous_commit $commit_hash > "commit_$(printf "%03d" $i)_$(git rev-parse --short $commit_hash).diff"
    fi
done

echo "Diff files for all commits have been created."

Current Date: December 29, 2024

With documenting my experiences to blog and documentation; I’ve been starting the process to understand how I could get the Git information presented clearly into the appropriate resources, or as clear as possible.

Get Commits #

As a start, I began to conceptualize how to approach this from top, bottom approach. I began my experience with asking AI this:

Question #

I have a Git Repository and a Hugo Site.
I want to build a blog on this Hugo Site. The purpose of this blog is share my experiences with different systems I’ve been learning about, based on using commits
Is there a way I could easily capture the Commits and share on a post?

Answer #

To integrate Git commits into your Hugo blog posts in a way that allows you to share your experiences with different systems, you can follow these steps:

  1. Setup Your Environment

Ensure you have Hugo and Git installed on your system. Your Hugo site should already be set up with a basic structure.

  1. Capture Git Commits
  • Scripting: You can write a script (in bash, Python, or another language) to extract commit information from your Git repository. Here’s how you might do this with bash:

    bash

    git log --pretty=format:"%h %ad %s" --date=short -n 5 > commits.txt
    

    This command lists the last 5 commits with their hash, date, and message. You might customize this to fit your needs, like changing the number of commits, or formatting.

  • Automation: Automate this script to run each time you want to update your blog post with new commit information. You could include this in a CI/CD pipeline or run it manually before generating your site.

Resources for Reference:

  • For scripting to capture Git commits, consider looking into Git documentation for more options on formatting log output.
  • For integrating with Hugo, you might find it useful to understand how Hugo handles data files and template syntax.
  • For automation through GitHub Actions or similar CI/CD, explore how others have set up Hugo with GitHub Pages.

This method allows you to keep your blog posts updated with your Git commit history, providing a narrative of your development journey with various systems.

Commits, got it! #

So, I have a way to get the commits. Helpful overall. I want to present the exact changes to another person that would read the content of my side which led to these followup questions:

Question #

Ok, it’s helpful to know I could share in that manner with a script. How would I present the exact code changes from a commit?

Answer #

To present the exact code changes from a specific Git commit in your Hugo blog post, you can use git diff along with Hugo’s Markdown capabilities. Here’s how you can do it:

  1. Generate the Diff
  • Use git diff to see the changes made in a specific commit. Here’s how you can do it:

    bash

    git diff <commit_hash>~1..<commit_hash>
    

    Replace <commit_hash> with the actual hash of the commit you’re interested in. The ~1 refers to the commit before the one you specified, showing the changes introduced by that commit.

  • Or, if you just want to see the changes from the previous commit:

    bash

    git show <commit_hash>
    
  • To save this diff for use in your blog post:

    bash

    git diff <commit_hash>~1..<commit_hash> > commit_diff.txt
    
  1. Format the Diff for Markdown
  • Git diff output can be directly used in Markdown with some formatting. Here’s how you can present it:

    markdown

    Here's the exact change from commit `3d7546c`:
    
    ```diff
    <paste the output from commit_diff.txt here>
    
    
    The `diff` language in Markdown code blocks will highlight additions (with `+`) and deletions (with `-`).
    
  1. Example in Hugo Post
  • In your Hugo post, your Markdown might look like this:

    markdown

    ---
    title: "Detailed Changes in System XYZ"
    date: 2024-12-22
    ---
    
    Here's the exact change from commit `3d7546c`:
    
    ```diff
    diff --git a/path/to/file b/path/to/file
    index 1234567..89abcde 100644
    --- a/path/to/file
    +++ b/path/to/file
    @@ -1,3 +1,4 @@
    -Old line
    +New line added
    +Another new line
     Unchanged line
    

    This commit introduced a fix for an authentication issue by adding necessary checks.

This approach allows you to showcase specific code changes directly within your blog posts, giving a clear view of what was modified in each commit. Remember to use syntax highlighting for better readability, which Hugo supports through its integration with libraries like Highlight.js or Prism.js.

Question #

Write a loop script to pull the diff from all commits in repo, each commit would have it’s own file with a prefix of first commit to last commit.

Answer #

Here’s a bash script that will loop through all commits in a Git repository, generate diffs for each commit, and save them in individual files named with a prefix indicating their order from the first to the last commit:

#!/bin/bash

# Get the total number of commits
commit_count=$(git rev-list --count HEAD)

# Loop through each commit in reverse order (last to first)
for (( i=1; i<=$commit_count; i++ )); do
    # Calculate commit hash for the current iteration
    commit_hash=$(git rev-list --max-count=1 --skip=$((commit_count - i)) HEAD)
    
    # Get the hash of the previous commit (or an empty string if it's the first commit)
    if [ $i -eq 1 ]; then
        previous_commit=""
    else
        previous_commit=$(git rev-list --max-count=1 --skip=$((commit_count - i + 1)) HEAD)
    fi

    # Generate the diff, using the empty tree for the initial commit if necessary
    if [ -z "$previous_commit" ]; then
        git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 $commit_hash > "commit_$(printf "%03d" $i)_$(git rev-parse --short $commit_hash).diff"
    else
        git diff $previous_commit $commit_hash > "commit_$(printf "%03d" $i)_$(git rev-parse --short $commit_hash).diff"
    fi
done

echo "Diff files for all commits have been created."

Explanation:

  • Commit Count: We first determine the total number of commits in the repository.
  • Loop: We loop through commits from the last to the first, which helps in maintaining the order in file names.
  • Commit Hash: For each iteration, we get the hash of the commit we’re currently processing.
  • Previous Commit: We determine the previous commit’s hash, except for the first commit where there isn’t one, so we use the empty tree’s hash as a placeholder.
  • Diff Generation:
    • For the first commit, we compare against the empty tree (4b825dc642cb6eb9a060e54bf8d69288fbee4904), which is a constant known hash in Git for an empty repository state.
    • For subsequent commits, we compare against the previous commit’s hash.
  • File Naming: Files are named with a three-digit prefix for ordering (001, 002, etc.), followed by the short hash of the commit for clarity and uniqueness.

Note:

  • This script assumes you’re running it in the root directory of your Git repository.
  • The script uses printf “%03d” to ensure the commit number is always three digits, aiding in correct sorting.
  • git rev-parse –short gives a shortened version of the commit hash for readability.

Make sure to make the script executable with chmod +x script_name.sh before running it.