Undo and redo¶
Did a papers add and are unhappy with the result?
puts the library back as it was before the command: the bibtex, and the
files that the command moved, renamed, copied or deleted. papers redo
does the command's changes again. Both take -n N to go several steps at
once.
$ papers add ~/Downloads/esd-4-11-2013.pdf --move
$ papers undo
undo: papers.bib restored to 4f1c9a2e papers add ~/Downloads/esd-4-11-2013.pdf --move (2026-10-22 14:03)
files/perrette_2013_a-scaling-approach.pdf --> moved back to ~/Downloads/esd-4-11-2013.pdf
There is nothing to set up: every command that changes a library records a step in its history.
The history¶
papers history lists the steps of the library, the latest first. >
marks where the library is now, and the steps that papers redo can bring
back are marked as undone:
$ papers history
b7e30d51 papers rm smith2020 --delete-files (2026-10-22 14:10) (undone: `papers redo`)
> 4f1c9a2e papers add ~/Downloads/esd-4-11-2013.pdf --move (2026-10-22 14:03)
92ad6c07 papers tag smith2020 --add climate (2026-10-21 09:12)
...
history: ~/.local/share/papers/history, 3.2 MB (up to 500 MB: the history-size setting; deleted files kept)
A step is named by its identifier, the first column: 8 characters of the sha256 of the step (of its bibtex, its other files, its parent and its time), which never changes. A command that takes a step accepts the start of it, 4 characters or more, as long as no other step starts the same way.
papers restore STEP brings the library to that step. Making a change after an
undo starts a new line of history; the undone steps are not lost, and
papers restore STEP still reaches them.
Taking back an older step¶
papers undo -n 3 goes back over the last three steps. To take back one
step alone and keep the steps made after it, give its identifier (or the
start of it, see The history):
The revert is a new step of the history (papers undo takes it back). For
each entry that the step changed, papers compares the entry before the step,
after it, and now:
- an entry that the step added is removed, unless it changed since (it is kept, and a line says so);
- an entry that the step removed comes back as it was, unless the library has an entry with its key now (or with its key among its former keys): that entry stays, and a line says so when it is not the removed one;
- a field that the step changed goes back to its value before the step,
unless it changed since: then it is a conflict, decided as for
papers pull, with--on-duplicate(keep: the value now,update: the value before the step; in a terminal, papers asks); - the tags and the file links are taken one by one: those that the step added are removed, those it removed come back, those added since stay;
- a key that the step changed (with
--keep-old-key, which keeps the former key inids) goes back to the former key.
The files go back as undo moves them, for the files of the step only: a file
that the step moved or renamed is moved back, a file it deleted comes back
from the history. The pairs that the step recorded in .papers/distinct.json
(entries that are not the same paper) are removed. The origin copies
(.papers/origin/) are not changed: the next pull or push compares
with them, and with auto-push the revert is pushed like any command.
A step that also changed the pool is reverted in the library only; a line
gives the command that reverts the pool's step:
papers -C ../pool history --revert 3c5e0b7a.
Deleted files¶
A file that a command deletes (papers rm --delete-files, papers file
rm, papers file clean...) is kept by the history, and papers undo puts
it back, also when no entry linked to it, or when the command was stopped
(an error, Ctrl-C) after deleting it:
undo: papers.bib restored to 4f1c9a2e papers add paper.pdf (2026-10-22 14:03)
files/perrette_2013_a-scaling-approach.pdf: restored from the history
The history keeps up to 500 MB (the history-size setting). Beyond that,
the oldest steps are dropped first, and the deleted files that only they
needed go to the trash of the system (a step that brought a file back from
the history, papers file fix or papers history --revert, needs it too). Before a command that deletes more
than the history keeps, or so much that recent steps would be dropped,
papers asks first (-y answers yes; without a terminal, the files are
kept):
3 files to delete, 812 MB: more than the history keeps (history-size: 500 MB).
- This command cannot be undone: the files go to the trash of the system, not to the history (the history keeps its steps).
Proceed? [y/N]
papers history shows the size of the files each step keeps
([3.2 MB of deleted files]). papers history --drop-files STEP removes from
the history the files that the step deleted, and --drop-files PATH the file
deleted from PATH (by any step): they go to the trash of the system, the
steps stay, and undo says the files are no longer in the history. papers
history --remove removes the whole history of the library. Both ask
first (-y does not); with --dry-run they only say what they would remove.
If you would rather not keep deleted files at all (you have your own
backups, or no space to spare): papers config --global keep-deleted-files
false. Deleted files then go straight to the trash of the system, and undo
says it cannot bring them back.
Changes made outside papers¶
When you edit the bibtex yourself (in an editor, JabRef, another program,
or on another computer that syncs the library), papers notices it at its
next command and records your change as a step of its own, "changed outside
papers". papers undo never drops it silently: undoing a papers command
goes back to what was on disk just before it, your change included.
The step of your change also has the files of .papers/ (the origin
records of a library with a pool, distinct.json, files.json) as they
were on disk, so a synced folder that brought a new bibtex and new origin
records together gives one consistent step. papers notices a change by the
bibtex only: a change made outside papers to the files of .papers/ alone
is not a step of its own, it becomes part of the next command's step (and
undoing that command takes it back too).
Running papers undo right after your own edit undoes that edit (papers
redo brings it back). papers restore without a step number does the
same: it puts the library back to its last step, as papers left it.
Where the history is¶
The history is kept on your computer, not in the library:
~/.local/share/papers/history on Linux (the history-dir setting). It is
not synced or shared with the library: a library you copy to another
computer, or receive from someone, starts with an empty history there.
The history follows the library: moving or renaming the library folder
keeps it (each library has an identifier, id in .papers/config.json).
A copy of a library shares the history up to the copy, then each folder
has its own steps. papers export makes a new library, with a history of
its own.
papers history --all lists the histories on the computer, with the space
each one uses; papers history --remove removes that of the library
(--remove ID: another one, e.g. of a library you deleted).
All libraries share one store, so that a file kept by several of them is
stored once. papers config history-separate true gives a library a store
of its own, with its own history-size.
Undo in a library that has a pool¶
A pool is a library with its own history. A command that exchanges entries
with the pool (add in a shallow library, a command that changes entries
with auto-push; push, pull, sync) writes both, and each records a
step in its own history. When the command wrote the pool, the step of the
library also records the step of the pool.
papers undoandpapers redoin the library undo and redo the pool's step too, as long as the pool is still where the command left it (for redo: where the undo left it). The files that the command moved to the files directory of the pool are moved back.- If the pool changed since (another command in the pool or in another
library that shares it), papers reverts the pool's step there instead (a
new step of the pool, see Taking back an older step).
An entry that changed in the pool since stays; in a terminal, papers asks
about a field changed on both sides.
papers redothen reverts that revert. If the undo took the pool's step back and the pool changed after it,papers redodoes the step again there (a new step of the pool, with the same rules). - If the pool changed outside papers since its last step, the library only is undone, and a line says so.
- With auto-push, the shared entries that differ from their origin copy are
pushed after the undo or redo, as after any command. In general there is
nothing to push: the undo restores the origin copies with the bibtex.
There is something when a step was made with auto-push off; that push is
then a new step, after which there is nothing to redo, as after any
command (
papers restore STEPstill goes to the steps undone). papers undo --library-only(andredo --library-only) leave the pool as it is: the files that the command moved to the pool are copied back.- The pool does not know which libraries use its entries. If another
library pulled an entry since the
addthat undo takes back, that library's link to the PDF breaks: the PDF goes back where it came from, andpapers file fix --search FOLDERthere finds it. papers -C POOL undoandpapers -C POOL redochange the pool only: they undo the last change of the pool, whichever library made it. In the history of the pool, a step made from a library names it:31 papers add ../new.bib (2026-10-28 10:09, from ~/papers/paper2).- The library and the pool are locked during the undo (see Two commands at the same time): no other command changes the pool between the moment undo looks where the pool is and the moment it writes it.
$ papers add ~/Downloads/esd-4-11-2013.pdf --move
$ papers undo
undo: papers.bib restored to 0e8d41f3 papers pull (2026-10-28 10:12)
~/sealevel/files/perrette_2013_a-scaling-approach.pdf --> moved back to ~/Downloads/esd-4-11-2013.pdf
pool ../sealevel: also undone, restored to 3c5e0b7a papers push (2026-10-28 10:09)
The library also restores its origin copies (.papers/origin/, see
Pools) and .papers/distinct.json to the step it
goes back to, and removes those that did not exist at that step. The next
exchange then compares the library and the pool to the origin copies of
that step:
- After undoing a
pull, or apushwhose step the pool did not undo or revert (--library-only, a conflict in the pool), the pool shows as changed inpapers status: what the pool has beyond the restored state comes again with the nextpull, and the nextpushdoes not send the undone state back to the pool. - After an undo in the pool, the origin copies of the library still have the
newer version, so the pool shows as changed, and a
pulltakes the pool's older values for the fields the library did not change since. A field that the pool undo removes is a removal in the pool: thepullremoves it from the library too, unless the library changed it since (a conflict, seepapers pull).
papers restore STEP restores the library only.
Details¶
How undo finds the files¶
Each step records the files its command moved, renamed, copied or deleted, with their checksum. Undo compares the files that the entries link to now with those of the step it goes back to, and finds each missing file:
- where the commands in between moved or copied it;
- by its checksum (
.papers/files.json, see Checksums): a file that no entry links to any more is moved, a file that an entry links to, or a file of the pool, is copied; - among the deleted files kept by the history.
The rules:
- A file is never overwritten: if its former place is taken, papers says so and leaves it where it is.
- A file whose content changed since the command (e.g. a PDF annotated since) is left as it is, with a message.
- A file outside the library that a command only unlinked (e.g.
papers file detach) is never deleted by undo or redo, and the files that no command touched are left alone. - In a shallow library, a file that
addmoved into the files directory of the pool is copied back: the pool entry keeps it.
A file outside the library (~/Downloads, a folder of the project) is
recorded with its full path; a file inside it, relative to the library
(with the paths absolute setting, with its full path), so that undo in a
copy of the library acts on the copy's files.
When another program writes the bibtex while a papers command runs, papers does not overwrite it, and puts back the files that the command had already moved, copied or deleted.
Checksums¶
.papers/files.json holds the checksum (sha256) of the files that the
entries link to. With the checksums setting (true by default), a command
writes the checksum of the files it moves, copies, adds or links.
papers file checksum writes the checksums of all the files (or of the
entries given), --check reports the files whose content changed since
their checksum (e.g. annotated PDFs) and writes nothing. With papers
config checksums false, the commands write no checksum, and undo finds
the files through the steps of the commands only.
What a step holds¶
The bibtex, byte for byte (stored in pieces of about 32 entries: a step that
changes one entry adds one piece, a few KB), the files of .papers/ that belong to the library
(origin copies, distinct.json, files.json; not config.json), the
command and its time, and the files it moved, copied or deleted. The
history keeps older contents of the bibtex, but not of the PDFs: an
annotated PDF replaces the previous one.