Commit 7fbff430 authored by Jonas Bernoulli's avatar Jonas Bernoulli

magit-commit-reshelve, magit-reshelve-since: New commands

parent 0f94dcf3
......@@ -317,6 +317,8 @@ Changes since v2.11.0
space and two new options `magit-refs-primary-column-width' and
`magit-refs-focus-column-width' were added. #3378
* Added commands `magit-commit-reshelve' and `magit-reshelve-since'.
Fixes since v2.11.0
......@@ -330,6 +330,33 @@ depending on the value of option `magit-commit-squash-confirm'."
(user-error "Nothing staged"))))
(defvar magit--reselve-history nil)
(defun magit-commit-reshelve (date)
"Change the committer date and possibly the author date of `HEAD'.
If you are the author of `HEAD', then both dates are changed,
otherwise only the committer date. The current time is used
as the initial minibuffer input and the original author (if
that is you) or committer date is available as the previous
history element."
(let ((author-p (magit-rev-author-p "HEAD")))
(push (magit-rev-format (if author-p "%ad" "%cd") "HEAD"
(concat "--date=format:%F %T %z"))
(list (read-string (if author-p
"Change author and committer dates to: "
"Change committer date to: ")
(cons (format-time-string "%F %T %z") 17)
(let ((process-environment process-environment))
(push (concat "GIT_COMMITTER_DATE=" date) process-environment)
(magit-run-git "commit" "--amend" "--no-edit"
(and (magit-rev-author-p "HEAD")
(concat "--date=" date)))))
;;; Pending Diff
(defun magit-commit-diff ()
......@@ -321,6 +321,78 @@ on a position in a file-visiting buffer."
(magit-add-change-log-entry whoami file-name t))
;;; Reshelve
(defun magit-reshelve-since (rev)
"Change the author and committer dates of the commits since REV.
Ask the user for the first reachable commit whose dates should
be changed. The read the new date for that commit. The initial
minibuffer input and the previous history element offer good
values. The next commit will be created one minute later and so
This command is only intended for interactive use and should only
be used on highly rearranged and unpublished history."
(interactive (list nil))
((not rev)
(let ((backup (concat "refs/original/refs/heads/"
(when (and (magit-ref-p backup)
(not (magit-y-or-n-p
"Backup ref %s already exists. Override? " backup)))
(user-error "Abort")))
(magit-log-select 'magit-reshelve-since
"Type %p on a commit to reshelve it and the commits above it,"))
(cl-flet ((adjust (time offset)
"%F %T %z"
(+ (floor time)
(* offset 60)
(- (car (decode-time time)))))))
(let* ((start (concat rev "^"))
(range (concat start ".." (magit-get-current-branch)))
(time-rev (adjust (float-time (string-to-number
(magit-rev-format "%at" start)))
(time-now (adjust (float-time)
(- (string-to-number
(magit-git-string "rev-list" "--count"
(push time-rev magit--reselve-history)
(let ((date (floor
(read-string "Date for first commit: "
time-now 'magit--reselve-history))))))
(magit-run-git "filter-branch" "--force" "--env-filter"
(format "case $GIT_COMMIT in %s\nesac"
(lambda (rev)
(prog1 (format "%s) \
export GIT_AUTHOR_DATE=\"%s\"; \
export GIT_COMMITTER_DATE=\"%s\";;" rev date date)
(cl-incf date 60)))
(magit-git-lines "rev-list" "--reverse"
" "))
range "--")
(lambda (process event)
(when (memq (process-status process) '(exit signal))
(if (> (process-exit-status process) 0)
(magit-process-sentinel process event)
(process-put process 'inhibit-refresh t)
(magit-process-sentinel process event)
(magit-run-git "update-ref" "-d"
(concat "refs/original/refs/heads/"
;;; Revision Stack
(defvar magit-revision-stack nil)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment