Hacker Newsnew | past | comments | ask | show | jobs | submit | lavp's commentslogin

I made a bash function to turn these commands into a one page diagnostics report so that you can use this in your `.bashrc`:

Diagnostics function, colorized (I tried to add guards so it is portable with terminals that do not support color):

  git_diag() {
    local since="${1:-1 year ago}"
    local root repo branch

    # --- patterns ---
    local pattern="${GIT_DIAG_PATTERN:-fix|bug|broken|hotfix|incident|issue|patch}"
    local firefight_pattern="revert|hotfix|emergency|rollback"

    # --- colors ---
    local GREP_COLOR_MODE='never'
    if [[ -z "${NO_COLOR:-}" ]] && [[ -t 1 ]] && [[ "${TERM:-}" != "dumb" ]] && [[ "$(tput colors 2>/dev/null || echo 0)" -ge 8 ]]; then
      local BLACK=$(tput setaf 0)
      local RED=$(tput setaf 1)
      local GREEN=$(tput setaf 2)
      local YELLOW=$(tput setaf 3)
      local BLUE=$(tput setaf 4)
      local MAGENTA=$(tput setaf 5)
      local CYAN=$(tput setaf 6)
      local WHITE=$(tput setaf 7)
      local BOLD=$(tput bold)
      local DIM=$(tput dim 2>/dev/null || true)
      local RESET=$(tput sgr0)
      GREP_COLOR_MODE='always'
    else
      local BLACK='' RED='' GREEN='' YELLOW='' BLUE='' MAGENTA='' CYAN='' WHITE=''
      local BOLD='' DIM='' RESET=''
    fi

    local TITLE="$CYAN"
    local COLOR_COUNT="$CYAN"
    local COLOR_FILE="$YELLOW"

    if ! root="$(git rev-parse --show-toplevel 2>/dev/null)"; then
      printf 'git_diag: not inside a Git repository\n' >&2
      return 1
    fi

    repo="${root##*/}"
    branch="$(git branch --show-current 2>/dev/null)"
    branch="${branch:-DETACHED}"

    _git_diag_fmt_count() {
      local count_color="$1"
      local text_color="$2"

      awk -v count_color="$count_color" -v text_color="$text_color" -v reset="$RESET" '{
        c=$1
        $1=""
        sub(/^ +/, "")
        printf "  %s%10d%s  %s%s%s\n", count_color, c, reset, text_color, $0, reset
      }'
    }

    printf '%s%sGit repo diagnostics%s\n' "$BOLD" "$TITLE" "$RESET"
    printf '%s%-11s%s %s\n' "$BOLD" "Repo:"      "$RESET" "$repo"
    printf '%s%-11s%s %s\n' "$BOLD" "Branch:"    "$RESET" "$branch"
    printf '%s%-11s%s %s\n' "$BOLD" "Timeframe:" "$RESET" "$since → now"
    printf '\n\n'

    printf '%s%s1) Most changed files%s\n' "$BOLD" "$TITLE" "$RESET"
    git log --since="$since" --format='' --name-only \
      | awk 'NF' \
      | sort \
      | uniq -c \
      | sort -nr \
      | head -n 10 \
      | _git_diag_fmt_count "$COLOR_COUNT" "$COLOR_FILE"

    printf '\n%s%s2) Top contributors%s\n' "$BOLD" "$TITLE" "$RESET"
    git shortlog -sn --no-merges --since="$since" \
      | head -n 10 \
      | awk -v count_color="$COLOR_COUNT" -v reset="$RESET" '{
          printf "  %s%10d%s  %s\n", count_color, $1, reset, substr($0, index($0,$2))
        }'

    printf '\n%s%s3) Bug/fix hotspots%s %s(pattern: %s)%s\n' "$BOLD" "$TITLE" "$RESET" "$DIM" "$pattern" "$RESET"
    git log --since="$since" --format='' --name-only -i -E --grep="$pattern" \
      | awk 'NF' \
      | sort \
      | uniq -c \
      | sort -nr \
      | head -n 10 \
      | _git_diag_fmt_count "$COLOR_COUNT" "$COLOR_FILE"

    printf '\n%s%s4) Commit count by month%s\n' "$BOLD" "$TITLE" "$RESET"
    git log --since="$since" --format='%ad' --date=format:'%Y-%m' \
      | sort \
      | uniq -c \
      | sort -k2r \
      | awk -v count_color="$COLOR_COUNT" -v mag="$MAGENTA" -v reset="$RESET" '
        {
          data[NR,1] = $2
          data[NR,2] = $1
          if (length($1) > max) max = length($1)
        }
        END {
          for (i = 1; i <= NR; i++) {
            printf "  %s%10s%s  %s%*d commits%s\n",
              mag, data[i,1], reset,
              count_color, max, data[i,2], reset
          }
        }
      '

    printf '\n%s%s5) Firefighting commits%s %s(pattern: %s)%s\n' "$BOLD" "$TITLE" "$RESET" "$DIM" "$firefight_pattern" "$RESET"
    git log --since="$since" -i -E \
      --grep="$firefight_pattern" \
      --date=short \
      --pretty=format:'%ad %h %s' \
      | head -n 10 \
      | awk -v mag="$MAGENTA" -v dim="$DIM" -v reset="$RESET" '{
          date=$1
          hash=$2
          $1=$2=""
          sub(/^  */, "")
          printf "  %s%-10s%s  %s%-12s%s  %s\n",
            mag, date, reset,
            dim, hash, reset,
            $0
        }' \
      | GREP_COLORS='ms=01;31' grep --color="$GREP_COLOR_MODE" -i -E "$firefight_pattern"
  }
Uncolorized diagnostics function (same, but without the colors):

  git_diag() {
    local since="${1:-1 year ago}"
    local pattern="${GIT_DIAG_PATTERN:-fix|bug|broken|hotfix|incident|issue|patch}"
    local root repo branch

    if ! root="$(git rev-parse --show-toplevel 2>/dev/null)"; then
      printf 'git_diag: not inside a Git repository\n' >&2
      return 1
    fi

    repo="${root##*/}"
    branch="$(git branch --show-current 2>/dev/null)"
    branch="${branch:-DETACHED}"

    _git_diag_fmt_count() {
      awk '{
        c=$1
        $1=""
        sub(/^ +/, "")
        printf "  %10d  %s\n", c, $0
      }'
    }

    printf '============================================================\n'
    printf 'Git repo diagnostics\n'
    printf '%-11s%as\n' 'Repo:'      "$repo"
    printf '%-11s%s\n' 'Branch:'    "$branch"
    printf '%-11s%s\n' 'Timeframe:' "$since"
    printf '============================================================\n\n'

    printf '1) Most changed files (top 10)\n'
    git log --since="$since" --format='' --name-only \
      | awk 'NF' \
      | sort \
      | uniq -c \
      | sort -nr \
      | head -n 10 \
      | _git_diag_fmt_count

    printf '\n2) Top 10 contributors (no merges, since %s)\n' "$since"
    git shortlog -sn --no-merges --since="$since" \
      | head -n 10 \
      | _git_diag_fmt_count

    printf '\n3) Bug/fix hotspots (top 10, matching: %s)\n' "$pattern"
    git log --since="$since" --format='' --name-only -i -E --grep="$pattern" \
      | awk 'NF' \
      | sort \
      | uniq -c \
      | sort -nr \
      | head -n 10 \
      | _git_diag_fmt_count

    printf '\n4) Commit count by month (since %s)\n' "$since"
    git log --since="$since" --format='%ad' --date=format:'%Y-%m' \
      | sort \
      | uniq -c \
      | sort -k2r \
      | awk '
        {
          data[NR,1] = $2
          data[NR,2] = $1
          if (length($1) > max) max = length($1)
        }
        END {
          for (i = 1; i <= NR; i++) {
            printf "  %10s  %*d commits\n", data[i,1], max, data[i,2]
          }
        }
      '

    printf '\n5) 10 most recent firefighting commits (revert|hotfix|emergency|rollback)\n'
    git log --since="$since" -i -E \
      --grep='revert|hotfix|emergency|rollback' \
      --date=short \
      --pretty=format:'%ad %h %s' \
      | head -n 10 \
      | awk '{
          date=$1
          hash=$2
          $1=$2=""
          sub(/^  */, "")
          printf "  %-10s  %-12s  %s\n", date, hash, $0
        }' \
      | GREP_COLORS='ms=01;31' grep --color=always -i -E 'revert|hotfix|emergency|rollback'
  }

Airport security used to be handled by private companies. Then 9/11 happened and that's the whole reason TSA even exists.


`rm` is a destructive operation, but you can always alias it to move it to a trash folder.

File managers have nowhere near the flexibility available in the terminal.


I feel very uncomfortable with Chess players holding 'Grandmaster' titles. Would much prefer 'Grandmain'.


I’ve found Macs to be good for most dev stuff with the exception of non-Dockerized C++.

Unfortunately I do a lot of C++… I hate the hoops you have to go through to not use the Apple Clang compiler.


Yeah, C++ is only a side actor on Apple since Mac OS got replaces with NeXTSTEP, Copland was C++ based, and BeOS as well, but Objective-C won.

Now with Swift, and the whole security legistation ongoing issues across several countries, Apple seems to only care to the extent it needs for their uses of LLVM, Metal Shading Language (C++14 dialect), and IO / Driver Kit frameworks.

They aren't contributing to clang as they once were, Google also not after the whole ABI break discussion.

On Windows land, it isn't much better, it appears that after getting first place reaching C++20 compliance, Microsoft decided to invest their programming language budgets on .NET, Rust and Go, asking the community what features that actually care about in newer standards.

https://developercommunity.visualstudio.com/t/Implement-C23-...

https://developercommunity.visualstudio.com/t/Implement-C26-...

So it is going to be hard going forward, expecting the very latest features on the three major compilers, when the contributions get reduced.


When you are delivering mate in 1, the square still gets highlighted as being attacked by the king.


What you described is syntax differences. `=` is assignment, not equivalence.



I also TA'd 110 and I firmly disagree. CPSC110 teaches you to view a particular problem as a series of different possible states, and solving for those states (while placing an emphasis on seeing base cases and working up from there). Students learn about data structures like binary trees by the fifth week, and the ninth week they're already able to solve sudoku puzzles using generative recursion. We even touched on the n-queens problem towards the end of the course.

Racket serves its purpose well as a simple and fast to learn educational language; it's easy to see and understand recursion. It's also easy to see what the execution order of statements in your program.

I will say though that some problem sets were a bit brutal in terms of time taken to complete them.


Agreed. My main observations from students in my cohort were that those who viewed programming as a set of instructions struggled, whereas those who viewed the course material as a series of manipulations on mathematical objects grasped the material much quicker. In general, the course focused a lot on learning from first principles, which I appreciate much more nowadays.


Good ol' Gregory Kiczales


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: