Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

git-status performance and safety fixes #64

Merged
merged 13 commits into from
Apr 14, 2024
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