Skip to content

Instantly share code, notes, and snippets.

@vermiculus
Last active May 27, 2020 11:40
Show Gist options
  • Save vermiculus/9984b6f4a6ccddde3697aec61dac4ea3 to your computer and use it in GitHub Desktop.
Save vermiculus/9984b6f4a6ccddde3697aec61dac4ea3 to your computer and use it in GitHub Desktop.
#!/bin/bash
# (setq magit-git-executable "~/bin/chatty-git")
start=$(gdate +%s.%N) # gdate => GNU `date' -- Mac OS X has its own version that should not be overridden on my machine
git "$@"
code="$?"
end=$(gdate +%s.%N)
echo ">${start}-${end}|$@" >> ~/chatty-git.log
exit $code
(defun grab-log-line ()
"Grab one line of the log and advance point.
Return a cons of the command and how long that command took."
(let ((start-time (buffer-substring-no-properties
(+ (point) 1)
(progn
(forward-char)
(search-forward-regexp (rx "-") nil 'noerror)
(- (point) 1))))
(end-time (buffer-substring-no-properties
(point)
(progn
(search-forward-regexp (rx "|") nil 'noerror)
(- (point) 1))))
(command (buffer-substring-no-properties
(point)
(if (search-forward-regexp (rx bol ">") nil 'noerror)
(prog1 (- (point) 2)
(backward-char))
(- (point) 1)))))
(cons command (- (string-to-number end-time)
(string-to-number start-time)))))
(defun process-log-file (file)
"Process FILE and display sorted results in a new window.
Commit-specific calls are generlized with \"<hash>\" tokens.
Results are sorted by total time taken across all calls to each
command."
(interactive (list (expand-file-name "~/chatty-git.log" nil)))
(let (log-lines sums)
(with-temp-buffer
(insert-file-contents-literally file)
(goto-char 0)
(while (looking-at-p (rx bol ">"))
(push (grab-log-line) log-lines)))
;; `log-lines' is now backwards, but that doesn't really matter
;; for summing
(setq log-lines
(mapcar
(lambda (pair)
(let ((command (car pair)))
(setq command (replace-regexp-in-string
(rx (repeat 40 xdigit))
"<long-hash>"
command)
command (replace-regexp-in-string
(rx (repeat 8 xdigit))
"<short-hash>"
command)
command (replace-regexp-in-string
(rx (or "--no-pager "
"--literal-pathspecs "
"-c core.preloadindex=true "
"-c log.showSignature=false "))
""
command))
(cons command (cdr pair))))
log-lines))
(mapc (lambda (pair)
(if-let (found (assoc-string (car pair) sums))
(setcdr found (cons (1+ (cadr found)) (+ (cddr found) (cdr pair))))
(push (cons (car pair) (cons 1 (cdr pair))) sums)))
log-lines)
;; CONTROL SORTING HERE
(let ((by-average-time (lambda (a b) (< (/ (cadr a) (cddr a))
(/ (cadr b) (cddr b)))))
(by-total-time (lambda (a b) (> (cddr a) (cddr b)))))
(setq sums (sort sums by-total-time)))
;; sums is now sorted appropriately; start printing results
(let ((inhibit-read-only t)
(print-escape-newlines t)
(fmtstr (format "%%%dd %%6.4f %%S\n"
(1+ (log (apply #'max (mapcar #'cadr sums)) 10)))))
(with-current-buffer (get-buffer-create "*results*")
(erase-buffer)
(dolist (sum sums)
(insert (format fmtstr (cadr sum) (cddr sum) (car sum))))
(goto-char 0)
(view-buffer-other-window (current-buffer))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment