Skip to content

Instantly share code, notes, and snippets.

@kevbost
Last active December 21, 2023 02:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kevbost/b36e4e03a9fa592e5d71a6671514139b to your computer and use it in GitHub Desktop.
Save kevbost/b36e4e03a9fa592e5d71a6671514139b to your computer and use it in GitHub Desktop.
Shell script to run git diff against a deleted and added file after a rename

sh ./scripts/diff_deleted_file.sh ./fileName.js ./fileName.ts [commit_from_deletion] [--prettier] | pbcopy

Table of Contents

Why

On Github, when a file is renamed and changed (IE: typescript conversion), git will mark the old file name as deleted and the new file name as added based on how many changes were detected. If the number of changes is below 50% (according to some SO comment), git will mark the file as renamed/moved. But if the changes are over 50%, the diff is lost.

There is no way to get around this, so this utility script can help with seeing differences between renamed files. The --prettier flag option will run prettier on the deleted file to make sure that the two files match as closely as possible.

To use it, run the command using the old file name and new file name, and paste the output into a markdown codeblock with the diff syntax:

```diff
paste output here
```

CLI Command

sh ./scripts/diff_deleted_file.sh ./src/fileName.js ./src/fileName.ts --prettier

or to copy directly to clipboard, append with | pbcopy:

sh ./scripts/diff_deleted_file.sh ./src/fileName.js ./src/fileName.ts --prettier | pbcopy

Optional git commit hash argument

If the file was deleted in a previous commit, provide the commit hash from the deletion. The script will use the file from that commit's parent commit to use in a comparison.

Usage

sh ./scripts/diff_deleted_file.sh ./src/fileName.js ./src/fileName.ts [commitHash_from_file_deletion] [--prettier] | pbcopy

Usage: ./scripts/diff_deleted_file.sh <deleted-file-path> <current-file-path> [commit-hash] [--prettier]
Compares a deleted file from the git history with a current file.

Arguments:
  <deleted-file-path>  Path to the deleted file in git history. E.g., ./client/async/queries/conversations.js
  <current-file-path>  Path to the current file. E.g., ./client/async/queries/conversations.ts
  [commit-hash]        (Optional) Git commit hash. If not provided, latest commit (HEAD) is used.
  [--prettier]         (Optional) If provided, prettier formatting will be used.

Shell Script

./scripts/diff_deleted_file.sh

#!/bin/sh

# ----------------------------- DOCS ----------------------------- #
# https://gist.github.com/kevbost/b36e4e03a9fa592e5d71a6671514139b #
# ---------------------------------------------------------------- #

# Check if arguments are provided
if [ $# -lt 2 ]; then
  echo "Usage: $0 <deleted-file-path> <current-file-path> [commit-hash] [--prettier]"
  echo "Compares a deleted file from the git history with a current file."
  echo ""
  echo "Arguments:"
  echo "  <deleted-file-path>  Path to the deleted file in git history. E.g., ./client/async/queries/conversations.js"
  echo "  <current-file-path>  Path to the current file. E.g., ./client/async/queries/conversations.ts"
  echo "  [commit-hash]        (Optional) Git commit hash. If not provided, latest commit (HEAD) is used."
  echo "  [--prettier]         (Optional) If provided, prettier formatting will be used."
  exit 1
fi

# Assign arguments to variables
DELETED_FILE_PATH=$1
CURRENT_FILE_PATH=$2

# If third argument is provided, set COMMIT_HASH to it; Otherwise, set COMMIT_HASH to 'HEAD'
COMMIT_HASH=
if [ $# -ge 3 ] && [ ${3#-} = $3 ]; then
    COMMIT_HASH=$3^1
else
    COMMIT_HASH="HEAD"
fi

# Get the content of the deleted file from the git history
DELETED_FILE=$(git show "$COMMIT_HASH":"${DELETED_FILE_PATH}")

# Check if '--prettier' flag is provided
use_prettier=false
for arg in "$@"
do
    if [ "$arg" = "--prettier" ] ; then
        use_prettier=true
        break
    fi
done

if [ "$use_prettier" = true ] ; then
    FORMATTED_DELETED_FILE=$(echo "$DELETED_FILE" | npx prettier --stdin-filepath deleted_file.js --ignore-path '')
else
    FORMATTED_DELETED_FILE=$DELETED_FILE
fi

# Create a temporary file
TEMP_FILE=$(mktemp)

# Write the formatted deleted file to this temporary file
echo "$FORMATTED_DELETED_FILE" > "$TEMP_FILE"

# Compare the temporary file with the current file
git --no-pager diff "$TEMP_FILE" "$CURRENT_FILE_PATH"

# Remove the temporary file
rm "$TEMP_FILE"

Output

diff --git a/var/folders/9d/xjgvmb2s0k18zs5vm_p5lw500000gn/T/tmp.K6Yr4QnftL b/./client/utils/eventUtils.ts
index 1b9eb1270..38535ba6d 100644
--- a/var/folders/9d/xjgvmb2s0k18zs5vm_p5lw500000gn/T/tmp.K6Yr4QnftL
+++ b/./client/utils/eventUtils.ts
@@ -1,11 +1,18 @@
 import isEmpty from 'lodash/isEmpty'
 
+interface Subscription {
+  id: string
+  func: (...args: unknown[]) => unknown
+}
+
 class EventPublisher {
+  private subscriptions: Record<string, Subscription[]>
+
   constructor() {
     this.subscriptions = {}
   }
 
-  addSubscription = (type, { id, func }) => {
+  addSubscription = (type: string, { id, func }: Subscription): void => {
     if (!Array.isArray(this.subscriptions[type])) {
       this.subscriptions[type] = []
     }
@@ -14,18 +21,18 @@ class EventPublisher {
     this.subscriptions[type].push({ id, func })
   }
 
-  hasSubscription = (type) => {
+  hasSubscription = (type: string): boolean => {
     return !isEmpty(this.subscriptions[type])
   }
 
-  removeSubscription = (type, id) => {
+  removeSubscription = (type: string, id: string): void => {
     this.subscriptions[type] = this.subscriptions[type].filter(
       (sub) => sub.id !== id,
     )
   }
 
-  notifySubscriptions = (type, ...args) => {
-    Array.isArray(this.subscriptions[type]) &&
+  notifySubscriptions = (type: string, ...args: unknown[]): void => {
+    if (Array.isArray(this.subscriptions[type])) {
       this.subscriptions[type].forEach((sub) => {
         try {
           sub.func(...args)
@@ -33,6 +40,7 @@ class EventPublisher {
           // Not handling error.
         }
       })
+    }
   }
 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment