E 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.

For more information about Magit, see https://magit.vc.

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.)

Please read about this in the manual.

Comments on Here, Reddit, G+