What's New
This release lets you scan several directories in one run, adds a treemap view
and item actions to the web UI, teaches gdu to read .gitignore files, and lets
you plug in your own trash command. Below is a walkthrough of each new feature.
Scan multiple directories at once
More than one directory can now be given on the command line, which is useful
when only a subset of a large tree is of interest:
gdu ~/projects/alpha ~/projects/beta ~/projects/gamma
The directories are scanned one after another and presented together under a
virtual top level directory named (multiple), so they can be compared and
sorted like ordinary siblings. They are listed by their absolute path, so
directories that share a base name stay distinguishable, and each one keeps its
real path, so rescanning, deletion and opening a shell work as usual once you
navigate into one of them.
Directories nested in one another are rejected, since scanning both would count
the nested part twice. Exporting (-o) and database storage (--db) accept a
single directory only. The virtual top level directory has no counterpart on
disk, so --change-cwd, spawning a shell, --browse-parent-dirs and exporting
are unavailable while it is shown; rescanning it rescans every directory below
it.
Treemap view in the web UI
The web UI gained a full-window treemap next to the existing donut chart. Toggle
between the two from the header button. The treemap shows the complete nested
subtree of the current directory rather than just its direct children, so a
single screen is enough to find what is taking up the space. Details too small
to display are folded into their nearest visible parent directory.
Click a tile to select it, double-click a directory to open it, and press ?
for the keyboard shortcuts.
by @mikhail-angelov in #651
Reveal and delete items from the web UI
The web UI is no longer read-only. In the treemap, press O to reveal the
selected item in the system file manager and D (or Delete) to delete it
after confirmation. In the donut view, each row of the table has its own reveal
and delete buttons that act on that item.
The confirmation dialog offers both "Move to Trash" and "Delete Permanently",
and can suppress further confirmations for the current browser session - the
choice is shared between the treemap and the table, so with "permanent" chosen a
single click on a row's delete button deletes immediately.
--no-delete applies to the web UI as well: the delete action is hidden and the
server rejects delete requests. Reveal remains available because it does not
modify scanned data. Deletion while a filter is active is disabled by default,
since the displayed tree may omit files that are still present on disk; set
GDU_ALLOW_DELETE_WITH_FILTER=1 to override the check.
Security: browsing stays unauthenticated, but reveal and delete need more: a
request that both originates from a loopback address and carries a random token,
generated fresh for each server run and never served over the API. The token
travels only in the URL gdu prints and opens. On a multi-user machine, use
--web-open=false and open the printed URL from an already-running browser, as
a cold-started browser may retain that URL in its command line.
by @mikhail-angelov in #659 and @dundee in #683
Ignore directories from a .gitignore file
Directories can now be ignored using .gitignore-style patterns read from a
file:
gdu -G .gitignore /some/dir
A name without / matches at any depth, a trailing / marks a directory, and a
leading / anchors the pattern to the directory being scanned. Blank lines and
comments are skipped.
Negated patterns (starting with !) and patterns matching every directory (such
as * or **) are rejected with an error rather than skipped silently, as both
would make gdu report less than is really on disk. Since gdu prunes whole
directories, file patterns such as *.class are accepted but have no effect.
-I, -X and -G now combine: a directory is ignored if it matches any of
them, instead of the last option winning and silently dropping the others.
Paths from -i apply in addition.
by @TigerZCoder in #673
Use your own trash command
The D key and the web UI's "Move to Trash" action can now be routed through a
command of your choice instead of the built-in XDG trash:
gdu --trash-command 'trash-put --trash-dir ~/mytrash'
gdu --trash-command 'mv -f "$1" ~/mytrash/'
The command is evaluated by /bin/sh with the absolute path of the item
appended as an argument, which is also exported as GDU_TRASH_PATH. Commands
that take their destination last can refer to the path as "$1" instead, in
which case it is not appended. The command must not be interactive. Not
supported on Windows.
Copy the path of the selected item
Press y to copy the full path of the file or directory under the cursor to the
system clipboard. Gdu shells out to the usual clipboard tools - pbcopy on
macOS, clip on Windows, and wl-copy, xclip or xsel elsewhere - so no new
dependency is pulled in, but one of them has to be installed.
by @addielaruee in #645
Bars for the item count column
The item count column can now be drawn with a bar next to the number, the same
way sizes are, making it easy to spot the directories holding the most files.
Enable it in the configuration file:
style:
show-item-count-bar: true
The bar is only drawn while the item count column itself is visible, so combine
it with -C or toggle the column with the c key.
Finer control over Ctrl+C during a scan
Stopping a scan and keeping partial results, introduced in v5.37.0, got a second
step: pressing Ctrl+C again while the scan is still stopping quits gdu
immediately, so a scan that is slow to wind down no longer traps you.
If you would rather have the first Ctrl+C quit gdu outright, use the new
--ctrl-c-quits flag. Esc always stops the scan and keeps the results found
so far, regardless of the flag.
Hardlinks preserved in trimmed JSON exports
Exports that selected attributes explicitly with --output-attrs dropped the
inode information for hardlinked files, so re-importing them counted the same
file several times and inflated the totals. ino is now a selectable attribute
and is honored by both the in-memory and SQLite exporters:
gdu --output-attrs=asize,dsize,ino -o out.json /some/dir
Available attributes are asize, dsize, items, mtime, notreg and ino;
name is always included.
by @AdamMagued in #686
Windows ARM64 binaries
Releases now include a native Windows ARM64 build, gdu_windows_arm64.exe.zip,
alongside the existing amd64 one.
Summary of all changes
- feat: allow scanning multiple directories by @dundee in #653
- feat: add Treemap feature for web UI by @mikhail-angelov in #651
- feat: add user actions: delete, reveal file ( to webui treemap) by @mikhail-angelov in #659
- feat(webui): add reveal and delete actions to the file table by @dundee in #683
- feat(ignore): add -G/--ignore-from-gitignore for .gitignore-style patterns by @TigerZCoder in #673
- feat: add --trash-command option by @dundee in #652
- feat: copy path of selected item to clipboard by @addielaruee in #645
- feat: show bar for item count by @dundee in #649
- feat: allow ctrl+c to quit instead of stopping the scan by @dundee in #664
- feat: quit on second ctrl+c during a scan by @dundee in #665
- fix: support ino in --output-attrs to preserve hardlinks by @AdamMagued in #686
- fix: StoreDir fixes by @dundee in #644
- fix(report): prevent export progress from wrapping by @sjh9714 in #646
- fix: panic exporting top files from archives or a persistent DB by @VXNCXNX in #631
- fix(device): include same-filesystem bind mounts with --no-cross by @fzlzjerry in #662
- fix(stdout): --depth ignores --show-apparent-size when sorting by @VXNCXNX in #630
- fix(report): honor --summarize and --depth for stored and archived items by @VXNCXNX in #660
- fix(device): skip macOS mounts reached through the Data volume with --no-cross by @anandghegde in #670
- fix(stdout): honor --top and --depth when reading an input file by @VXNCXNX in #668
- fix(stdout): honor apparent-size flag in --top ranking by @VXNCXNX in #669
- fix(ignore): escape path separators in generated absolute path alternatives by @TigerZCoder in #672
- test: take expected disk usage from stat instead of assuming 4 KiB blocks by @Juice-de-Orange in #682
- ci: build Windows ARM64 release binary by @meop in #647
- ci: bump version of golang by @dundee in #650
- chore(deps): bump github/codeql-action from 4.37.4 to 4.37.8 by @dependabot[bot] in #642
- chore(deps): bump github.com/dgraph-io/badger/v4 from 4.9.2 to 4.9.6 by @dependabot[bot] in #635
- chore(deps): bump github/codeql-action from 4.37.8 to 4.37.9 by @dependabot[bot] in #648
- chore(deps): bump github/codeql-action from 4.37.9 to 4.38.1 by @dependabot[bot] in #675
- chore(deps): bump docker/login-action from 4.5.2 to 4.6.0 by @dependabot[bot] in #632
- chore(deps): bump golang.org/x/sys from 0.46.0 to 0.47.0 by @dependabot[bot] in #636
- chore(deps): bump github.com/mattn/go-isatty from 0.0.22 to 0.0.24 by @dependabot[bot] in #655
- chore(deps): bump github.com/stretchr/testify from 1.11.1 to 1.12.1 by @dependabot[bot] in #656
- chore(deps): bump modernc.org/sqlite from 1.52.0 to 1.59.0 by @dependabot[bot] in #657
- chore(deps): bump github.com/sirupsen/logrus from 1.9.4 to 1.10.2 by @dependabot[bot] in #658
- chore(deps): bump @vitest/mocker and vitest in /webui/frontend by @dependabot[bot] in #663
New Contributors
- @addielaruee made their first contribution in #645
- @mikhail-angelov made their first contribution in #651
- @fzlzjerry made their first contribution in #662
- @anandghegde made their first contribution in #670
- @TigerZCoder made their first contribution in #672
- @Juice-de-Orange made their first contribution in #682
- @meop made their first contribution in #647
- @AdamMagued made their first contribution in #686
Full Changelog: v5.37.0...v5.38.0