One day I wanted to move a couple of files into the directory with the sources for this blog. It’s an often used directory, meaning fasd could help me with its path, but I used the wrong command, which resulted in this output and a bunch of missing files:
1234567891011
$ mv /Volumes/files/file{1,2} `fasd -d`
mv: rename 1 to /Users/user/Documents/var/1: No such file or directory
mv: rename 1.01117 to /Users/user/Documents/var/1.01117: No such file or directory
mv: rename 1.01117 to /Users/user/Documents/var/1.01117: No such file or directory
mv: rename /Volumes/disk/var/podcasts/backups/kazakh_v_kanade to /Users/user/Documents/var/kazakh_v_kanade: Permission denied
mv: rename 1.06288 to /Users/user/Documents/var/1.06288: No such file or directory
mv: rename 1.06288 to /Users/user/Documents/var/1.06288: No such file or directory
…
mv: rename 1.8225 to /Users/user/Documents/var/1.8225: No such file or directory
mv: rename 1.88823 to /Users/user/Documents/var/1.88823: No such file or directory
^C
This doesn’t look right at all. What was the output of that subcommand?
Oh my, that’s now what I expected; I thought it was going to present a picker. But…
The source files were gone in an unknown direction, and I noticed some odd behavior in CopyQ and Thunderbird.
(I should’ve read the output more thoroughly, then at least it would be quicker to find the new location of the files. But I also wouldn’t know what tmutil compare sucks; see the next section.)
TimeMachine
This was a seemingly simple task: figure out what changed in my filesystem since the last TimeMachine backup (which had been before these changes).
Oh look, man tmutil says there is this compare command to find the differences. Unfortunately I couldn’t get any meaningful information from it, i.e. for it to say that the directory ~/bin/ is in the latest backup, but no longer on disk. I tried a number of options, but not a single one of them worked as I expected:
“326.2G” removed?! This is a complete and utter nonsense! I have no idea what this output means.
DiffMerge
Well, to find missing files, I can compare the directories recursively. I started with DiffMerge, but it would probably take a while to find the differences since it also compared the file contents. So to the next option.
Comparing directories
In the end I went with the manual approach in the terminal, which means it’s very composable and customizable to whatever I need. And that is find . | sort — it can print the sorted paths to all the files in all subdirectories recursively. Basically I needed to compare the file list of /Volumes/disk/Backups.backupdb/mac/Latest/MacHD-Data/Users/user/ and $HOME/.
The files were 230–320 MiB, but vimdiff was fine comparing them. It showed me exactly what directories (and files inside) were missing. Easy!
After looking at the changes, I realized that about two dozens of directories were only moved into one ~/Documents/var/ (not removed), so at least I found the place.
I had to compare $HOME, /Applications and /usr/local to manually restore all those items to their places. It took some time, but I’m sure everything is correct now.
1234
$ mv bin ~
$ mv CopyQ.app /Applications
$ mv public ~/src/octopress/
# etc.
A number of discoveries
TM and symlinks
Apparently tmutil restore can’t restore symlinks (at least on OS X 10.15.7):
1234
$ tmutil restore -v /Volumes/disk/Backups.backupdb/mac/Latest/MacintoshHD-Data/Users/user/docs ~/
/Users/user/Documents: Source path is not inside a snapshot.
$ ll /Volumes/disk/Backups.backupdb/mac/Latest/MacintoshHD-Data/Users/user/docs
lrwxr-xr-x+ 1 u staff 21 Jan 12020 /Volumes/disk/Backups.backupdb/mac/Latest/MacintoshHD-Data/Users/user/docs -> /Users/user/Documents
Yes, I know that ~/docs is a symlink for ~/Documents and I want TM to restore the symlink itself, but it can’t?!
Auto-excluded directories
I didn’t know Xcode automatically excluded build directories from TM backups:
I mentioned in the beginning that CopyQ had troubles saving the clipboard history right after this wrong move, so I restarted it and it was fine. However only when I found the application here instead of /Applications/, I discovered that Alfred launched the program from this location and I hadn’t noticed that before (since Alfred’s purpose is launch programs fast).
fasd
Finally, what I wanted to do initially was this:
123
$ mv /Volumes/files/file{1,2}`fasd -d octo`# or with the default alias:$ mv /Volumes/files/file{1,2}`d octo`