Semantics for one step undo/redo
- From
Jon Seymour <jon.seymour@gmail.com>
- Date
- Jun 14, 2005, 13:50 UTC
- Message-ID
- <2cfc403205061406507af5a66@mail.gmail.com>
Hi.
I've implemented some undo/redo scripts which I am testing in my own workspace before I unleash them on an wider audience. However, I thought it would be useful to discuss the semantics of my approach on the list.
The approach focuses on one-step undo, redo. What I mean by this is that a given undo or redo operation can undo or redo exactly one commit. Of course, it is possible to compose arbitrary sequences of undo and redos with the expected results. I regard multi-commit undos/redos to be a special case of the one-step undo/redo and so can be neglected for the purposes of discussion.
UNDO Semantics:
When the working tree and cache are synced with a commit, C, then
undo has the effect of returning the workspace to the state
immediately prior to the commit C.UNDO Pre-conditions:
- the working tree matches the cache (git-update-cache --refresh
exits with zero)
- the cache matches the tree specified by HEAD or UNDONE_HEADUNDO Post-conditions
- UNDONE_HEAD is set to the value of HEAD
- HEAD is replaced by its left-most parent
- HEAD's commit message is written to .nextmsg
- the workspace tree and cache is unchanged
- an entry containing the UNDONE_HEAD head and its parents are
written to the end git/redo-logA tweak to the undo implementation would be to allow the user to specify which merge branch to undo down.
REDO Semantics
- redo will replay a previous commit but any or all of the tree,
the parents, the message may be replaced by edited values.REDO Pre-conditions:
- at least one entry exists in the .git/redo-log
- the cache matches the working tree
- .nextmsg contains the commit message
- HEAD contains the commit id of the current predecessor (which
may differ from the logged value)REDO Post-conditions:
- the working tree is committed with .nextmsg as its message, the
first parent replaced by HEAD and the remaining parents read from .the
tail of .git/redo-log
- .nextmsg is cleared
- the last line of .git/redo-log is removedWith the scripts I have written, I can fix a commit message, 4 messages old with:
undo
undo
undo
undo
vi .nextmsg
while redo
do
echo done
doneI think my approach differs a little from Junio's (but I haven't analysed his deeply) in that the redolog is actually just the slightly edited output of git-rev-list --merge-order --parents head base [ the edits removes from the list the parallel branches that aren't actually involved in the undo ]
Comments?
jon.
-- homepage: http://www.zeta.org.au/~jon/ blog: http://orwelliantremors.blogspot.com/