    (funcall mode)
    (setq git-timemachine-directory git-directory
          git-timemachine-file (file-relative-name file-name git-directory)
-         git-timemachine-revision nil)
-   (git-timemachine-show-current-revision)
+    git-timemachine-revision nil)
+   (funcall get-revision-fn)
    (goto-char (point-min))
    (forward-line (1- cur-line))
    (git-timemachine-mode))))
 
+;;;###autoload
+(defun git-timemachine-toggle ()
+ "Toggle git timemachine mode."
+ (interactive)
+ (if (bound-and-true-p git-timemachine-mode)
+  (git-timemachine-quit)
+  (git-timemachine)))
+
+;;;###autoload
+(defun git-timemachine ()
+ "Enable git timemachine for file of current buffer."
+ (interactive)
+ (git-timemachine--start #'git-timemachine-show-current-revision))
+
+;;;###autoload
+(defun git-timemachine-switch-branch (git-branch)
+ "Enable git timemachine for current buffer, switching to GIT-BRANCH."
+ (interactive (list (git-timemachine-completing-read-fn "Branch to switch to: "(vc-git-branches))))
+ (git-timemachine--start (lambda () (git-timemachine-show-latest-revision-in-branch git-branch))))
+
 (provide 'git-timemachine)
 
 ;;; git-timemachine.el ends here

 :type '(radio (const :tag "Commit SHA" commit) (const :tag "Commit Subject" subject))
 :group 'git-timemachine)

(defvar-local git-timemachine-directory nil)
(defvar-local git-timemachine-revision nil)
(defvar-local git-timemachine-file nil)
(defvar-local git-timemachine--revisions-cache nil)

(defun git-timemachine--revisions ()
 "List git revisions of current buffers file."
 (if git-timemachine--revisions-cache
  git-timemachine--revisions-cache
  (setq git-timemachine--revisions-cache

    (let ((default-directory git-timemachine-directory)
          (file git-timemachine-file))
     (with-temp-buffer

      (unless (zerop (if git-branch
                      (process-file vc-git-program nil t nil "--no-pager" "log" git-branch "--name-only" "--follow" "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file)
                      (process-file vc-git-program nil t nil "--no-pager" "log" "--name-only" "--follow" "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file)))
       (error "Git log command exited with non-zero exit status for file: %s" file))

      (goto-char (point-min))
      (let ((lines)
            (commit-number (/ (1+ (count-lines (point-min) (point-max))) 3)))
       (while (not (eobp))
        (let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
         (string-match "\\([^\0]*\\)\0\\([^\0]*\\)\0\\([^\0]*\\)\0\\(.*\\)\0\\(.*\\)" line)
         (let ((commit (match-string 1 line))
               (date-relative (match-string 2 line))
               (date-full (match-string 3 line))
               (subject (match-string 4 line))
               (author (match-string 5 line)))
          (forward-line 1)
          (let ((file-name (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
           (push (list commit file-name commit-number date-relative date-full subject author) lines))))
        (setq commit-number (1- commit-number))
        (forward-line 2))
       (nreverse lines))))
