]> code.delx.au - gnu-emacs/blobdiff - lisp/org/org-attach.el
Update copyright year to 2015
[gnu-emacs] / lisp / org / org-attach.el
index 3e665b79da8af702e22abb88f30c3d7c67f742bb..71e2dbabdb20bc2e235e312d751f9fc2bb51e7fb 100644 (file)
@@ -1,6 +1,6 @@
 ;;; org-attach.el --- Manage file attachments to org-mode tasks
 
-;; Copyright (C) 2008-2013 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2015 Free Software Foundation, Inc.
 
 ;; Author: John Wiegley <johnw@newartisans.com>
 ;; Keywords: org data task
@@ -41,6 +41,7 @@
   (require 'cl))
 (require 'org-id)
 (require 'org)
+(require 'vc-git)
 
 (defgroup org-attach nil
   "Options concerning entry attachments in Org-mode."
@@ -54,6 +55,15 @@ where the Org file lives."
   :group 'org-attach
   :type 'directory)
 
+(defcustom org-attach-git-annex-cutoff (* 32 1024)
+  "If non-nil, files larger than this will be annexed instead of stored."
+  :group 'org-attach
+  :version "24.4"
+  :package-version '(Org . "8.0")
+  :type '(choice
+         (const :tag "None" nil)
+         (integer :tag "Bytes")))
+
 (defcustom org-attach-auto-tag "ATTACH"
   "Tag that will be triggered automatically when an entry has an attachment."
   :group 'org-attach
@@ -198,7 +208,9 @@ the directory and (if necessary) the corresponding ID will be created."
            (save-excursion
              (save-restriction
                (widen)
-               (goto-char org-entry-property-inherited-from)
+               (if (marker-position org-entry-property-inherited-from)
+                   (goto-char org-entry-property-inherited-from)
+                 (org-back-to-heading t))
                (let (org-attach-allow-inheritance)
                  (org-attach-dir create-if-not-exists-p)))))
       (org-attach-check-absolute-path attach-dir)
@@ -252,18 +264,32 @@ the ATTACH_DIR property) their own attachment directory."
 (defun org-attach-commit ()
   "Commit changes to git if `org-attach-directory' is properly initialized.
 This checks for the existence of a \".git\" directory in that directory."
-  (let ((dir (expand-file-name org-attach-directory)))
-    (when (file-exists-p (expand-file-name ".git" dir))
+  (let* ((dir (expand-file-name org-attach-directory))
+        (git-dir (vc-git-root dir))
+        (changes 0))
+    (when (and git-dir (executable-find "git"))
       (with-temp-buffer
        (cd dir)
-       (shell-command "git add .")
-       (shell-command "git ls-files --deleted" t)
-       (mapc #'(lambda (file)
-                 (unless (string= file "")
-                   (shell-command
-                    (concat "git rm \"" file "\""))))
-             (split-string (buffer-string) "\n"))
-       (shell-command "git commit -m 'Synchronized attachments'")))))
+       (let ((have-annex
+              (and org-attach-git-annex-cutoff
+                   (file-exists-p (expand-file-name "annex" git-dir)))))
+         (dolist (new-or-modified
+                  (split-string
+                   (shell-command-to-string
+                    "git ls-files -zmo --exclude-standard") "\0" t))
+           (if (and have-annex
+                    (>= (nth 7 (file-attributes new-or-modified))
+                        org-attach-git-annex-cutoff))
+               (call-process "git" nil nil nil "annex" "add" new-or-modified)
+             (call-process "git" nil nil nil "add" new-or-modified))
+           (incf changes)))
+       (dolist (deleted
+                (split-string
+                 (shell-command-to-string "git ls-files -z --deleted") "\0" t))
+         (call-process "git" nil nil nil "rm" deleted)
+         (incf changes))
+       (when (> changes 0)
+         (shell-command "git commit -m 'Synchronized attachments'"))))))
 
 (defun org-attach-tag (&optional off)
   "Turn the autotag on or (if OFF is set) off."
@@ -405,14 +431,14 @@ This ignores files starting with a \".\", and files ending in \"~\"."
                (directory-files dir nil "[^~]\\'"))))
 
 (defun org-attach-reveal (&optional if-exists)
-  "Show the attachment directory of the current task in dired."
+  "Show the attachment directory of the current task.
+This will attempt to use an external program to show the directory."
   (interactive "P")
   (let ((attach-dir (org-attach-dir (not if-exists))))
     (and attach-dir (org-open-file attach-dir))))
 
 (defun org-attach-reveal-in-emacs ()
-  "Show the attachment directory of the current task.
-This will attempt to use an external program to show the directory."
+  "Show the attachment directory of the current task in dired."
   (interactive)
   (let ((attach-dir (org-attach-dir t)))
     (dired attach-dir)))