I am sending this as a normal patch, because my previous 1-line patch has not been applied yet, and I don't want the text to reappear here. Eventually I'll make my own repo, but I don't want to deal with it at the moment.
The only thing that doesn't work is doing "=" on a filename, but that seems to require another function to be created. I would love it if someone could apply these changes in a similar way to xgit-diff, so that it actually works. Then I can start trying out git for real. <<BEGIN LOG>> * lisp/xgit.el (xgit-status-line-regexp, xgit-status-untracked-regexp) (xgit-status-renamed-regexp): New variables used to match parts of the xgit-status output. (xgit-parse-status-sort): New function that sorts the xgit-status lines according to status rather than just filename. (xgit-parse-status): Rewrite to search forward for regexps, rather than use split-string. All of the status types I've tried so far are recognized properly and sorted. (xgit-status): Even if git returned a non-zero status, it still can have lines to parse, such as files which have not been added yet. <<END LOG>>
pgpqSKW4AICV8.pgp
Description: PGP signature
=== modified file 'lisp/xgit.el'
--- lisp/xgit.el 2007-06-10 07:57:30 +0000
+++ lisp/xgit.el 2007-06-17 20:29:50 +0000
@@ -91,40 +91,91 @@
(message "Git Version: %s" version))
version))
-;; TODO: update for git
+(defvar xgit-status-line-regexp
+ "^#[ \t]+\\([[:alpha:]][[:alpha:][:blank:]]+\\):\\(?:[ \t]+\\(.+\\)\\)?$"
+ "Regexp that matches a line of status output.
+The first match string is the status type, and the optional
+second match is the file.")
+
+(defvar xgit-status-untracked-regexp "^#\t\\(.+\\)$"
+ "Regexp that matches a line of status output indicating an
+untracked file.
+
+The first match is the file.")
+
+(defvar xgit-status-renamed-regexp "^\\(.+\\) -> \\(.+\\)$"
+ "Regexp that divides a filename string.
+The first match is the original file, and the second match is the
+new file.")
+
+(defun xgit-parse-status-sort (status-list)
+ "Sort STATUS-LIST in the order A, M, R, D, ?."
+ (let ((order '(("A" . 1) ("M" . 2) ("R" . 3) ("D" . 4) ("?" . 5))))
+ (sort status-list
+ #'(lambda (a b)
+ (let ((ao (cdr (assoc (car (cddr a)) order)))
+ (bo (cdr (assoc (car (cddr b)) order))))
+ (and (integerp ao) (integerp bo)
+ (< ao bo)))))))
+
(defun xgit-parse-status (changes-buffer)
(dvc-trace "xgit-parse-status (dolist)")
- (let ((status-list
- (split-string (dvc-buffer-content output) "\n")))
- (with-current-buffer changes-buffer
- (setq dvc-header (format "git status -w for %s\n" default-directory))
- (let ((buffer-read-only)
- status modif modif-char)
- (dolist (elem status-list)
- (unless (string= "" elem)
- (setq modif-char (aref elem 0))
- (cond ((eq modif-char ?M)
- (setq status "M"
- modif "M"))
- ((eq modif-char ?A)
+ (with-current-buffer changes-buffer
+ (setq dvc-header (format "git status for %s\n" default-directory))
+ (with-current-buffer output
+ (save-excursion
+ (goto-char (point-min))
+ (let ((buffer-read-only)
+ (grouping "")
+ status-string
+ file status modif dir orig
+ status-list)
+ (while (re-search-forward xgit-status-line-regexp nil t)
+ (setq status-string (match-string 1)
+ file (match-string 2)
+ modif nil
+ dir nil
+ orig nil)
+ (cond ((or (null file) (string= "" file))
+ (when (string= status-string "Untracked files")
+ (let ((end
+ (save-excursion
+ (re-search-forward xgit-status-line-regexp
+ nil 'end)
+ (point))))
+ (forward-line 2)
+ (while (re-search-forward xgit-status-untracked-regexp
+ end t)
+ (when (match-beginning 1)
+ (setq status-list
+ (cons (list 'file (match-string 1) "?")
+ status-list))))
+ (forward-line -1)))
+ (setq grouping status-string
+ status nil))
+ ((string= status-string "modified")
+ (setq status "M"))
+ ((string= status-string "new file")
(setq status "A"))
- ((eq modif-char ?R)
- (setq status "R"))
- ((eq modif-char ?!)
- (setq status "D"))
- ((eq modif-char ??)
- (setq status "?"))
+ ((string= status-string "deleted")
+ (setq status "D")
+ (when (string= grouping "Changed but not updated")
+ (setq modif "?")))
+ ((string= status-string "renamed")
+ (setq status "R")
+ (when (string-match xgit-status-renamed-regexp file)
+ (setq orig (match-string 1 file)
+ file (match-string 2 file)
+ dir " ")))
(t
- (setq modif nil
- status nil)))
- (when (or modif status)
- (ewoc-enter-last dvc-diff-cookie
- (list 'file
- (substring elem 2)
- status
- modif)))))))))
+ (setq status nil)))
+ (when status
+ (setq status-list (cons (list 'file file status modif dir orig)
+ status-list))))
+ (with-current-buffer changes-buffer
+ (dolist (elem (xgit-parse-status-sort (nreverse status-list)))
+ (ewoc-enter-last dvc-diff-cookie elem))))))))
-;; TODO: update for git
(defun xgit-status (&optional against path)
"Run git status."
(interactive (list nil default-directory))
@@ -145,15 +196,18 @@
(if (> (point-max) (point-min))
(dvc-show-changes-buffer output 'xgit-parse-status
(capture buffer))
- (dvc-diff-no-changes (capture buffer)
- "No changes in %s"
- (capture root))))
- :error
- (dvc-capturing-lambda (output error status arguments)
- (dvc-diff-error-in-process (capture buffer)
- "Error in diff process"
- (capture root)
- output error))))))
+ (dvc-diff-no-changes (capture buffer)
+ "No changes in %s"
+ (capture root)))))
+ :error
+ (dvc-capturing-lambda (output error status arguments)
+ (with-current-buffer (capture buffer)
+ (if (> (point-max) (point-min))
+ (dvc-show-changes-buffer output 'xgit-parse-status
+ (capture buffer))
+ (dvc-diff-no-changes (capture buffer)
+ "No changes in %s"
+ (capture root))))))))
(defcustom git-log-max-count -1
"Number of logs to print. Specify negative value for all logs.
--
Michael Olson -- FSF Associate Member #652 |
http://mwolson.org/ -- Jabber: mwolson_at_hcoop.net | /` |\ | | |
Sysadmin -- Hobbies: Lisp, GP2X, HCoop | |_] | \| |_|
Projects: Emacs, Muse, ERC, EMMS, ErBot, DVC, Planner |
_______________________________________________ Dvc-dev mailing list [email protected] https://mail.gna.org/listinfo/dvc-dev
