The original link

Demand background

Because every weekend before the holiday to give the statistics of the number of code, if the manual statistics need to run the corresponding script under each developed project, too tedious. So write the following script for the first version of the code count

The code shown

The following is the amount of code in G:/project/tungee/. The part marked in red needs to be modified as your own project path and git mailbox

The first edition

Statistics by item

#! /bin/sh
# Can detect some errors, and when errors occur interrupt the program and output information
Use set -e to exit the script in case of an error instead of continuing. Use set-u to check if an unassigned variable is used; Try set-o Pipefail, which detects errors in pipes.
set -euo pipefail
trap "echo 'error: Script failed: see failed command above'" ERR
# {} prevents download incomplete code from being executed
{
  function to_array(){
    x=The $1
    OLD_IFS="$IFS" 
    IFS=","
    array=($x) 
    IFS="$OLD_IFS" 
    for each in ${array[*]}
    do
    echo $each
    done
  }
  echo "Enter the project name, separated by commas, without Spaces."
  read input
  files=($(to_array $input))
  echo -e "\n"
  for file in ${files[@]}
  do
    if [ ! -d "G:/project/tungee/$file" ]; then
      echo -e "$fileDirectory does not exist.
      continue;
    fi
    if [ ! -d "G:/project/tungee/$file/.git" ]; then
      echo -e "$fileNot a Git repository.
      continue;
    fi
    cd "G:/project/tungee/$file"
    echo "$fileCode count:"
    i=`date +%w`
    while [ $i -ge 1 ]
    do
      sinceDate=`date -d "-$i day" +%Y-%m-%d`
      untilDate=`date -d "-$(($i-1)) day" +%Y-%m-%d`
      git log --author="[email protected]" --since=$sinceDate --until=$untilDate --pretty=tformat: --numstat | gawk '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "'$untilDate'Add lines: %s, delete lines: %s, total lines: %s\n", add, subs, loc}'
      i=$(($i-1))
    done
    echo -e "\n"
  done
}
Copy the code

Running effect

The above update is 2019-5-22


The second edition

Added statistics by date and shell parameter input

#! /bin/sh
/git.bash mockingbird robin koala
# Can detect some errors, and when errors occur interrupt the program and output information
Use set -e to exit the script in case of an error instead of continuing. Use set-u to check if an unassigned variable is used; Try set-o Pipefail, which detects errors in pipes.
set -euo pipefail
trap "echo 'error: Script failed: see failed command above'" ERR
# {} prevents download incomplete code from being executed
{
  function to_array() {
    x=The $1
    OLD_IFS="$IFS" 
    IFS=","
    array=($x) 
    IFS="$OLD_IFS" 
    for each in ${array[*]}
    do
    echo $each
    done
  }

  file_path="G:/project/tungee"
  git_email="[email protected]"
  date_stat="date +%w" # date_stat="echo 5" # date_stat="echo 5

  if [ $# -lt 1 ]; then
    echo "Enter the project name, separated by commas, without Spaces."
    read input
    files=($(to_array $input))
  else
    files=$*
  fi

  echo -e "By date:"
  i=$($date_stat)
  while [ $i -ge 1 ]
  do
    add_sum=0
    subs_sum=0
    loc_sum=0
    for file in ${files[@]}
    do
      if [ ! -d "$file_path/$file" ]; then
        echo -e "$fileDirectory does not exist.
        continue;
      fi
      if [ ! -d "$file_path/$file/.git" ]; then
        echo -e "$fileNot a Git repository.
        continue;
      fi
      cd "$file_path/$file"
      since_date=`date -d "-$i day" +%Y-%m-%d`
      until_date=`date -d "-$(($i-1)) day" +%Y-%m-%d`
      eval $(git log --author=$git_email --since=$since_date --until=$until_date --pretty=tformat: --numstat | awk -v add=0 -v subs=0 -v loc=0 '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "add=%s; subs=%s; loc=%s;" , add, subs, loc }')
      add_sum=$(($add_sum + $add))
      subs_sum=$(($subs_sum + $subs))
      loc_sum=$(($loc_sum + $loc))
    done
    printf "$until_dateIncrease the total number of rows:$add_sum, the total number of deleted rows:$subs_sum, total lines of code:$loc_sum\n"
    i=$(($i-1))
  done

  echo -e "\n By item:"
  for file in ${files[@]}
  do
    if [ ! -d "$file_path/$file" ]; then
      echo -e "$fileDirectory does not exist.
      continue;
    fi
    if [ ! -d "$file_path/$file/.git" ]; then
      echo -e "$fileNot a Git repository.
      continue;
    fi
    cd "$file_path/$file"
    echo "$fileCode count:"
    i=$($date_stat)
    while [ $i -ge 1 ]
    do
      since_date=`date -d "-$i day" +%Y-%m-%d`
      until_date=`date -d "-$(($i-1)) day" +%Y-%m-%d`
      git log --author=$git_email --since=$since_date --until=$until_date --pretty=tformat: --numstat | awk -v add=0 -v subs=0 -v loc=0 '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "'$until_date'Add lines: %s, delete lines: %s, total lines: %s\n", add, subs, loc}'
      i=$(($i-1))
    done
  done
}
Copy the code

Running effect

The third edition

Add branch statistics function, remove shell parameter input (currently not supported)

#! /bin/sh
/git.bash mockingbird robin koala
# Can detect some errors, and when errors occur interrupt the program and output information
Use set -e to exit the script in case of an error instead of continuing. Use set-u to check if an unassigned variable is used; Try set-o Pipefail, which detects errors in pipes.
# set -euo pipefail
# trap "echo 'error: Script failed: see failed command above'" ERR
# {} prevents download incomplete code from being executed
{
  function to_array() {
    x=The $1
    OLD_IFS="$IFS" 
    IFS=","
    array=($x) 
    IFS="$OLD_IFS" 
    for each in ${array[*]}
    do
    echo $each
    done
  }

  file_path="G:/project/tungee"
  git_email="[email protected]"
  date_stat="date +%w" Date_stat ="echo 5

  echo "Enter the project name, separated by commas, without Spaces."
  read input
  projects=($(to_array $input))
  echo "Enter branch names separated by commas without Spaces."
  read input
  branches=($(to_array $input))

  for branch in ${branches[@]}
  do
    exist_branch_projects=()
    for file in ${projects[@]}
    do
      if [ ! -d "$file_path/$file" ]; then
        echo -e "$fileDirectory does not exist.
        continue;
      fi
      if [ ! -d "$file_path/$file/.git" ]; then
        echo -e "$fileNot a Git repository.
        continue;
      fi
      cd "$file_path/$file"
      git checkout $branch -q >/dev/null 2>&1 Redirect error messages, that is, mask error messages
      if [ $? -ne 0 ]; then
        echo -e "\n$fileSwitch branches to$branchFailure, this branch may not exist."
      else
        exist_branch_projects+=($file)
        git pull origin $branch -q
      fi
    done
    echo -e "\ n branches$branchCode statistics on:"
    {
      echo -e "By date:"
      i=$($date_stat)
      while [ $i -ge 1 ]
      do
        add_sum=0
        subs_sum=0
        loc_sum=0
        for file in ${exist_branch_projects[@]}
        do
          if [ ! -d "$file_path/$file" ]; then
            echo -e "$fileDirectory does not exist.
            continue;
          fi
          if [ ! -d "$file_path/$file/.git" ]; then
            echo -e "$fileNot a Git repository.
            continue;
          fi
          cd "$file_path/$file"
          # git checkout master
          since_date=`date -d "-$i day" +%Y-%m-%d`
          until_date=`date -d "-$(($i-1)) day" +%Y-%m-%d`
          eval $(git log --author=$git_email --since=$since_date --until=$until_date --pretty=tformat: --numstat | awk -v add=0 -v subs=0 -v loc=0 '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "add=%s; subs=%s; loc=%s;" , add, subs, loc }')
          add_sum=$(($add_sum + $add))
          subs_sum=$(($subs_sum + $subs))
          loc_sum=$(($loc_sum + $loc))
        done
        printf "$until_dateIncrease the total number of rows:$add_sum, the total number of deleted rows:$subs_sum, total lines of code:$loc_sum\n"
        i=$(($i-1))
      done

      echo -e "By item:"
      for file in ${exist_branch_projects[@]}
      do
        if [ ! -d "$file_path/$file" ]; then
          echo -e "$fileDirectory does not exist.
          continue;
        fi
        if [ ! -d "$file_path/$file/.git" ]; then
          echo -e "$fileNot a Git repository.
          continue;
        fi
        cd "$file_path/$file"
        # git checkout master
        echo "$fileCode count:"
        i=$($date_stat)
        while [ $i -ge 1 ]
        do
          since_date=`date -d "-$i day" +%Y-%m-%d`
          until_date=`date -d "-$(($i-1)) day" +%Y-%m-%d`
          git log --author=$git_email --since=$since_date --until=$until_date --pretty=tformat: --numstat | awk -v add=0 -v subs=0 -v loc=0 '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "'$until_date'Add lines: %s, delete lines: %s, total lines: %s\n", add, subs, loc}'
          i=$(($i-1))
        done
      done
    }
  done
}
Copy the code

Running effect

The above update is updated at 2019-8-15 20:49:40


The fourth edition

The third edition of the number of statistical code does not match the corresponding time, the code written yesterday to today, do the following fixes

Also added day of the week optimization tips

Fixed code statistics not matching the wrong time and adding a day of the week prompt

#! /bin/sh
/git.bash mockingbird robin koala
# Can detect some errors, and when errors occur interrupt the program and output information
Use set -e to exit the script in case of an error instead of continuing. Use set-u to check if an unassigned variable is used; Try set-o Pipefail, which detects errors in pipes.
# set -euo pipefail
# trap "echo 'error: Script failed: see failed command above'" ERR
# {} prevents download incomplete code from being executed
{
  function to_array() {
    x=The $1
    OLD_IFS="$IFS" 
    IFS=","
    array=($x) 
    IFS="$OLD_IFS" 
    for each in ${array[*]}
    do
    echo $each
    done
  }

  file_path="G:/project/tungee"
  git_email="[email protected]"
  date_stat="date +%w" Date_stat ="echo 5

  # if [ $date_stat -eq 0 ]; then
  # date_stat=7
  # fi

  echo "Enter the project name, separated by commas, without Spaces."
  read input
  projects=($(to_array $input))
  echo "Enter branch names separated by commas without Spaces."
  read input
  branches=($(to_array $input))

  for branch in ${branches[@]}
  do
    exist_branch_projects=()
    for file in ${projects[@]}
    do
      if [ ! -d "$file_path/$file" ]; then
        echo -e "$fileDirectory does not exist.
        continue;
      fi
      if [ ! -d "$file_path/$file/.git" ]; then
        echo -e "$fileNot a Git repository.
        continue;
      fi
      cd "$file_path/$file"
      git checkout $branch -q >/dev/null 2>&1 Redirect error messages, that is, mask error messages
      if [ $? -eq 0 ]; then
        exist_branch_projects+=($file)
        git pull origin $branch -q
      # else
      # # echo -e "\n$file failed to switch branch to $branch.
      fi
    done
    echo -e "\ n branches$branchCode statistics on:"
    {
      echo -e "By date:"
      # or I = $(($($date_stat) - 1))
      $a+$b = expr $a+$b = expr $a+$b
      # $() and ' 'are equivalent to command replacement, perform the result replacement
      i=`expr $($date_stat`) - 1while [ $i -ge 0 ]
      do
        add_sum=0
        subs_sum=0
        loc_sum=0
        for file in ${exist_branch_projects[@]}
        do
          if [ ! -d "$file_path/$file" ]; then
            echo -e "$fileDirectory does not exist.
            continue;
          fi
          if [ ! -d "$file_path/$file/.git" ]; then
            echo -e "$fileNot a Git repository.
            continue;
          fi
          cd "$file_path/$file"
          # git checkout $branch
          since_date=`date -d "-$i day" +%Y-%m-%d`
          since_week=`date -d "-$i day" +%A`
          until_date=`date -d "-$(($i-1)) day" +%Y-%m-%d`
          eval $(git log --author=$git_email --since=$since_date --until=$until_date --pretty=tformat: --numstat | awk -v add=0 -v subs=0 -v loc=0 '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "add=%s; subs=%s; loc=%s;" , add, subs, loc }')
          add_sum=$(($add_sum + $add))
          subs_sum=$(($subs_sum + $subs))
          loc_sum=$(($loc_sum + $loc))
        done
        printf "$since_date($since_week) increase the total number of rows:$add_sum, the total number of deleted rows:$subs_sum, total lines of code:$loc_sum\n"
        i=$(($i-1))
      done

      # echo -e "by project:"
      # for file in ${exist_branch_projects[@]}
      # do
      # if [ ! -d "$file_path/$file" ]; then
      # echo -e "$file directory does not exist."
      # continue;
      # fi
      # if [ ! -d "$file_path/$file/.git" ]; then
      # echo -e "$file is not a Git repository.
      # continue;
      # fi
      # cd "$file_path/$file"
      # # git checkout $branch
      # echo "$file"
      # i=$($date_stat)
      # while [ $i -ge 1 ]
      # do
      # since_date=`date -d "-$i day" +%Y-%m-%d`
      # until_date=`date -d "-$(($i-1)) day" +%Y-%m-%d`
      # git log --author=$git_email --since=$since_date --until=$until_date --pretty=tformat: --numstat | awk -v add=0 -v subs=0 -v loc=0 '{ add += $1 ; subs += $2 ; Loc += $1 - $2} END {printf "'$until_date' : %s, add, subs, loc}'
      # i=$(($i-1))
      # done
      # done
    }
  done
}
Copy the code

Running effect

Updated at 2020-3-7 11:57:55


The fifth edition

There are two problems with today’s code:

  1. As I cycles to zero,-$(($i-1))There is something wrong with this line of codeuntil_datesince_dateInstead, it was a day too early, resulting in script statistics errors
  2. When the statistics of today’s code are transmitted, the current time of minute and second will be added by default to cause the statistics to fail, that is, the minute and second must be added, otherwise the statistics of today’s code cannot be collected

Fix statistics today code

#! /bin/sh
/git.bash mockingbird robin koala
# Can detect some errors, and when errors occur interrupt the program and output information
Use set -e to exit the script in case of an error instead of continuing. Use set-u to check if an unassigned variable is used; Try set-o Pipefail, which detects errors in pipes.
# set -euo pipefail
# trap "echo 'error: Script failed: see failed command above'" ERR
# {} prevents download incomplete code from being executed
{
  function to_array() {
    x=The $1
    OLD_IFS="$IFS" 
    IFS=","
    array=($x) 
    IFS="$OLD_IFS" 
    for each in ${array[*]}
    do
    echo $each
    done
  }

  file_path="G:/project/tungee"
  git_email="[email protected]"
  date_stat="echo 9" Date_stat ="echo 5

  # if [ $date_stat -eq 0 ]; then
  # date_stat=7
  # fi

  echo "Enter the project name, separated by commas, without Spaces."
  read input
  projects=($(to_array $input))
  echo "Enter branch names separated by commas without Spaces."
  read input
  branches=($(to_array $input))

  for branch in ${branches[@]}
  do
    exist_branch_projects=()
    for file in ${projects[@]}
    do
      if [ ! -d "$file_path/$file" ]; then
        echo -e "$fileDirectory does not exist.
        continue;
      fi
      if [ ! -d "$file_path/$file/.git" ]; then
        echo -e "$fileNot a Git repository.
        continue;
      fi
      cd "$file_path/$file"
      git checkout $branch -q >/dev/null 2>&1 Redirect error messages, that is, mask error messages
      if [ $? -eq 0 ]; then
        exist_branch_projects+=($file)
        # git pull origin $branch -q
      # else
      # # echo -e "\n$file failed to switch branch to $branch.
      fi
    done
    echo -e "\ n branches$branchCode statistics on:"
    {
      echo -e "By date:"
      # or I = $(($($date_stat) - 1))
      $a+$b = expr $a+$b = expr $a+$b
      # $() and ' 'are equivalent to command replacement, perform the result replacement
      i=`expr $($date_stat`) - 1while [ $i -ge 0 ]
      do
        add_sum=0
        subs_sum=0
        loc_sum=0
        for file in ${exist_branch_projects[@]}
        do
          if [ ! -d "$file_path/$file" ]; then
            echo -e "$fileDirectory does not exist.
            continue;
          fi
          if [ ! -d "$file_path/$file/.git" ]; then
            echo -e "$fileNot a Git repository.
            continue;
          fi
          cd "$file_path/$file"
          # git checkout $branch
          since_date=`date -d "-$i day" +%Y-%m-%d`
          if [ $i -ge 1 ]; then
            until_date=`date -d "-$(($i-1)) day" +%Y-%m-%d`
          else
            until_date=`date -d "+$((0-$i+1)) day" +%Y-%m-%d`
          fi
          eval $(git log --author=$git_email --since="$since_date 00:00:00" --until="$until_date 00:00:00" --pretty=tformat: --numstat | awk -v add=0 -v subs=0 -v loc=0 '{ add += $1 ; subs += $2 ; loc += $1 - $2 } END { printf "add=%s; subs=%s; loc=%s;" , add, subs, loc }')
          add_sum=$(($add_sum + $add))
          subs_sum=$(($subs_sum + $subs))
          loc_sum=$(($loc_sum + $loc))
        done
        since_week=`date -d "-$i day" +%A`
        printf "$since_date($since_week) increase the total number of rows:$add_sum, the total number of deleted rows:$subs_sum, total lines of code:$loc_sum\n"
        i=$(($i-1))
      done

      # echo -e "by project:"
      # for file in ${exist_branch_projects[@]}
      # do
      # if [ ! -d "$file_path/$file" ]; then
      # echo -e "$file directory does not exist."
      # continue;
      # fi
      # if [ ! -d "$file_path/$file/.git" ]; then
      # echo -e "$file is not a Git repository.
      # continue;
      # fi
      # cd "$file_path/$file"
      # # git checkout $branch
      # echo "$file"
      # i=$($date_stat)
      # while [ $i -ge 1 ]
      # do
      # since_date=`date -d "-$i day" +%Y-%m-%d`
      # until_date=`date -d "-$(($i-1)) day" +%Y-%m-%d`
      # git log --author=$git_email --since=$since_date --until=$until_date --pretty=tformat: --numstat | awk -v add=0 -v subs=0 -v loc=0 '{ add += $1 ; subs += $2 ; Loc += $1 - $2} END {printf "'$until_date' : %s, add, subs, loc}'
      # i=$(($i-1))
      # done
      # done
    }
  done
}
Copy the code

Running effect