Skip to content

Commit

Permalink
fix: git-status performance and safety fixes (janoamaral#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
Stealthii authored Apr 14, 2024
1 parent 9740b2e commit 2d57f79
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 85 deletions.
95 changes: 43 additions & 52 deletions src/git-status.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,60 +6,57 @@ if [ "$SHOW_NETSPEED" == "0" ]; then
fi

CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source $CURRENT_DIR/themes.sh
source $CURRENT_DIR/../lib/coreutils-compat.sh
source "$CURRENT_DIR/../lib/coreutils-compat.sh"
source "$CURRENT_DIR/themes.sh"

cd $1
cd "$1" || exit 1
RESET="#[fg=${THEME[foreground]},bg=${THEME[background]},nobold,noitalics,nounderscore,nodim]"
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
STATUS=$(git status --porcelain 2>/dev/null | egrep "^(M| M)" | wc -l)
BRANCH_SIZE=${#BRANCH}
STATUS=$(git status --porcelain 2>/dev/null | grep -cE "^(M| M)")

SYNC_MODE=0
NEED_PUSH=0
NEED_PULL=0

if test "$BRANCH_SIZE" -gt "25"; then
BRANCH=$(echo $BRANCH | cut -c1-25)""
if [[ ${#BRANCH} -gt 25 ]]; then
BRANCH="${BRANCH:0:25}"
fi

STATUS_CHANGED=""
STATUS_INSERTIONS=""
STATUS_DELETIONS=""
STATUS_UNTRACKED=""

if test "$STATUS" != "0"; then
CHANGED_COUNT=$(git diff --shortstat 2>/dev/null | tr "," "\n" | grep "chang" | cut -d" " -f2 | bc)
INSERTIONS_COUNT="$(git diff --shortstat 2>/dev/null | tr "," "\n" | grep "ins" | cut -d" " -f2 | bc)"
DELETIONS_COUNT="$(git diff --shortstat 2>/dev/null | tr "," "\n" | grep "del" | cut -d" " -f2 | bc)"
if [[ $STATUS -ne 0 ]]; then
DIFF_COUNTS=($(git diff --numstat 2>/dev/null | awk 'NF==3 {changed+=1; ins+=$1; del+=$2} END {printf("%d %d %d", changed, ins, del)}'))
CHANGED_COUNT=${DIFF_COUNTS[0]}
INSERTIONS_COUNT=${DIFF_COUNTS[1]}
DELETIONS_COUNT=${DIFF_COUNTS[2]}

SYNC_MODE=1
fi

STATUS_UNTRACKED="$(git ls-files --other --directory --exclude-standard | wc -l | bc)"
UNTRACKED_COUNT="$(git ls-files --other --directory --exclude-standard | wc -l | bc)"

if [[ $CHANGED_COUNT > 0 ]]; then
STATUS_CHANGED="#[fg=${THEME[yellow]},bg=${THEME[background]},bold] ${CHANGED_COUNT} "
if [[ $CHANGED_COUNT -gt 0 ]]; then
STATUS_CHANGED="${RESET}#[fg=${THEME[yellow]},bg=${THEME[background]},bold] ${CHANGED_COUNT} "
fi

if [[ $INSERTIONS_COUNT > 0 ]]; then
STATUS_INSERTIONS="#[fg=${THEME[green]},bg=${THEME[background]},bold] ${INSERTIONS_COUNT} "
if [[ $INSERTIONS_COUNT -gt 0 ]]; then
STATUS_INSERTIONS="${RESET}#[fg=${THEME[green]},bg=${THEME[background]},bold] ${INSERTIONS_COUNT} "
fi

if [[ $DELETIONS_COUNT > 0 ]]; then
STATUS_DELETIONS="#[fg=${THEME[red]},bg=${THEME[background]},bold] ${DELETIONS_COUNT} "
if [[ $DELETIONS_COUNT -gt 0 ]]; then
STATUS_DELETIONS="${RESET}#[fg=${THEME[red]},bg=${THEME[background]},bold] ${DELETIONS_COUNT} "
fi

if [[ $STATUS_UNTRACKED > 0 ]]; then
STATUS_UNTRACKED="#[fg=#565f89,bg=#15161e,bold] ${STATUS_UNTRACKED} "
else
STATUS_UNTRACKED=""
if [[ $UNTRACKED_COUNT -gt 0 ]]; then
STATUS_UNTRACKED="${RESET}#[fg=#565f89,bg=#15161e,bold] ${UNTRACKED_COUNT} "
fi

# Determine repository sync status
if [[ $SYNC_MODE == 0 ]]; then
if [[ $SYNC_MODE -eq 0 ]]; then
NEED_PUSH=$(git log @{push}.. | wc -l | bc)
if [[ $NEED_PUSH > 0 ]]; then
if [[ $NEED_PUSH -gt 0 ]]; then
SYNC_MODE=2
else
LAST_FETCH=$(stat -c %Y .git/FETCH_HEAD | bc)
Expand All @@ -70,36 +67,30 @@ if [[ $SYNC_MODE == 0 ]]; then
git fetch --atomic origin --negotiation-tip=HEAD
fi

REMOTE_DIFF="$(git diff --shortstat $(git rev-parse --abbrev-ref HEAD) origin/$(git rev-parse --abbrev-ref HEAD) 2>/dev/null | wc -l | bc)"
if [[ $REMOTE_DIFF > 0 ]]; then
# Check if the remote branch is ahead of the local branch
REMOTE_DIFF="$(git diff --numstat "${BRANCH}" "origin/${BRANCH}" 2>/dev/null)"
if [[ -n $REMOTE_DIFF ]]; then
SYNC_MODE=3
fi
fi
fi

if [[ $SYNC_MODE > 0 ]]; then
case "$SYNC_MODE" in
1)
REMOTE_STATUS="$RESET#[bg=#15161e,fg=#ff9e64,bold]▒ 󱓎"
;;
2)
REMOTE_STATUS="$RESET#[bg=#15161e,fg=#f7768e,bold]▒ 󰛃"
;;
3)
REMOTE_STATUS="$RESET#[bg=#15161e,fg=#bb9af7,bold]▒ 󰛀"
;;
*)
echo default
;;
esac
else
REMOTE_STATUS="$RESET#[fg=#73daca,bg=#15161e,bold]▒ "
fi

if test "$BRANCH" != ""; then
if test "$STATUS" = "0"; then
echo "$REMOTE_STATUS $RESET$BRANCH $RESET$STATUS_UNTRACKED"
else
echo "$REMOTE_STATUS $RESET$BRANCH $RESET$STATUS_CHANGED$RESET$STATUS_INSERTIONS$RESET$STATUS_DELETIONS$RESET$STATUS_UNTRACKED"
fi
# Set the status indicator based on the sync mode
case "$SYNC_MODE" in
1)
REMOTE_STATUS="$RESET#[bg=#15161e,fg=${THEME[bred]},bold]▒ 󱓎"
;;
2)
REMOTE_STATUS="$RESET#[bg=#15161e,fg=${THEME[red]},bold]▒ 󰛃"
;;
3)
REMOTE_STATUS="$RESET#[bg=#15161e,fg=${THEME[magenta]},bold]▒ 󰛀"
;;
*)
REMOTE_STATUS="$RESET#[bg=#15161e,fg=${THEME[green]},bold]▒ "
;;
esac

if [[ -n $BRANCH ]]; then
echo "$REMOTE_STATUS $RESET$BRANCH $STATUS_CHANGED$STATUS_INSERTIONS$STATUS_DELETIONS$STATUS_UNTRACKED"
fi
61 changes: 28 additions & 33 deletions src/wb-git-status.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@ if [ "$SHOW_WIDGET" == "0" ]; then
fi

CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source $CURRENT_DIR/themes.sh
source "$CURRENT_DIR../lib/coreutils-compat.sh"
source "$CURRENT_DIR/themes.sh"

# Imports
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/.."
. "${ROOT_DIR}/lib/coreutils-compat.sh"

cd $1
cd "$1" || exit 1
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
PROVIDER=$(git config remote.origin.url | awk -F '@|:' '{print $2}')
STATUS=$(git status --porcelain 2>/dev/null | egrep "^(M| M)" | wc -l)

PROVIDER_ICON=""

Expand All @@ -28,59 +24,58 @@ REVIEW_STATUS=""
ISSUE_STATUS=""
BUG_STATUS=""

if [[ $PROVIDER == "github.com" ]]; then
if [[ -n $BRANCH ]]; then
exit 0
fi

if [[ $PROVIDER == "github.com" ]]; then
if ! command -v gh &>/dev/null; then
exit 1
fi

PROVIDER_ICON="$RESET#[fg=${THEME[foreground]}] "
if test "$BRANCH" != ""; then
PR_COUNT=$(gh pr list --json number --jq 'length' | bc)
REVIEW_COUNT=$(gh pr status --json reviewRequests --jq '.needsReview | length' | bc)
RES=$(gh issue list --json "assignees,labels" --assignee @me)
ISSUE_COUNT=$(echo $RES | jq 'length' | bc)
BUG_COUNT=$(echo $RES | jq 'map(select(.labels[].name == "bug")) | length' | bc)
ISSUE_COUNT=$((ISSUE_COUNT - BUG_COUNT))
else
exit 0
PR_COUNT=$(gh pr list --json number --jq 'length' | bc)
REVIEW_COUNT=$(gh pr status --json reviewRequests --jq '.needsReview | length' | bc)
RES=$(gh issue list --json "assignees,labels" --assignee @me)
ISSUE_COUNT=$(echo "$RES" | jq 'length' | bc)
BUG_COUNT=$(echo "$RES" | jq 'map(select(.labels[].name == "bug")) | length' | bc)
ISSUE_COUNT=$((ISSUE_COUNT - BUG_COUNT))
elif [[ $PROVIDER == "gitlab.com" ]]; then
if ! command -v glab &>/dev/null; then
exit 1
fi
else
PROVIDER_ICON="$RESET#[fg=#fc6d26] "
if test "$BRANCH" != ""; then
PR_COUNT=$(glab mr list | grep -E "^\!" | wc -l | bc)
REVIEW_COUNT=$(glab mr list --reviewer=@me | grep -E "^\!" | wc -l | bc)
ISSUE_COUNT=$(glab issue list | grep -E "^\#" | wc -l | bc)
else
exit 0
fi
PR_COUNT=$(glab mr list | grep -cE "^\!")
REVIEW_COUNT=$(glab mr list --reviewer=@me | grep -cE "^\!")
ISSUE_COUNT=$(glab issue list | grep -cE "^\#")
else
exit 0
fi

if [[ $PR_COUNT > 0 ]]; then
if [[ $PR_COUNT -gt 0 ]]; then
PR_STATUS="#[fg=${THEME[ghgreen]},bg=${THEME[background]},bold] ${RESET}${PR_COUNT} "
fi

if [[ $REVIEW_COUNT > 0 ]]; then
if [[ $REVIEW_COUNT -gt 0 ]]; then
REVIEW_STATUS="#[fg=${THEME[ghyellow]},bg=${THEME[background]},bold] ${RESET}${REVIEW_COUNT} "
fi

if [[ $ISSUE_COUNT > 0 ]]; then
if [[ $ISSUE_COUNT -gt 0 ]]; then
ISSUE_STATUS="#[fg=${THEME[ghgreen]},bg=${THEME[background]},bold] ${RESET}${ISSUE_COUNT} "
fi

if [[ $BUG_COUNT > 0 ]]; then
if [[ $BUG_COUNT -gt 0 ]]; then
BUG_STATUS="#[fg=${THEME[ghred]},bg=${THEME[background]},bold] ${RESET}${BUG_COUNT} "
fi

if [[ $PR_COUNT > 0 || $REVIEW_COUNT > 0 || $ISSUE_COUNT > 0 ]]; then
if [[ $PR_COUNT -gt 0 || $REVIEW_COUNT -gt 0 || $ISSUE_COUNT -gt 0 ]]; then
WB_STATUS="#[fg=${THEME[black]},bg=${THEME[background]},bold] $RESET$PROVIDER_ICON $RESET$PR_STATUS$REVIEW_STATUS$ISSUE_STATUS$BUG_STATUS"
fi

echo "$WB_STATUS"

# Wait extra time if status-interval is less than 30 seconds to
# avoid to overload GitHub API
INTERVAL="$(tmux show -g | grep status-interval | cut -d" " -f2 | bc)"
if [[ $INTERVAL < 20 ]]; then
INTERVAL=$(tmux display -p '#{status-interval}')
if [[ $INTERVAL -lt 20 ]]; then
sleep 20
fi

0 comments on commit 2d57f79

Please sign in to comment.