git.el: Support for showing unknown/ignored directories.
Instead of recursing into directories that only contain unknown files, display only the directory itself. Its contents can be expanded with git-find-file (bound to C-m). Signed-off-by: Alexandre Julliard <julliard@winehq.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Alexandre Julliard committed
Feb 7, 2008 at 13:50 UTC
3f3d564aa74e80cb30ead37e4581ee21220b4ac4
1 file changed
+29
-9
contrib/emacs/git.el
+29
-9
@@ -558,12 +558,15 @@ and returns the process output as a string."
558
(?\100 " (type change file -> subproject)")
559
(?\120 " (type change symlink -> subproject)")
560
(t " (subproject)")))
561
+ (?\110 nil) ;; directory (internal, not a real git state)
562
(?\000 ;; deleted or unknown
563
(case old-type
564
(?\120 " (symlink)")
565
(?\160 " (subproject)")))
566
(t (format " (unknown type %o)" new-type)))))
566
- (if str (propertize str 'face 'git-status-face) "")))
567
+ (cond (str (propertize str 'face 'git-status-face))
568
+ ((eq new-type ?\110) "/")
569
+ (t ""))))
570
571
(defun git-rename-as-string (info)
572
"Return a string describing the copy or rename associated with INFO, or an empty string if none."
@@ -666,9 +669,11 @@ Return the list of files that haven't been handled."
669
(with-temp-buffer
670
(apply #'git-call-process-env t nil "ls-files" "-z" (append options (list "--") files))
671
(goto-char (point-min))
669
- (while (re-search-forward "\\([^\0]*\\)\0" nil t 1)
672
+ (while (re-search-forward "\\([^\0]*?\\)\\(/?\\)\0" nil t 1)
673
(let ((name (match-string 1)))
671
- (push (git-create-fileinfo default-state name) infolist)
674
+ (push (git-create-fileinfo default-state name 0
675
+ (if (string-equal "/" (match-string 2)) (lsh ?\110 9) 0))
676
+ infolist)
677
(setq files (delete name files)))))
678
(git-insert-info-list status infolist)
679
files))
@@ -713,7 +718,7 @@ Return the list of files that haven't been handled."
718
(defun git-run-ls-files-with-excludes (status files default-state &rest options)
719
"Run git-ls-files on FILES with appropriate --exclude-from options."
720
(let ((exclude-files (git-get-exclude-files)))
716
- (apply #'git-run-ls-files status files default-state
721
+ (apply #'git-run-ls-files status files default-state "--directory"
722
(concat "--exclude-per-directory=" git-per-dir-ignore-file)
723
(append options (mapcar (lambda (f) (concat "--exclude-from=" f)) exclude-files)))))
724
@@ -957,6 +962,7 @@ Return the list of files that haven't been handled."
962
"Add marked file(s) to the index cache."
963
(interactive)
964
(let ((files (git-get-filenames (git-marked-files-state 'unknown 'ignored))))
965
+ ;; FIXME: add support for directories
966
(unless files
967
(push (file-relative-name (read-file-name "File to add: " nil nil t)) files))
968
(apply #'git-call-process-env nil nil "update-index" "--add" "--" files)
@@ -983,7 +989,10 @@ Return the list of files that haven't been handled."
989
(format "Remove %d file%s? " (length files) (if (> (length files) 1) "s" "")))
990
(progn
991
(dolist (name files)
986
- (when (file-exists-p name) (delete-file name)))
992
+ (ignore-errors
993
+ (if (file-directory-p name)
994
+ (delete-directory name)
995
+ (delete-file name))))
996
(apply #'git-call-process-env nil nil "update-index" "--remove" "--" files)
997
(git-update-status-files files nil)
998
(git-success-message "Removed" files))
@@ -992,7 +1001,7 @@ Return the list of files that haven't been handled."
1001
(defun git-revert-file ()
1002
"Revert changes to the marked file(s)."
1003
(interactive)
995
- (let ((files (git-marked-files))
1004
+ (let ((files (git-marked-files-state 'added 'deleted 'modified 'unmerged))
1005
added modified)
1006
(when (and files
1007
(yes-or-no-p
@@ -1063,6 +1072,16 @@ Return the list of files that haven't been handled."
1072
(message "Inserting unknown files...done"))
1073
(git-remove-handled)))
1074
1075
+(defun git-expand-directory (info)
1076
+ "Expand the directory represented by INFO to list its files."
1077
+ (when (eq (lsh (git-fileinfo->new-perm info) -9) ?\110)
1078
+ (let ((dir (git-fileinfo->name info)))
1079
+ (git-set-filenames-state git-status (list dir) nil)
1080
+ (git-run-ls-files-with-excludes git-status (list (concat dir "/")) 'unknown "-o")
1081
+ (git-refresh-files)
1082
+ (git-refresh-ewoc-hf git-status)
1083
+ t)))
1084
+
1085
(defun git-setup-diff-buffer (buffer)
1086
"Setup a buffer for displaying a diff."
1087
(let ((dir default-directory))
@@ -1237,9 +1256,10 @@ Return the list of files that haven't been handled."
1256
(interactive)
1257
(unless git-status (error "Not in git-status buffer."))
1258
(let ((info (ewoc-data (ewoc-locate git-status))))
1240
- (find-file (git-fileinfo->name info))
1241
- (when (eq 'unmerged (git-fileinfo->state info))
1242
- (smerge-mode 1))))
1259
+ (unless (git-expand-directory info)
1260
+ (find-file (git-fileinfo->name info))
1261
+ (when (eq 'unmerged (git-fileinfo->state info))
1262
+ (smerge-mode 1)))))
1263
1264
(defun git-find-file-other-window ()
1265
"Visit the current file in its own buffer in another window."