Revise usage: a cookbook

Package-centric usage

For code that might be useful more than once, it's often a good idea to put it in a package. Revise cooperates with the package manager to enforce its distinction between "versioned" and "under development" packages; packages that you want to modify and have tracked by Revise should be deved rather than added.


You should never modify package files in your .julia/packages directory, because this breaks the "contract" that such package files correspond to registered versions of the code. In recent versions of Julia, the source files in .julia/packages are read-only, and you should leave them this way.

In keeping with this spirit, Revise is designed to avoid tracking changes in such files. The correct way to make and track modifications is to dev the package.

For creating packages, the author recommends PkgTemplates.jl. A fallback is to use "plain" Pkg commands. Both options are described below.



Because PkgTemplates integrates nicely with git, this approach might require you to do some configuration. (Once you get things set up, you shouldn't have to do this part ever again.) PkgTemplates needs you to configure your git user name and email. Some instructions on configuration are here and here. It's also helpful to sign up for a GitHub account and set git's github.user variable. The PkgTemplates documentation may also be useful.

If you struggle with this part, consider trying the "plain" Pkg variant below.


If the current directory in your Julia session is itself a package folder, PkgTemplates will use it as the parent environment (project) for your new package. To reduce confusion, before trying the commands below it may help to first ensure you're in a a "neutral" directory, for example by typing cd() at the Julia prompt.

Let's create a new package, MyPkg, to play with.

julia> using PkgTemplates

julia> t = Template()
  → User: timholy
  → Host:
  → License: MIT (Tim Holy <> 2019)
  → Package directory: ~/.julia/dev
  → Minimum Julia version: v1.0
  → SSH remote: No
  → Add packages to main environment: Yes
  → Commit Manifest.toml: No
  → Plugins: None

julia> t("MyPkg")
Generating project MyPkg:
[lots more output suppressed]

In the first few lines you can see the location of your new package, here the directory /home/tim/.julia/dev/MyPkg.

Before doing anything else, let's try it out:

julia> using Revise   # you must do this before loading any revisable packages

julia> using MyPkg
[ Info: Precompiling MyPkg [102b5b08-597c-4d40-b98a-e9249f4d01f4]

julia> MyPkg.greet()
Hello World!

(It's perfectly fine if you see a different string of digits and letters after the "Precompiling MyPkg" message.) You'll note that Julia found your package without you having to take any extra steps.

Without quitting this Julia session, open the MyPkg.jl file in an editor. You might be able to open it with

julia> edit(pathof(MyPkg))

although that might require configuring your EDITOR environment variable.

You should see something like this:

module MyPkg

greet() = print("Hello World!")

end # module

This is the basic package created by PkgTemplates. Let's modify greet to return a different message:

module MyPkg

greet() = print("Hello, revised World!")

end # module

Now go back to that same Julia session, and try calling greet again. After a pause (while Revise's internal code compiles), you should see

julia> MyPkg.greet()
Hello, revised World!

From this point forward, revisions should be fast. You can modify MyPkg.jl quite extensively without quitting the Julia session, although there are some Limitations.

Using Pkg

Pkg works similarly to PkgTemplates, but requires less configuration while also doing less on your behalf. Let's create a blank MyPkg using Pkg. (If you tried the PkgTemplates version above, you might first have to delete the package with Pkg.rm("MyPkg") following by a complete removal from your dev directory.)

julia> using Pkg

julia> cd(Pkg.devdir())   # take us to the standard "development directory"

(v1.2) pkg> generate MyPkg
Generating project MyPkg:

(v1.2) pkg> dev MyPkg
[ Info: resolving package identifier `MyPkg` as a directory at `~/.julia/dev/MyPkg`.

For the line starting (v1.2) pkg>, hit the ] key at the beginning of the line, then type generate MyPkg. The next line, dev MyPkg, is necessary to tell Pkg about the existence of this new package.

Now you can do the following:

julia> using MyPkg
[ Info: Precompiling MyPkg [efe7ebfe-4313-4388-9b6c-3590daf47143]

julia> edit(pathof(MyPkg))

and the rest should be similar to what's above under PkgTemplates. Note that with this approach, MyPkg has not been set up for version control.


If you add instead of dev the package, the package manager will make a copy of the MyPkg files in your .julia/packages directory. This will be the "official" version of the files, and Revise will not track changes.

includet usage

The alternative to creating packages is to manually load individual source files. This approach is intended for early stages of development; if you want to track multiple files and/or have some files include other files, you should consider switching to the package style above.

Open your editor and create a file like this:

mygreeting() = "Hello, world!"

Save it as mygreet.jl in some directory. Here we will assume it's being saved in /tmp/.

Now load the code with includet, which stands for "include and track":

julia> using Revise

julia> includet("/tmp/mygreet.jl")

julia> mygreeting()
"Hello, world!"

Now, in your editor modify mygreeting to do this:

mygreeting() = "Hello, revised world!"

and then try it in the same session:

julia> mygreeting()
"Hello, revised world!"

As described above, the first revision you make may be very slow, but later revisions should be fast.