Lesson 30 · Recovery
GitTree Undo, Redo and recovery snapshots
Undo a commit from GitTree's toolbar, redo it, and learn what the app can and cannot take back, when it refuses, and why it keeps recovery snapshots.
- Level: Intermediate
- 9 min read
- 6 min video
- Updated
- Before this lesson: Reset: soft, mixed and hard, Find a lost commit with reflog
Progress saved in this browser.
Playing loads the video from YouTube (privacy-enhanced mode).
What you will learn
- Read what the next Undo or Redo would do before you press it.
- Predict that undoing a commit keeps its changes staged, and that Redo can bring the commit back.
- Recognise why the app refuses an Undo or Redo: the branch moved, files changed, a remote was changed.
- Know what recovery snapshots are and how to delete old ones deliberately.
Before you start
You are on private/undo-demo, a branch from lesson 18's result M with a clean work tree. You will create one small note, docs/signup-recovery.md, and commit it through GitTree, because GitTree's Undo works from the steps it records itself. A commit made in a terminal is a different thing and does not go into that record.
Everything is local and on the Free plan (GitTree asks you to sign in): no hosting account, no provider, no internet. Every identity is fictional (example.com). Never run this lesson in a real project.
Make the changes in GitTree or with the native Git commands, not both in the same copy. Reading the result is always safe. The menu labels, tooltips and notices come from GitTree 2.0's own strings and source. The native commands were run with Git 2.43 in disposable copies and show only the Git model, not the app's record. The GitTree steps were not run on macOS, Windows or Linux.
Concept and state effects
GitTree keeps a journal of the steps it performs. Undo reverses the newest step and Redo repeats the step undone last. The toolbar tooltip names the step, for example "Undo: commit …". Read it first: if it names something other than what you expect, stop.
Before a destructive step, GitTree saves a recovery snapshot under refs/ogt/trash/* and writes the journal entry. Undo restores from that record, and only while nothing has changed since: a branch is moved back only if it still points where the step left it, and files are restored only if nobody edited them after. Otherwise Undo is refused with a reason, and the snapshot is kept.
Undoing a commit moves the branch back and keeps the committed changes staged, so nothing is lost. Redo of that commit moves the branch forward again to the same commit. Not every step can be redone, and some cannot be undone: a force push changed a remote ("push again to change it back"); a deleted stash is kept as a snapshot but not undone yet; the very first commit has no earlier state. A step that stopped partway has no complete result to undo.
Snapshots are not deleted on a schedule. The command Delete Old Recovery Snapshots… lets you choose an age, shows exactly which snapshots are older, and deletes only those after you confirm. Deleting a snapshot removes the way back for that step.
Undo and Redo change only the local repository. Nothing is published.
Prepare the exact project state
Start from a separate ordinary copy of lesson 18's result M that you trust and leave your original untouched. Create the branch and make the note. DOC_LOST is the note's content.
Complete file inputs
Save only at the phase named below. These are full UTF-8/LF bodies with a final newline; never paste Markdown fences. Unchanged runnable files inherit the named input. Versions in separate variants must not overwrite the original.
docs/signup-recovery.md — DOC_LOST
# Recovered signup work
Keep a branch name before leaving useful experimental work.In GitTree
Open the palette with Command+Shift+P (Ctrl+Shift+P on Ubuntu). Undo and Redo are in the toolbar and in the palette; the shortcuts are Command+Z for Undo and Command+Shift+Z or Command+Y for Redo (Ctrl on Windows and Linux).
- In a separate copy, create the branch
private/undo-demoand save DOC_LOST asdocs/signup-recovery.md. Open the changes list: the file is new. - Stage only that file and commit it with the Summary
docs: demonstrate a reversible local commit. Wait for the real result. - Hover Undo in the toolbar. The tooltip reads "Undo: commit …". If it names another step, stop: do not undo something you did not mean to.
- Choose Undo once. The notice says "Undid: commit." The branch is back on M and the note is staged, not deleted.
- Hover Redo. The tooltip reads "Redo: commit …". Choose Redo once. The notice says "Redid: commit." The commit is back and the work tree is clean.
- Separate stale-state copy. In a second copy, repeat steps 1 to 4, then, outside GitTree, commit the staged note with
git commit -m "docs: external move after app undo". Look at Redo: it is disabled, and its reason is "The branch moved since; undoing would overwrite that change." Do not force it. - Open the palette and run Delete Old Recovery Snapshots…. Leave Older than (days) at 30 and choose Find. Read what the list says: either "No snapshots are that old." or a list of the old ones. Close the dialog; do not delete anything to finish the lesson.
For every ordinary commit in the course: Summary is the stated subject, Description is empty and the options Amend Previous Commit, Skip Hooks, Add Signed-off-by, Different Author, Push After Commit and Allow Empty Commit stay off.
In the terminal
The terminal does not use the app's journal. This is the plain Git model of what the commit undo does, in a different clean copy of lesson 18's result:
git switch --create private/undo-demo
BEFORE_SHA="$(git rev-parse HEAD)"Save DOC_LOST as docs/signup-recovery.md, then:
git add -- docs/signup-recovery.md
git commit --quiet -m "docs: demonstrate a reversible local commit"
AFTER_SHA="$(git rev-parse HEAD)"
git reset --soft "$BEFORE_SHA"
git status --shortA docs/signup-recovery.mdThe branch is back and the file is staged. Moving forward again:
git reset --soft "$AFTER_SHA"
git status --shortThe status is empty. These commands do not call the app's Undo or Redo, record a GitTree journal entry or create a snapshot; git for-each-ref refs/ogt/trash prints nothing in this copy. In an app-made take it lists the real snapshot names, which you read without changing them.
The guard against a stale step is a compare-and-swap. Git has the same idea in update-ref, which moves a ref only if it still holds the value you expect. After an external commit:
git update-ref refs/heads/private/undo-demo "$AFTER_SHA" "$BEFORE_SHA"Git refuses with "cannot lock ref … is at … but expected …". GitTree's own refusal is the one in the tooltip: "The branch moved since; undoing would overwrite that change."
Result
Where you end: in the first copy the note was committed, undone (staged, branch on M) and redone (branch on the commit, tree clean). In the stale copy Redo was refused because the branch moved, and the external commit was left intact. You opened the snapshot dialog and closed it without deleting anything.
Common mistakes
- Pressing Undo without reading the tooltip, and undoing a step you did not mean.
- Assuming every action can be undone or redone: a force push and a deleted stash are not, and most steps have no Redo.
- Expecting Undo to cover edits you made in an editor outside GitTree.
- Deleting old snapshots to tidy up, which removes the way back.
If something goes wrong
If Undo is disabled, read the reason in the tooltip: the branch moved, files were edited since, a remote was changed, or there is nothing to undo. If a step is refused, its recovery snapshot is kept under refs/ogt/trash/*; do not delete it while you are unsure. For commits made outside GitTree, use the reflog from lesson 29.
Check your understanding
Answer each question, then read why. Questions marked “Required” count toward completing the lesson.
0 of 6 correct
Answer the required questions correctly to complete the lesson.
Checked in this browser.
Practice
Write down what the Undo tooltip said, what the branch and the staged list looked like after Undo, and what Redo did. In the stale copy, write the reason Redo gave. Then name one step the app cannot undo and say why.
Your own confirmation: the site cannot see your computer.
To complete the lesson, answer the required questions correctly and confirm the practical exercise.
Recap
- Read the tooltip before you press.
- Undoing a commit keeps its changes staged.
- A moved branch or edited files make Undo refuse; snapshots are kept.
Related
Glossary terms introduced
Undo — تراجع; Redo — إعادة; journal — سجل العمليات; recovery snapshot — لقطة استعادة.
Video transcript
The narration of the video, cue by cue.
Show the transcript
- GitTree can take some steps back. Here is how, and where it stops.
- GitTree keeps a journal of its own steps. Undo reverses the newest one.
- Before a risky step, it saves a recovery snapshot first.
- We have a branch, and a new note.
- Stage only that file.
- Write the summary. All the options stay off.
- Commit once, in GitTree itself.
- A commit made in a terminal is not in this record.
- Hover Undo. The tooltip names the step: commit.
- If it names something else, stop.
- Choose Undo once. The notice says undid commit.
- The branch is back on M.
- And the note is staged, not deleted. Nothing is lost.
- Now Redo names the same commit.
- Choose Redo once. The commit is back.
- The work tree is clean again.
- In a second copy, we commit and undo the same way.
- Now commit the staged note outside GitTree.
- Redo is disabled. The branch moved since.
- It leaves your commit alone. Never force it.
- Other reasons: files edited, a remote changed, the first commit.
- Now the snapshots. Run Delete Old Recovery Snapshots.
- It says that only the listed snapshots are deleted.
- Leave thirty days, and choose Find.
- Close it. Nothing expires on its own.
- In a plain Git copy, a soft reset gives the same shape.
- Forward again, the tree is clean, and there is no app snapshot.
- Git guards a ref the same way: move it only if it holds what you expect.
- Undo is not a global rewind. It reverses steps the app recorded.
- Practice: write the tooltip, the result of Undo, Redo, and the stale reason.
- Next, what a detached HEAD means.