branch: master
commit fe95f52772c6e25c54085fcaca189296bb0c8aad
Author: nathan moreau <[email protected]>
Commit: Oleh Krehel <[email protected]>

    Unify the different ways to check for git.
    
    Merge both variables counsel--git-dir and counsel--git-grep-dir.
---
 counsel.el | 179 ++++++++++++++++++++++++++++---------------------------------
 1 file changed, 81 insertions(+), 98 deletions(-)

diff --git a/counsel.el b/counsel.el
index 37c1928..536dee9 100644
--- a/counsel.el
+++ b/counsel.el
@@ -1006,27 +1006,29 @@ BUFFER defaults to the current one."
    ("x" counsel-find-file-extern "open externally")))
 
 ;;;###autoload
+(defun counsel-locate-git-root ()
+  "Locate the root of the git repository containing the current buffer."
+  (setq counsel--git-dir (locate-dominating-file default-directory ".git"))
+  (and (null counsel--git-dir) (error "Not in a git repository"))
+  counsel--git-dir)
+
 (defun counsel-git (&optional initial-input)
   "Find file in the current Git repository.
 INITIAL-INPUT can be given as the initial minibuffer input."
   (interactive)
   (counsel-require-program (car (split-string counsel-git-cmd)))
-  (setq counsel--git-dir (locate-dominating-file
-                          default-directory ".git"))
+  (counsel-locate-git-root)
   (ivy-set-prompt 'counsel-git counsel-prompt-function)
-  (if (null counsel--git-dir)
-      (error "Not in a git repository")
-    (setq counsel--git-dir (expand-file-name
-                            counsel--git-dir))
-    (let* ((default-directory counsel--git-dir)
-           (cands (split-string
-                   (shell-command-to-string counsel-git-cmd)
-                   "\n"
-                   t)))
-      (ivy-read "Find file" cands
-                :initial-input initial-input
-                :action #'counsel-git-action
-                :caller 'counsel-git))))
+  (setq counsel--git-dir (expand-file-name counsel--git-dir))
+  (let* ((default-directory counsel--git-dir)
+         (cands (split-string
+                 (shell-command-to-string counsel-git-cmd)
+                 "\n"
+                 t)))
+    (ivy-read "Find file" cands
+              :initial-input initial-input
+              :action #'counsel-git-action
+              :caller 'counsel-git)))
 
 (defun counsel-git-action (x)
   "Find file X in current Git repository."
@@ -1051,9 +1053,6 @@ INITIAL-INPUT can be given as the initial minibuffer 
input."
 (defvar counsel-git-grep-cmd nil
   "Store the command for `counsel-git-grep'.")
 
-(defvar counsel--git-grep-dir nil
-  "Store the base git directory.")
-
 (defvar counsel--git-grep-count nil
   "Store the line count in current repository.")
 
@@ -1073,7 +1072,7 @@ Typical value: '(recenter)."
 (defun counsel-prompt-function-dir ()
   "Return prompt appended with the parent directory."
   (ivy-add-prompt-count
-   (let ((directory counsel--git-grep-dir))
+   (let ((directory counsel--git-dir))
      (format "%s [%s]: "
              (ivy-state-prompt ivy-last)
              (let ((dir-list (eshell-split-path directory)))
@@ -1093,7 +1092,7 @@ Typical value: '(recenter)."
   (if (and (or counsel-git-grep-skip-counting-lines (> counsel--git-grep-count 
20000))
            (< (length string) 3))
       (counsel-more-chars 3)
-    (let* ((default-directory counsel--git-grep-dir)
+    (let* ((default-directory counsel--git-dir)
            (cmd (format counsel-git-grep-cmd
                         (setq ivy--old-re (ivy--regex string t)))))
       (if (and (not counsel-git-grep-skip-counting-lines) (<= 
counsel--git-grep-count 20000))
@@ -1107,7 +1106,7 @@ Typical value: '(recenter)."
     (with-ivy-window
       (let ((file-name (match-string-no-properties 1 x))
             (line-number (match-string-no-properties 2 x)))
-        (find-file (expand-file-name file-name counsel--git-grep-dir))
+        (find-file (expand-file-name file-name counsel--git-dir))
         (goto-char (point-min))
         (forward-line (1- (string-to-number line-number)))
         (re-search-forward (ivy--regex ivy-text t) (line-end-position) t)
@@ -1195,37 +1194,32 @@ INITIAL-INPUT can be given as the initial minibuffer 
input."
     (setq proj (car proj-and-cmd))
     (setq counsel-git-grep-cmd (cdr proj-and-cmd))
     (counsel-require-program (car (split-string counsel-git-grep-cmd)))
-    (setq counsel--git-grep-dir
-          (if proj
-              (car proj)
-            (locate-dominating-file default-directory ".git")))
-    (if (null counsel--git-grep-dir)
-        (error "Not in a git repository")
-      (unless (or proj counsel-git-grep-skip-counting-lines)
-        (setq counsel--git-grep-count
-              (if (eq system-type 'windows-nt)
-                  0
-                (counsel--gg-count "" t))))
-      (let ((collection-function
-             (if proj
-                 #'counsel-git-grep-proj-function
-               #'counsel-git-grep-function))
-            (unwind-function
-             (if proj
-                 (lambda ()
-                   (counsel-delete-process)
-                   (swiper--cleanup))
+    (counsel-locate-git-root)
+    (unless (or proj counsel-git-grep-skip-counting-lines)
+      (setq counsel--git-grep-count
+            (if (eq system-type 'windows-nt)
+                0
+              (counsel--gg-count "" t))))
+    (let ((collection-function
+           (if proj
+               #'counsel-git-grep-proj-function
+             #'counsel-git-grep-function))
+          (unwind-function
+           (if proj
                (lambda ()
-                 (swiper--cleanup)))))
-        (ivy-read "git grep" collection-function
-                  :initial-input initial-input
-                  :matcher #'counsel-git-grep-matcher
-                  :dynamic-collection (or proj 
counsel-git-grep-skip-counting-lines (> counsel--git-grep-count 20000))
-                  :keymap counsel-git-grep-map
-                  :action #'counsel-git-grep-action
-                  :unwind unwind-function
-                  :history 'counsel-git-grep-history
-                  :caller 'counsel-git-grep)))))
+                 (counsel-delete-process)
+                 (swiper--cleanup))
+             (lambda ()
+               (swiper--cleanup)))))
+      (ivy-read "git grep" collection-function
+                :initial-input initial-input
+                :matcher #'counsel-git-grep-matcher
+                :dynamic-collection (or proj 
counsel-git-grep-skip-counting-lines (> counsel--git-grep-count 20000))
+                :keymap counsel-git-grep-map
+                :action #'counsel-git-grep-action
+                :unwind unwind-function
+                :history 'counsel-git-grep-history
+                :caller 'counsel-git-grep))))
 
 (defun counsel-git-grep-proj-function (str)
   "Grep for STR in the current git repository."
@@ -1255,7 +1249,7 @@ INITIAL-INPUT can be given as the initial minibuffer 
input."
   "Return git grep candidates for REGEX."
   (setq counsel-gg-state -2)
   (counsel--gg-count regex)
-  (let* ((default-directory counsel--git-grep-dir)
+  (let* ((default-directory counsel--git-dir)
          (counsel-gg-process " *counsel-gg*")
          (proc (get-process counsel-gg-process))
          (buff (get-buffer counsel-gg-process)))
@@ -1296,7 +1290,7 @@ EVENT is a string describing the change."
   "Count the number of results matching REGEX in `counsel-git-grep'.
 The command to count the matches is called asynchronously.
 If NO-ASYNC is non-nil, do it synchronously instead."
-  (let ((default-directory counsel--git-grep-dir)
+  (let ((default-directory counsel--git-dir)
         (cmd
          (concat
           (format
@@ -1335,7 +1329,7 @@ If NO-ASYNC is non-nil, do it synchronously instead."
 When REVERT is non-nil, regenerate the current *ivy-occur* buffer."
   (unless (eq major-mode 'ivy-occur-grep-mode)
     (ivy-occur-grep-mode)
-    (setq default-directory counsel--git-grep-dir))
+    (setq default-directory counsel--git-dir))
   (setq ivy-text
         (and (string-match "\"\\(.*\\)\"" (buffer-name))
              (match-string 1 (buffer-name))))
@@ -1370,7 +1364,7 @@ When REVERT is non-nil, regenerate the current 
*ivy-occur* buffer."
              (when (string-match "\\`\\(.*?\\):\\([0-9]+\\):\\(.*\\)\\'" cand)
                (with-ivy-window
                  (let ((file-name (match-string-no-properties 1 cand)))
-                   (setq file-name (expand-file-name file-name 
counsel--git-grep-dir))
+                   (setq file-name (expand-file-name file-name 
counsel--git-dir))
                    (unless (member file-name done-buffers)
                      (push file-name done-buffers)
                      (find-file file-name)
@@ -1388,17 +1382,15 @@ The git command applies the stash entry where candidate 
X was found in."
 (defun counsel-git-stash ()
   "Search through all available git stashes."
   (interactive)
-  (let ((dir (locate-dominating-file default-directory ".git")))
-    (if (null dir)
-        (error "Not in a git repository")
-      (let ((cands (split-string (shell-command-to-string
-                                  "IFS=$'\n'
+  (counsel-locate-git-root)
+  (let ((cands (split-string (shell-command-to-string
+                              "IFS=$'\n'
 for i in `git stash list --format=\"%gd\"`; do
     git stash show -p $i | grep -H --label=\"$i\" \"$1\"
 done") "\n" t)))
-        (ivy-read "git stash: " cands
-                  :action 'counsel-git-stash-kill-action
-                  :caller 'counsel-git-stash)))))
+    (ivy-read "git stash: " cands
+              :action 'counsel-git-stash-kill-action
+              :caller 'counsel-git-stash)))
 ;;** `counsel-git-log'
 (defvar counsel-git-log-cmd "GIT_PAGER=cat git log --grep '%s'"
   "Command used for \"git log\".")
@@ -1442,31 +1434,23 @@ TREE is the selected candidate."
 
 (defun counsel-git-worktree-list ()
   "List worktrees in the git repository containing the current buffer."
+  (counsel-locate-git-root)
   (let ((cmd-output (shell-command-to-string "git worktree list")))
-    (and (string-match "fatal: Not a git repository" cmd-output)
-         (error "Not in a git repository!"))
     (delete "" (split-string (string-trim-right cmd-output) "\n"))))
 
 (defun counsel-git-worktree-parse-root (tree)
   "Return worktree from candidate TREE."
   (substring tree 0 (string-match " " tree)))
 
-(defun counsel-git-toplevel ()
-  "Return the base directory of the current git repository."
-  (let ((out (string-trim-right (shell-command-to-string "git rev-parse 
--show-toplevel"))))
-    (unless (string-match-p "Not a git repository" out) out)))
-
 (defun counsel-git-close-worktree-files-action (root-dir)
   "Close all buffers from the worktree located at ROOT-DIR."
   (setq root-dir (counsel-git-worktree-parse-root root-dir))
   (save-excursion
     (dolist (buf (buffer-list))
       (set-buffer buf)
-      (let (top)
-        (and buffer-file-name
-             (setq top (counsel-git-toplevel))
-             (string= "." (file-relative-name root-dir top))
-             (kill-buffer buf))))))
+      (and buffer-file-name
+           (string= "." (file-relative-name root-dir 
(counsel-locate-git-root)))
+           (kill-buffer buf)))))
 
 (ivy-set-actions
  'counsel-git-change-worktree
@@ -1476,14 +1460,14 @@ TREE is the selected candidate."
 (defun counsel-git-change-worktree ()
   "Find the file corresponding to the current buffer on a different worktree."
   (interactive)
-  (let ((git-root-dir (counsel-git-toplevel)))
-    (ivy-read "Select worktree: "
-              (or (cl-delete git-root-dir (counsel-git-worktree-list)
-                             :key #'counsel-git-worktree-parse-root :test 
#'string=)
-                  (error "No other worktrees!"))
-              :action (lambda (tree) (counsel-git-change-worktree-action 
git-root-dir tree))
-              :require-match t
-              :caller 'counsel-git-change-worktree)))
+  (counsel-locate-git-root)
+  (ivy-read "Select worktree: "
+            (or (cl-delete counsel--git-dir (counsel-git-worktree-list)
+                           :key #'counsel-git-worktree-parse-root :test 
#'string=)
+                (error "No other worktrees!"))
+            :action (lambda (tree) (counsel-git-change-worktree-action 
counsel--git-dir tree))
+            :require-match t
+            :caller 'counsel-git-change-worktree))
 
 ;;** `counsel-git-checkout'
 (defun counsel-git-checkout-action (branch)
@@ -1498,9 +1482,8 @@ BRANCH is a string whose first word designates the 
command argument."
   "List branches in the git repository containing the current buffer.
 
 Does not list the currently checked out one."
+  (counsel-locate-git-root)
   (let ((cmd-output (shell-command-to-string "git branch -vv --all")))
-    (and (string-match "fatal: Not a git repository" cmd-output)
-         (error "Not in a git repository!"))
     (cl-mapcan
      (lambda (str) (when (string-prefix-p " " str)
                      (list (substring str (string-match (rx (not (any blank))) 
str)))))
@@ -1920,7 +1903,7 @@ INITIAL-DIRECTORY, if non-nil, is used as the root 
directory for search."
 ;;* Grep
 (defun counsel--grep-mode-occur (git-grep-dir-is-file)
   "Generate a custom occur buffer for grep like commands.
-If GIT-GREP-DIR-IS-FILE is t, then `counsel--git-grep-dir' is treated as a full
+If GIT-GREP-DIR-IS-FILE is t, then `counsel--git-dir' is treated as a full
 path to a file rather than a directory (e.g. for `counsel-grep-occur').
 
 This function expects that the candidates have already been filtered.
@@ -1929,11 +1912,11 @@ It applies no filtering to ivy--all-candidates."
     (ivy-occur-grep-mode))
   (let* ((directory
           (if git-grep-dir-is-file
-              (file-name-directory counsel--git-grep-dir)
-            counsel--git-grep-dir))
+              (file-name-directory counsel--git-dir)
+            counsel--git-dir))
          (prepend
           (if git-grep-dir-is-file
-              (concat (file-name-nondirectory counsel--git-grep-dir) ":")
+              (concat (file-name-nondirectory counsel--git-dir) ":")
             "")))
     (setq default-directory directory)
     ;; Need precise number of header lines for `wgrep' to work.
@@ -1967,7 +1950,7 @@ If non-nil, append EXTRA-AG-ARGS to BASE-CMD."
     (setq extra-ag-args ""))
   (if (< (length string) 3)
       (counsel-more-chars 3)
-    (let ((default-directory counsel--git-grep-dir)
+    (let ((default-directory counsel--git-dir)
           (regex (counsel-unquote-regex-parens
                   (setq ivy--old-re
                         (ivy--regex string)))))
@@ -2011,7 +1994,7 @@ AG-PROMPT, if non-nil, is passed as `ivy-read' prompt 
argument."
                                "%s" "" (substring-no-properties 
counsel-ag-base-command pos))))
                 (read-string (format "(%s) args:" command) ag-args)))))
   (ivy-set-prompt 'counsel-ag counsel-prompt-function)
-  (setq counsel--git-grep-dir (or initial-directory default-directory))
+  (setq counsel--git-dir (or initial-directory default-directory))
   (ivy-read (or ag-prompt (car (split-string counsel-ag-base-command)))
             (lambda (string)
               (counsel-ag-function string counsel-ag-base-command 
extra-ag-args))
@@ -2091,9 +2074,9 @@ RG-PROMPT, if non-nil, is passed as `ivy-read' prompt 
argument."
                                  " in directory: ")))))
   (counsel-require-program (car (split-string counsel-rg-base-command)))
   (ivy-set-prompt 'counsel-rg counsel-prompt-function)
-  (setq counsel--git-grep-dir (or initial-directory
-                                  (locate-dominating-file default-directory 
".git")
-                                  default-directory))
+  (setq counsel--git-dir (or initial-directory
+                             (locate-dominating-file default-directory ".git")
+                             default-directory))
   (ivy-read (or rg-prompt (car (split-string counsel-rg-base-command)))
             (lambda (string)
               (counsel-ag-function string counsel-rg-base-command 
extra-rg-args))
@@ -2126,17 +2109,17 @@ RG-PROMPT, if non-nil, is passed as `ivy-read' prompt 
argument."
                         (ivy--regex string)))))
       (counsel--async-command
        (format counsel-grep-base-command regex
-               (shell-quote-argument counsel--git-grep-dir)))
+               (shell-quote-argument counsel--git-dir)))
       nil)))
 
 (defun counsel-grep-action (x)
   "Go to candidate X."
   (with-ivy-window
     (swiper--cleanup)
-    (let ((default-directory (file-name-directory counsel--git-grep-dir))
+    (let ((default-directory (file-name-directory counsel--git-dir))
           file-name line-number)
       (when (cond ((string-match "\\`\\([0-9]+\\):\\(.*\\)\\'" x)
-                   (setq file-name counsel--git-grep-dir)
+                   (setq file-name counsel--git-dir)
                    (setq line-number (match-string-no-properties 1 x)))
                   ((string-match "\\`\\([^:]+\\):\\([0-9]+\\):\\(.*\\)\\'" x)
                    (setq file-name (match-string-no-properties 1 x))
@@ -2177,7 +2160,7 @@ RG-PROMPT, if non-nil, is passed as `ivy-read' prompt 
argument."
   (interactive)
   (counsel-require-program (car (split-string counsel-grep-base-command)))
   (setq counsel-grep-last-line nil)
-  (setq counsel--git-grep-dir (buffer-file-name))
+  (setq counsel--git-dir (buffer-file-name))
   (let ((init-point (point))
         res)
     (unwind-protect

Reply via email to