Earlier quoted context omitted.
I don’t understand how people can remember all these custom scripting languages. I can’t even remember most git flags, I’m ecstatic when I remember how to iterate over arrays in “jq”, I can’t fathom how people remember these types of syntaxes.
I am convinced that the vast majority of professionals simply don't bother to remember and, ESPECIALLY WITH GIT, just look stuff up every single time the workflow deviates from their daily usage. At this point perhaps a million person-years have been sacrificed to the semantically incoherent shit UX of git. I have loathed git from the beginning but there's effectively no other choice. That said, the OP's commands are…
Git commands I run before reading any code
391–400 of 546 posts
Re: Git commands I run before reading any code
#392I love how the author thinks developers write commit messages. All joking aside, it really is a chronic problem in the corporate world. Most codebases I encounter just have "changed stuff" or "hope this works now". It's a small minority of developers (myself included) who consider the git commit log to be important enough to spend time writing something meaningful. AI generated commit messages helps this a lot, if de…
Non-Core repos are absolute free-form anything goes. You can commit 8 times a day without a PR as long as you're not deploying to production. This is excellent for things like test harnesses, CI/CD nonsense, one-off experiments, demos, prototypes, etc.
My last Core commit had something like 20 to 1 ratio between lines of commit message to lines of code (small change touching something deep that required a lot of explanation). My last non-Core commit message was "hope this works" (it did not).
Re: Git commands I run before reading any code
#393I ran these commands on a number of codebases I work on and I have to say they paint a very different picture than the reality I know to be true. > git shortlog -sn --no-merges Is the most egregious. In one codebase there is a developer's name at the top of the list who outpaced the number 2 by almost 3x the number of commits. That developer no longer works at the company? Crisis? Nope, the opposite. The developer wa…
Re: Git commands I run before reading any code
#394Earlier quoted context omitted.
Git rebases don't work if there are conflicts, jj doesn't have this problem. Also idk if you can rebase onto multiple parents with git but jj can do it.
Can you explain how conflicts are not conflicts? If I change a line of code several times and rebase on to a branch that changed the same lines of code, how are you sure what the right one is?
Re: Git commands I run before reading any code
#395Earlier quoted context omitted.
One of the best developers I work with commits everything with the message "changes" (This is not an endorsement to do that, he's a good developer in spite of his shitty commit messages)
Obviously a very unpopular opinion, but I guess for my own sake it's hard to write commit messages, because for me it's that I have never really even found use of other people commit messages, and I rarely even attempt to. Ultimately code is code and I don't care about how it got to how it is. I got same issue with documentation and comments or really anything that isn't building stuff. I don't like writing it, don't…
Re: Git commands I run before reading any code
#396I like the mindset, it reminds me of "Your code as a crime scene" by Adam Tornhill: https://www.adamtornhill.com/articles/crimescene/codeascrime... Also, very tangentially, to the notion of the Developer's Legacy Index: https://www.javaadvent.com/2021/12/using-jgit-to-analyse-the...
Re: Git commands I run before reading any code
#397Diagnostics 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
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 Re: Git commands I run before reading any code
#398Earlier quoted context omitted.
I particularly love when the “CTO” is also the main offender.
I am a CTO and I actually have very little patience for people that obsess over minor formatting issues (use a linter if you care), commit messages, and other fringe issues. If that's the biggest issue you have in a team, amazing. You are doing great. But you probably have bigger issues. The focus of the CTO is on the big picture stuff. Like staying on top of technical debt and correcting people when they keep on add…
Why do you think OSS projects have a high bar for change descriptions? It's because some things matter for the long run.
Also, it's pretty clear from the context of this discussion that it's about the descriptions on pull requests (or other units of change like CLs) and not individual commits that get squashed in a PR/CL.
> BTW. making AI tools write good commit messages is actually be a bit expensive. Many AI tools default to just summarizing the first message of a chat session under the assumption that just one thing changed over the course of a session. Making the AI look at the actual diff is of course possible and not that hard (just ask). And it definitely yields better descriptions when you do that. But it also takes more time and the token cost goes up as well. I'm not sure that's actually worth the expense in tokens. I tend to not bother with this. But again; depends on the context.
All coding agents do that these days - they just run git diff and figure out what the change is when writing the commit message. Are you saying that writing a better change description is not worth the pennies it costs in tokens?
Re: Git commands I run before reading any code
#399Earlier quoted context omitted.
> I am convinced that the vast majority of professionals simply don't bother to remember and, ESPECIALLY WITH GIT, just look stuff up every single time the workflow deviates from their daily usage. I wrote a cheat sheet in my notes of common commands, until they stuck in my head and I haven't needed it now for a decade or more. I also lean heavily on aliases and "self-documenting" things in my .bashrc file. Curious h…
I just use Claude Code as a terminal for git these days. It writes up better commit messages than I would write anyway. No more "git commit -m fix"
Re: Git commands I run before reading any code
#400Jujutsu equivalents, if anyone is curious: What Changes the Most jj log --no-graph -r 'ancestors(trunk()) & committer_date(after:"1 year ago")' \ -T 'self.diff().files().map(|f| f.path() ++ "\n").join("")' \ | sort | uniq -c | sort -nr | head -20 Who Built This jj log --no-graph -r 'ancestors(trunk()) & ~merges()' \ -T 'self.author().name() ++ "\n"' \ | sort | uniq -c | sort -nr Where Do Bugs Cluster jj log --no-grap…
Saw all the replies crying over how verbose these are, clicked through to TFA expecting to see simpler commands. Nope, they're basically the same thing, just slightly shorter. I would never memorize either the jj or git versions if I planned to use them regularly; I'd make aliases.
To me, the verbosity of both Git and JJ commands to do these things are an indication that neither of these tools are meant to do them.