macsAir

Collecting frequent-committer miles

Magit 2.4 released

I am excited to announce the release of Magit version 2.4,
consisting of 269 commits since the last feature release two and a
half months ago. The release notes can be found
here.

It’s Magit! A Git Porcelain inside Emacs

Magit is an interface to the version control system Git, implemented
as an Emacs package. Magit aspires to be a complete Git porcelain.
While we cannot (yet) claim that Magit wraps and improves upon each
and every Git command, it is complete enough to allow even experienced
Git users to perform almost all of their daily version control tasks
directly from within Emacs. While many fine Git clients exist, only
Magit and Git itself deserve to be called porcelains.

A little history

Half a year ago I released version 2.1, which was the first major
release in over two and a half years. The reception was mostly
positive, and quite a few power-users were euphoric about some of the
additions and refinements. I think it is justified to say, that Magit
took a huge leap forward.

But, as it is common for major rewrites, that release also contained a
few controversial changes and regressions, most of which were
addressed in the 2.2 release, whose slogan was deal with
regressions and “previously it was better”.

Then I moved on to tackle the backlog of open feature requests, and
implemented most of them in the 2.3 release. The slogan of that
release was get rid of the backlog (so that I can later concentrate
on the really important things).

And now…

Improve push, pull, fetch, and branch commands

The slogan of this release is to deal with the fact that everyone
has a different opinion on how branching and pushing should work.

The 2.1 release contained some changes to push and branch commands
which I believed to be non-intrusive and obvious. But it turned out
that one of these changes took some users by surprise. They did not
notice that creating a branch now also caused the upstream of the new
branch to be set (even though that information is being displayed at
the top of the status buffer) and as a result they ended up
unintentionally and prematurely pushing feature branches to master
on the upstream repository.

I was forced to make the “push the current branch to its configured
upstream” command always ask for confirmation, at least by default.
That was the only viable solution in the short term, which prevented
users from shooting themselves in the foot. But that “unnecessary”
confirmation dialog in turn upset some other users.

And then many suggestions started pouring in. Opinions on what is the
best (or “obviously only sane way”) to implement these features
diverge massively, and (since there now was a safety net in place) I
decided to delay my attempt to come up with a new interface that would
hopefully be acceptable to most users.

I also decided that improving these features incrementally was not an
option - the criticism along the way would have been unbearable. (In
particular I wanted to avoid “why are you changing this again?”.)
And since I have wanted to implement support for a “triangular branch
workflow” for a very long time now (since before I became Magit’s
maintainer), that meant that I had to do that at the same time. (That
is consistent with the slogan of this release - “everyone” includes
myself.)

I have implemented the triangular workflow a few weeks ago and merged
the result into master, the development branch. I also took into
account many of the concerns that were voiced earlier and
subsequently. Since most Emacs users nowadays install packages by
installing Melpa snapshots of the development branch, these changes
already had quite some exposure. The responses so far were very
mixed, ranging from “this is fantastic” to “the interface is
dysfunctional, you’ve designed software for imaginary users and
imaginary needs”.

A few things became very clear. (1) There is no satisfying everyone -
the willingness to reason about an initially inconvenient change is
not present in all users. (2) It would be advisable to write a
tutorial explaining what a triangular branch workflow is, why many
users are likely already using one without knowing it, and how the
changes to the Magit interface fit into the picture. And (3) I would
also have to explain how to restore the old key bindings and how to
revert some other changes.

Unfortunately it turned out that writing a tutorial suitable for both
power-users as well as beginners, would be a major amount of work. I
still haven’t finished that and have given up on doing so before the
release of version 2.4. The 2.1 release was delayed by
several months because I was stuck rewriting the manual; I do not want
something similar to happen here too.

However, the manual contains a
brief description of
the push-remote and triangular branch workflows.

If you want to restore some of the old key bindings, or even disable
push-remote support all together, then please see
this wiki page.

Speedup automatic reverts of file-visiting buffers

Starting with the 2.1 release, the option magit-revert-buffers
controlled if and how buffers that visit files that are tracked by Git
are reverted after the visited files changed on disk.

That option and the associated code replaced an earlier implementation
whose entry point was magit-auto-revert-mode and which was built on
top of the autorevert library, which is part of Emacs. When
upstream changes broke that implementation I decided to create an
independent, magit-specific implementation instead. But that turned
out to be a mistake. It complicated the code and the new
implementation was too inefficient when there are many open buffers
and/or tracked files.

I had to go back to implementing Magit’s auto-revert feature as an
extension of Emacs’ auto-revert feature. But this time we don’t
directly use functions that are only intended for internal use.
Instead the restored magit-auto-revert-mode is now a globalized
variant of the local mode auto-revert-mode.

If you have previously disabled the automatic reverts by setting
magit-revert-buffers to nil, then that should still be respected -
but please double-check. And if you don’t know whether you want
buffers to be automatically reverted, then please read the
documentation, to be able to make an informed choice.
magit-auto-revert-mode is enabled by default, because (1) if it were
not, then that would make many common tasks (such as discarding a
change and then continuing to edit the affected buffer) much more
inconvenient, and (2) it takes a very unusual workflow for the
automatic reverts to potentially cause data loss. (Such workflows
would be risky even without the automatic reverts.)