Open mateialexandru opened 2 years ago
The core of the mode is this shell command, so it'll need to be re-created for Windows:
"find . -mindepth 1 -maxdepth 1 -type d | sort | tr \\\\n \\\\0 | \
xargs -0 -I^ sh -c \"
cd ^
git rev-parse --is-inside-work-dir >/dev/null 2>&1 || exit 0
if [ \\\"true\\\" = \\\"\\$(git rev-parse --is-inside-git-dir)\\\" ]; then exit 0; fi
if [ \\\"\\$PWD\\\" != \\\"\\$(git rev-parse --show-toplevel)\\\" ]; then exit 0; fi
branch=\\\"\\$(git symbolic-ref --short HEAD)\\\"
remote=\\\"\\$(git config --get branch.\\${branch}.remote)\\\"
git rev-parse \\${remote}/\\${branch} >/dev/null 2>&1
if [ 0 -ne \\$? ]; then
forward=\\\"-\\\"
behind=\\\"-\\\"
else
forward=\\\"\\$(git log \\${remote}/\\${branch}..\\${branch} --oneline | wc -l)\\\"
behind=\\\"\\$(git log \\${branch}..\\${remote}/\\${branch} --oneline | wc -l)\\\"
fi
echo \\\"(\
file \\\\\\\"\\$PWD\\\\\\\"\
branch \\\\\\\"\\${branch}\\\\\\\"\
remote \\\\\\\"\\${remote}\\\\\\\"\
forward \\\\\\\"\\${forward}\\\\\\\"\
behind \\\\\\\"\\${behind}\\\\\\\"\
)\\\"
\"
For convenience, cleaned up with all the shonk removed.
find . -mindepth 1 -maxdepth 1 -type d \
| sort \
| tr '\n' '\0' \
| xargs -0 -I^ sh -c \
cd ^
git rev-parse --is-inside-work-dir >/dev/null 2>&1 || exit 0
if [ "true" = "$(git rev-parse --is-inside-git-dir)" ]; then exit 0; fi
if [ "$PWD" != "$(git rev-parse --show-toplevel)" ]; then exit 0; fi
branch="$(git symbolic-ref --short HEAD)"
remote="$(git config --get branch.${branch}.remote)"
git rev-parse ${remote}/${branch} >/dev/null 2>&1
if [ 0 -ne $? ]; then
forward="-"
behind="-"
else
forward="$(git log ${remote}/${branch}..${branch} --oneline | wc -l)"
behind="$(git log ${branch}..${remote}/${branch} --oneline | wc -l)"
fi
echo "(
file "$PWD"
branch "${branch}"
remote "${remote}"
forward "${forward}"
behind "${behind}"
)"
Probably best to just convert this to lisp.
Coming soon....
Cross platform, find directories at dir
...
(defun directories (dir)
"List directories at DIR."
(cl-reduce
(lambda (dirs filename)
"directories at pwd"
(when (file-directory-p filename)
(setq dirs (push filename dirs)))
dirs)
(cddr (directory-files dir t)) :initial-value '()))
(defun git-branch-local ()
"Return the local git branch at pwd.
Returns an empty string if we are not in a git work-tree."
(if (eql 'w32 (window-system))
(string-trim (shell-command-to-string "git symbolic-ref --short HEAD 2> nul")))
(string-trim (shell-command-to-string "git symbolic-ref --short HEAD 2> /dev/null")))
(defun git-remote-for (local-branch)
"Return the remote for LOCAL-BRANCH at pwd.
Returns an empty string if we are not in a git work-tree."
(string-trim (shell-command-to-string (format "git config --get branch.%s.remote" local-branch))))
(git-remote-for "main")
(defun git-top-level-p (dir)
"Return non-nil if DIR is top-level of the work-tree."
(string= dir
(shell-command-to-string "git rev-parse --show-toplevel")))
(defun directories (dir)
"List directories at DIR."
(cl-reduce
(lambda (dirs filename)
"directories at pwd"
(when (file-directory-p filename)
(setq dirs (push filename dirs)))
dirs)
(cddr (directory-files dir t)) :initial-value '()))
(directories default-directory)
(defun git-top-level-p (dir)
"Return non-nil if DIR is top-level of the work-tree."
(let ((top-level (string-chop-newline (shell-command-to-string "git rev-parse --show-toplevel"))))
(string= (file-name-as-directory top-level)
(file-name-as-directory dir))))
(git-top-level-p default-directory)
(defun redirect-stderr-to-null ()
"Generate cross platform stderr redirect."
(if (eql 'w32 (window-system))
" 2> nul "
" 2> /dev/null "))
(redirect-stderr-to-null)
(defun git-branch-local ()
"Return the local git branch at pwd.
Returns an empty string if we are not in a git work-tree."
(string-trim (shell-command-to-string (format "git symbolic-ref --short %s" (redirect-stderr-to-null)))))
(git-branch-local)
(defun git-remote-for (local-branch)
"Return the remote for LOCAL-BRANCH at pwd.
Returns an empty string if we are not in a git work-tree."
(string-trim (shell-command-to-string (format "git config --get branch.%s.remote %s" local-branch (redirect-stderr-to-null)))))
(git-remote-for "main")
(defun git-local-branch-ahead-of-remote (local-branch remote)
"Return the number of commits LOCAL-BRANCH is ahead of REMOTE (or 0)."
(let* ((log (shell-command-to-string (format "git log %2$s/%1$s..%1$s --oneline %3$s" local-branch remote (redirect-stderr-to-null))))
(count (s-count-matches "\n" log)))
count))
(cd "ayah")
(git-local-branch-ahead-of-remote "main" "origin")
(defun git-local-branch-behind-remote (local-branch remote)
"Return the number of commits LOCAL-BRANCH is behind REMOTE (or 0)."
(let* ((log (shell-command-to-string (format "git log %1$s..%2$s/%1$s --oneline %3$s" local-branch remote (redirect-stderr-to-null))))
(count (s-count-matches "\n" log)))
count))
(git-local-branch-behind-remote "main" "origin")
Ok throw these into *scratch*
and see if they work as expected on Windows... I don't have access to a Windows machine.
use (cd "c:\a-git-repo-you-have\")
and (cd "c:\")
(or however that's supposed to work.) to check the behavior when in and out of a repo.
I'm sure we can make this thing cross platform.
Warning (emacs): Fail invoke git command buffer: #
reason:(exited abnormally with code 255
FIND: Parameter format not correct
'tr' is not recognized as an internal or external command,
operable program or batch file.
)