Resolving duplicate ID's in org-mode - Emacs Stack Exchange
ID: 669d0144-fabf-4874-9ac9-9c1c08a134c3 ROAM_REFS: https://emacs.stackexchange.com/questions/24646/resolving-duplicate-ids-in-org-mode REVIEW_SCORE: 4.0 MTIME: [2025-02-02 Sun 20:29],[2024-12-25 Wed 16:06]
(defun my/org-id-update-id-locations (&optional files silent) "Scan relevant files for IDs. Store the relation between files and corresponding IDs. This will scan all agenda files, all associated archives, and all files currently mentioned in `org-id-locations'. When FILES is given, scan these files instead." (interactive) (if (not org-id-track-globally) (error "Please turn on `org-id-track-globally' if you want to track IDs") (let* ((org-id-search-archives (or org-id-search-archives (and (symbolp org-id-extra-files) (symbol-value org-id-extra-files) (member 'agenda-archives org-id-extra-files)))) (files (or files (append ;; Agenda files and all associated archives (org-agenda-files t org-id-search-archives) ;; Explicit extra files (if (symbolp org-id-extra-files) (symbol-value org-id-extra-files) org-id-extra-files) ;; Files associated with live Org buffers (delq nil (mapcar (lambda (b) (with-current-buffer b (and (derived-mode-p 'org-mode) (buffer-file-name)))) (buffer-list))) ;; All files known to have IDs org-id-files))) org-agenda-new-buffers file nfiles tfile ids reg found id seen (ndup 0)) (when (member 'agenda-archives files) (setq files (delq 'agenda-archives (copy-sequence files)))) (setq nfiles (length files)) (while (setq file (pop files)) (unless silent (message "Finding ID locations (%d/%d files): %s" (- nfiles (length files)) nfiles file)) (setq tfile (file-truename file)) (when (and (file-exists-p file) (not (member tfile seen))) (push tfile seen) (setq ids nil) (with-current-buffer (org-get-agenda-file-buffer file) (save-excursion (save-restriction (widen) (goto-char (point-min)) (while (re-search-forward "^[ \t]*:ID:[ \t]+\\(\\S-+\\)[ \t]*$" nil t) (setq id (match-string-no-properties 1)) (if (member id found) (progn ;added logic (if org-clone-delete-id (org-entry-delete nil "ID") (org-id-get-create t)) ;end of added logic (message "Duplicate ID \"%s\", also in file %s" id (or (car (delq nil (mapcar (lambda (x) (if (member id (cdr x)) (car x))) reg))) (buffer-file-name))) (when (= ndup 0) (ding) (sit-for 2)) (setq ndup (1+ ndup))) (push id found) (push id ids))) (push (cons (abbreviate-file-name file) ids) reg)))))) (org-release-buffers org-agenda-new-buffers) (setq org-agenda-new-buffers nil) (setq org-id-locations reg) (setq org-id-files (mapcar 'car org-id-locations)) (org-id-locations-save) ;; this function can also handle the alist form ;; now convert to a hash (setq org-id-locations (org-id-alist-to-hash org-id-locations)) (if (> ndup 0) (message "WARNING: %d duplicate IDs found, check *Messages* buffer" ndup) (message "%d unique files scanned for IDs" (length org-id-files))) org-id-locations)))
This node is a singleton!