Repository navigation
GitBolt 0.9.8
Pre-release
Pre-release
Mostly a security release: a repository you clone or open, or a server
you fetch from, could turn several of GitBolt's features against you
(see Security below). Also: submodules and worktrees open in GitBolt,
the Console works in bare repositories where git's
safe.bareRepository is explicit, a commit whose files can't be read
says why instead of looking unchanged, and usage statistics have a
Settings page of their own.
Fixed
- Opening a submodule or a worktree: Repository › Manage
submodules' "Open in New Window" did nothing, and Manage worktrees'
showed the worktree in your file manager. Both menus now have Open
in GitBolt, which opens the submodule or worktree in the window (a
submodule that isn't checked out says so), and Open in File
Explorer, which shows its folder. - The Console tab in a bare repository now sets GIT_DIR, as Git
bash has since 0.9.7, so git typed there works where git's
safe.bareRepositorysetting isexplicit. Opening a bare
repository, or leaving one, sets or unsets GIT_DIR in the Console's
shell at its prompt (sh, bash, zsh, ksh, csh, tcsh or fish), so the
shell keeps its jobs and history; a command still running in it is
left to finish first, and the line at the prompt is cleared with a
Ctrl+C first. On Windows, and with a shell of another kind, the
shell is started again once no command runs in it. - Recent repositories listed a repository twice when it was opened
by two spellings of its path: on macOS,/tmp/…from Finder and
/private/tmp/…from Terminal, a path through a symlinked folder,
and on Windows a short (8.3) name, asubstor mapped drive, or a
junction. It is now listed once, under the spelling it was last
opened by; one already listed twice becomes one entry once it has
been opened by each spelling again. - More crashes on config lines with no value (a name and no
= value; see 0.9.7). A line with none in a branch's section of
.git/config(rebase, say, which git reads astrue) crashed
Delete Branch. One in a remote's section (prune,mirror) crashed
removing the remote, and afetchwith none crashed adding one.
Each also left.git/config.lockbehind, which then stopped every
change to the config, git's own included; these now just work. A
merge.conflictstylewith no value, in any git config, crashed
switching branches, discarding changes, stashing and cherry-picking,
and amerge.defaultwith none crashed cherry-picks; they now stop
with git's own message ("missing value for …"). As in 0.9.7, the
fixes are in the libgit2 built into every GitBolt download. - Selecting a commit no longer waits for its diff. The Stats row,
the Diff tab and the File Tree now fill in from a background thread,
so a large commit no longer freezes the window; when that takes more
than a moment, the Stats row says "(counting…)" meanwhile. Selecting
another commit, switching repositories or quitting stops a read
still going for the commit before, where they used to wait for it. - A commit or a working tree that couldn't be read looked
unchanged. When git can't read a commit's files (a tree nested
past the 2,048-level limit, say), the Stats row and the Diff tab now
say why, where the commit looked as if it changed nothing, and the
File Tree's "Failed to load tree" says why too. When the working tree's status can't be read, the toolbar
shows "Commit (?)" with the reason in its tooltip, the Commit dialog
says why, and Recent repositories shows "—" instead of what read as
a clean status; a submodule list that can't be read says so too. - Discard and Unstage of a file whose name looks like a pattern
(*,[ab]) acted on every file the pattern matched: discarding a
file named*threw away the changes to all of them. One whose name
ends in a space was left as it was. They now act on that one file. - A commit message or name of one line of megabytes froze the
window while GitBolt laid it out. Such a line is now shown cut,
ending in "…", in the Commit tab (which says how long a cut subject
or message is), the log and the other views that show commits; Copy
in the log still copies all of it.
Security
These fixes close ways in which a repository you clone or open, or a
server you fetch from, could use GitBolt against you. Most needed you
to do something in GitBolt with the content, such as push, resolve a
conflict or open a file.
- Push could run a command named by a branch. A branch name that
begins with-reached git as an option instead of a name: from the
sidebar's Push, Merge, Rename, Set Upstream, Checkout as local branch
and Delete from remote, and from the toolbar's Push. In a repository
whoseoriginis a folder on your disk, a branch could be named so
that pushing it ran a program. Push, Merge, Set Upstream and Checkout
as local branch now refuse a name that begins with-and say why,
and names reach git after its--, with branches pushed by their
full name. Rename and Delete from remote still work on such a branch,
to get rid of it. - Resolve Conflicts wrote through symbolic links. When the file in
conflict was a symbolic link, the resolution was written to wherever
the link pointed, which could be any file of yours outside the
repository. Resolutions now go into the repository's index and are
written to the working tree from there, never through a link. A
link in conflict is resolved by taking Ours or Theirs as it is; the
dialog says which sides are links. Such a file's resolution used to
be lost from the index, too. A file whose executable bit only the
other side changed keeps it, as git does. Repository › Edit
.gitignore, .gitattributes and .mailmap don't open or save one of
those files when it is a link. - Open Externally ran programs. On macOS, a file marked executable
whose name has no extension (CHANGELOG, say) opens in Terminal and
runs, and so does a.commandfile; a cloned repository can contain
either.
Open Externally now asks before opening a file marked executable or
of a type that runs, or that opens what it points to (on Windows
also shell, Python, Ruby and Perl scripts; on a drive that keeps no
file modes, where every file looks executable, one git has as
executable or one your system would run), with Cancel as the
default and Open Containing Folder offered instead. A symbolic
link that leads out of the working tree isn't opened. File Explorer,
and Open in File Explorer for submodules and worktrees, show folders
and never launch an app, and a submodule path that isn't a path in
the working tree (on Windows, a network path) is refused before
anything touches it. - Removing a worktree could delete another folder. Repository ›
Manage worktrees › Remove deleted whichever folder the worktree's
files in.gitnamed. Anyone who could write to the repository's.git
folder (a repository handed over as a folder or an archive, or kept
in a shared folder) could make it delete any folder. GitBolt now
checks that the worktree links back to the repository, as git does,
and deletes nothing when it doesn't. The question names the folder
that will be deleted. - Text from repositories and servers was read as formatting.
Branch, tag, path and submodule names, and messages from git and
from servers, could carry markup that changed what a question said
(another name shown in place of the real one) or, in a message box,
added a link that one click sent to your browser or another app.
Message boxes, status labels, tooltips and the password prompt now
show such text exactly as it is written. - The Commit tab: a commit's author or committer email could add
attributes to its link, to restyle the tab or point the link at a
file. The email is now just the email. Clicking a link there blanked
the tab; a Parent or Child hash now selects that commit, and an email
opens your mail app. A long author name or email no longer pushes the
other rows out of view. - The Console kept an escape sequence that never ended in memory,
all of it, so printing a crafted file, or a server's messages, slowed
the Console down more and more; and one short escape sequence could
make it take gigabytes of memory, or, repeated, grow one line without
end. All are limited now. - Repositories that froze or crashed GitBolt. A pattern of many
*in a committed.gitattributesmade selecting a commit run
forever at full CPU, and one in.gitattributesor.gitignore
could do the same to opening the repository.
Patterns now give up after a bounded effort, and the patterns real
repositories use match as before. A repository whose commits nest
folders thousands of levels deep used up all memory when GitBolt
opened it, and crashed the File Tree; as git does, GitBolt now stops
at 2,048 levels ("tree too deep"). And a small.gitattributesthat
nests attribute macros could make GitBolt take gigabytes of memory;
what one file's rules can expand to is now limited. These fixes are
in the libgit2 built into every GitBolt download.