{"thread":{"id":"3549","subject":"[PATCH] contrib/emacs: Add an Emacs VC backend.","startedAt":"2006-03-04T14:32:19Z","lastAt":"2006-03-04T14:32:19Z","messageCount":1,"participants":["Alexandre Julliard"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"17144","messageId":"87r75il1qk.fsf@wine.dyndns.org","threadId":"3549","inReplyTo":null,"subject":"[PATCH] contrib/emacs: Add an Emacs VC backend.","fromName":"Alexandre Julliard","fromEmail":"julliard@winehq.org","sentAt":"2006-03-04T14:32:19Z","receivedAt":"2006-03-04T14:32:19Z","isPatch":true,"sender":{"key":"julliard@winehq.org","avatar":null},"body":"Add a basic Emacs VC backend. It currently supports the following\ncommands: checkin, checkout, diff, log, revert, and annotate. There is\nonly limited support for working with revisions other than HEAD.\n\nSigned-off-by: Alexandre Julliard <julliard@winehq.org>\n\n---\n\n contrib/emacs/vc-git.el |  135 +++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 135 insertions(+), 0 deletions(-)\n create mode 100644 contrib/emacs/vc-git.el\n\nb0c7984b6da71ab875c40a661b9a743370c41dfb\ndiff --git a/contrib/emacs/vc-git.el b/contrib/emacs/vc-git.el\nnew file mode 100644\nindex 0000000..2453cdc\n--- /dev/null\n+++ b/contrib/emacs/vc-git.el\n@@ -0,0 +1,135 @@\n+;;; vc-git.el --- VC backend for the git version control system\n+\n+;; Copyright (C) 2006 Alexandre Julliard\n+\n+;; This program is free software; you can redistribute it and/or\n+;; modify it under the terms of the GNU General Public License as\n+;; published by the Free Software Foundation; either version 2 of\n+;; the License, or (at your option) any later version.\n+;;\n+;; This program is distributed in the hope that it will be\n+;; useful, but WITHOUT ANY WARRANTY; without even the implied\n+;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR\n+;; PURPOSE.  See the GNU General Public License for more details.\n+;;\n+;; You should have received a copy of the GNU General Public\n+;; License along with this program; if not, write to the Free\n+;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,\n+;; MA 02111-1307 USA\n+\n+;;; Commentary:\n+\n+;; This file contains a VC backend for the git version control\n+;; system.\n+;;\n+;; To install: put this file on the load-path and add GIT to the list\n+;; of supported backends in `vc-handled-backends'.\n+;;\n+;; TODO\n+;;  - changelog generation\n+;;  - working with revisions other than HEAD\n+;;\n+\n+(defvar git-commits-coding-system 'utf-8\n+  \"Default coding system for git commits.\")\n+\n+(defun vc-git--run-command-string (file &rest args)\n+  \"Run a git command on FILE and return its output as string.\"\n+  (let* ((ok t)\n+         (str (with-output-to-string\n+                (with-current-buffer standard-output\n+                  (unless (eq 0 (apply #'call-process \"git\" nil '(t nil) nil\n+                                       (append args (list (file-relative-name file)))))\n+                    (setq ok nil))))))\n+    (and ok str)))\n+\n+(defun vc-git--run-command (file &rest args)\n+  \"Run a git command on FILE, discarding any output.\"\n+  (let ((name (file-relative-name file)))\n+    (eq 0 (apply #'call-process \"git\" nil (get-buffer \"*Messages\") nil (append args (list name))))))\n+\n+(defun vc-git-registered (file)\n+  \"Check whether FILE is registered with git.\"\n+  (with-temp-buffer\n+    (let* ((dir (file-name-directory file))\n+           (name (file-relative-name file dir)))\n+      (when dir (cd dir))\n+      (and (eq 0 (call-process \"git\" nil '(t nil) nil \"ls-files\" \"-c\" \"-z\" \"--\" name))\n+           (let ((str (buffer-string)))\n+             (and (> (length str) (length name))\n+                  (string= (substring str 0 (1+ (length name))) (concat name \"\\0\"))))))))\n+\n+(defun vc-git-state (file)\n+  \"git-specific version of `vc-state'.\"\n+  (let ((diff (vc-git--run-command-string file \"diff-index\" \"-z\" \"HEAD\" \"--\")))\n+    (if (and diff (string-match \":[0-7]\\\\{6\\\\} [0-7]\\\\{6\\\\} [0-9a-f]\\\\{40\\\\} [0-9a-f]\\\\{40\\\\} [ADMU]\\0[^\\0]+\\0\" diff))\n+        'edited\n+      'up-to-date)))\n+\n+(defun vc-git-workfile-version (file)\n+  \"git-specific version of `vc-workfile-version'.\"\n+  (let ((str (with-output-to-string\n+               (with-current-buffer standard-output\n+                 (call-process \"git\" nil '(t nil) nil \"symbolic-ref\" \"HEAD\")))))\n+    (if (string-match \"^\\\\(refs/heads/\\\\)?\\\\(.+\\\\)$\" str)\n+        (match-string 2 str)\n+      str)))\n+\n+(defun vc-git-revert (file &optional contents-done)\n+  \"Revert FILE to the version stored in the git repository.\"\n+  (if contents-done\n+      (vc-git--run-command file \"update-index\" \"--\")\n+    (vc-git--run-command file \"checkout\" \"HEAD\")))\n+\n+(defun vc-git-checkout-model (file)\n+  'implicit)\n+\n+(defun vc-git-workfile-unchanged-p (file)\n+  (let ((sha1 (vc-git--run-command-string file \"hash-object\" \"--\"))\n+        (head (vc-git--run-command-string file \"ls-tree\" \"-z\" \"HEAD\" \"--\")))\n+    (and head\n+         (string-match \"[0-7]\\\\{6\\\\} blob \\\\([0-9a-f]\\\\{40\\\\}\\\\)\\t[^\\0]+\\0\" head)\n+         (string= (car (split-string sha1 \"\\n\")) (match-string 1 head)))))\n+\n+(defun vc-git-register (file &optional rev comment)\n+  \"Register FILE into the git version-control system.\"\n+  (vc-git--run-command file \"update-index\" \"--add\" \"--\"))\n+\n+(defun vc-git-print-log (file)\n+  (let ((name (file-relative-name file))\n+        (coding-system-for-read git-commits-coding-system))\n+    (vc-do-command nil 'async \"git\" name \"rev-list\" \"--pretty\" \"HEAD\" \"--\")))\n+\n+(defun vc-git-diff (file &optional rev1 rev2)\n+  (let ((name (file-relative-name file)))\n+    (if (and rev1 rev2)\n+        (vc-do-command \"*vc-diff*\" 0 \"git\" name \"diff-tree\" \"-p\" rev1 rev2 \"--\")\n+      (vc-do-command \"*vc-diff*\" 0 \"git\" name \"diff-index\" \"-p\" (or rev1 \"HEAD\") \"--\"))\n+    ; git-diff-index doesn't set exit status like diff does\n+    (if (vc-git-workfile-unchanged-p file) 0 1)))\n+\n+(defun vc-git-checkin (file rev comment)\n+  (let ((coding-system-for-write git-commits-coding-system))\n+    (vc-git--run-command file \"commit\" \"-m\" comment \"--only\" \"--\")))\n+\n+(defun vc-git-checkout (file &optional editable rev destfile)\n+  (vc-git--run-command file \"checkout\" (or rev \"HEAD\")))\n+\n+(defun vc-git-annotate-command (file buf &optional rev)\n+  ; FIXME: rev is ignored\n+  (let ((name (file-relative-name file)))\n+    (call-process \"git\" nil buf nil \"annotate\" name)))\n+\n+(defun vc-git-annotate-time ()\n+  (and (re-search-forward \"[0-9a-f]+\\t(.*\\t\\\\([0-9]+\\\\)-\\\\([0-9]+\\\\)-\\\\([0-9]+\\\\) \\\\([0-9]+\\\\):\\\\([0-9]+\\\\):\\\\([0-9]+\\\\) \\\\([-+0-9]+\\\\)\\t[0-9]+)\" nil t)\n+       (vc-annotate-convert-time\n+        (apply #'encode-time (mapcar (lambda (match) (string-to-number (match-string match))) '(6 5 4 3 2 1 7))))))\n+\n+;; Not really useful since we can't do anything with the revision yet\n+;;(defun vc-annotate-extract-revision-at-line ()\n+;;  (save-excursion\n+;;    (move-beginning-of-line 1)\n+;;    (and (looking-at \"[0-9a-f]+\")\n+;;         (buffer-substring (match-beginning 0) (match-end 0)))))\n+\n+(provide 'vc-git)\n-- \n1.2.4.g0040-dirty\n\n-- \nAlexandre Julliard\njulliard@winehq.org\n"}]}