Use Magit API to rebase to closest branch
My workflow in Git is,
- Create a new feature branch based on main branch
- Add some small commits into feature branch
- Rebase feature branch interactively
The final rebase step happens a lot.
So I could use Magit api magit-rebase-interactive
to speed up it.
The key is to analyze output of git log --decorate --oneline
to find the main branch commit.
Code,
(defun my-git-extract-based (target)
"Extract based version from TARGET."
(replace-regexp-in-string "^tag: +"
""
(car (nreverse (split-string target ", +")))))
(defun my-git-rebase-interactive (&optional user-select-branch)
"Rebase interactively on the closest branch or tag in git log output.
If USER-SELECT-BRANCH is not nil, rebase on the tag or branch selected by user."
(interactive "P")
(let* ((log-output (shell-command-to-string "git --no-pager log --decorate --oneline -n 1024"))
(lines (split-string log-output "\n"))
(targets (delq nil
(mapcar (lambda (e)
(when (and (string-match "^[a-z0-9]+ (\\([^()]+\\)) " e)
(not (string-match "^[a-z0-9]+ (HEAD " e)))
(match-string 1 e))) lines)))
based)
(cond
((or (not targets) (eq (length targets) 0))
(message "No tag or branch is found to base on."))
((or (not user-select-branch)) (eq (length targets) 1)
;; select the closest/only tag or branch
(setq based (my-git-extract-based (nth 0 targets))))
(t
;; select the one tag or branch
(setq based (my-git-extract-based (completing-read "Select based: " targets)))))
;; start git rebase
(when based
(magit-rebase-interactive based nil))))
Screencast: