Dotnet logo

.NET Tools

Essential productivity kit for .NET and game developers

How-To's

Local History in Rider: undo and redo on steroids

We’ve all been there. Investigating a bug, making some code changes, then finding that these changes don’t fix the bug. Rinse, repeat, and two hours later we realize that first attempt needed just a little tweak. How can we roll back to it if we did not commit it to Git or Mercurial? How can we roll back any change we made to the code base between source control commits? Undo only goes so far…

In JetBrains Rider, there’s a solution to that: Local History. It’s a real-time, local version control that keeps track of changes we make to our code base.

What is Local History?

When we’re “in the flow”, our project and source code constantly changes. We write, refactor and debug, and when we finish a task, code is committed to a version control system (VCS) like Git or Mercurial.

Unfortunately, commits to the VCS are just snapshots. If we’re lucky, changes in between commits are captured in the undo stack, but that disappears if we close the IDE and reopen it a later time. Undo also does not track external changes, made outside of the IDE. What’s even worse: don’t you hate it when you undo 20 times, then accidentally press the keyboard so you can’t redo anymore?

This is where Rider’s Local History comes in: it keeps track of source code changes and file changes in our project in between VCS commits. Whenever something changes (and is persisted to disk), local history tracks the change and allows us to roll back (or forward). Accidentally deleted a folder of files that weren’t yet committed? Want to get back that class or entire namespace you wrote on the train commute home from work, was dropped a few minutes ago and never committed to source control? Local History!

Local History is enabled by default and keeps track of all every save (or delete), whether explicit (Ctrl+S) or implicit (Rider auto-saves every few seconds). It tracks changes in a solution or project, folders within our solution, files, classes, … As long as the file is text-based, Local History has it covered.

Showing Local History

One place where we can view local history is under the VCS | Local History | Show History menu. It will bring up a diff viewer where we can see a list of changes made to the file we have open. On the left, we can see a description of the changes. On the right, a diff between the current and previous version is shown.

Local History viewer

Just like in a regular diff/merge view, we can restore lines and blocks of code, or roll back to a previous version of the file. Doing so will update the file that is open in the editor, or in the case of e.g. a solution folder, files can be restored.

It’s also possible to label a specific point in time, for example right before we start a massive refactoring effort. Labels can be added using the VCS | Local History | Put label menu, and are shown in the Local History change list as well. Note that labels are solution-wide and apply to all files and folders.

Label local history

What with external changes? Local History tracks those, too. For example, here I dropped the folder Consent outside Rider. Invoking Local History on the parent folder shows us that an external change was detected and we can revert from here if we want to.

External changes can be reverted using Rider

There are a couple of entry points to Local History:

  • The Local History context menu in the Solution Explorer or in the editor (tip: selecting code will show Local History for just the selection)
  • The VCS | Local History menu
  • The VCS operations popup (Ctrl+Alt+Q)

Another entry point is the View | Recent Changes popup (tip: map it to a keyboard shortcut). It shows us a list of recent changes in our solution and lets us quickly open up Local History to view more details.

View recent changes and jump to local history

Cleaning Local History

While having Local History is a real life saver sometimes, its internal database may grow over time. Local History is cleaned when installing a new version of Rider, or when invalidating caches using the File | Invalidate Caches menu.

Keep in mind that Local History really is local. The history is stored locally and not shared with other developers working on the same project. Make sure to keep using proper source control as well!

Download the latest Rider EAP build and experience local history in action! Your feedback is appreciated.

image description