From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Ben Gamari Newsgroups: gmane.emacs.devel Subject: [PATCH] autorevert: Wait a while before calling vc-find-file-hook Date: Mon, 26 Oct 2015 19:43:38 +0100 Message-ID: <1445885018-17451-2-git-send-email-ben@smart-cactus.org> References: <1445885018-17451-1-git-send-email-ben@smart-cactus.org> NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1445885069 26735 80.91.229.3 (26 Oct 2015 18:44:29 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 26 Oct 2015 18:44:29 +0000 (UTC) Cc: Ben Gamari , 21559@debbugs.gnu.org, eliz@gnu.org, michael.albinus@gmx.de To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Oct 26 19:44:19 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Zqmkk-0006KX-Kd for ged-emacs-devel@m.gmane.org; Mon, 26 Oct 2015 19:44:19 +0100 Original-Received: from localhost ([::1]:54617 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zqmkj-0006Dv-SS for ged-emacs-devel@m.gmane.org; Mon, 26 Oct 2015 14:44:17 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:56113) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZqmkP-0006CX-16 for emacs-devel@gnu.org; Mon, 26 Oct 2015 14:43:58 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZqmkN-0001Qm-Tv for emacs-devel@gnu.org; Mon, 26 Oct 2015 14:43:56 -0400 Original-Received: from mail.smart-cactus.org ([54.187.36.80]:42289) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZqmkJ-0001LD-He; Mon, 26 Oct 2015 14:43:51 -0400 Original-Received: from localhost.localdomain (HSI-KBW-109-193-204-037.hsi7.kabel-badenwuerttemberg.de [109.193.204.37]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client did not present a certificate) (Authenticated sender: ben@smart-cactus.org) by mail.smart-cactus.org (Postfix) with ESMTPSA id BACAA435AB; Mon, 26 Oct 2015 18:32:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mail.smart-cactus.org; s=mail; t=1445884332; bh=QocgeQvSG1zNDC16y8OycyjTpImOMOkwc4wWDb61f5g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a3GCs44xo5WxxC2JPH+PtZY2O43uDRi3M3R0XScMllaeVcx63VNYlmjcsRgJ2AEyZ 77+5Ggi+p4pd+RYIvhe7Op4sorJBOGbYrVKsdFgvHCAt/S9abqf4UIduAiqy9HD9+r KCUAsXOdvIAQTYiD4QpQDXapdWc0H5V/gJxACTf0= X-Mailer: git-send-email 2.6.1 In-Reply-To: <1445885018-17451-1-git-send-email-ben@smart-cactus.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 54.187.36.80 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:192678 Archived-At: This provides a resolution for Bug #21559. emacs running with `auto-revert-mode` enabled breaks `git rebase` in repositories where files are open. The problem appears to be that `auto-revert-mode` attempts to refresh version control information with `vc-find-file-hook` on revert events. `vc-find-file-hook` calls out to `git`, taking the repository's index lock. This interferes badly with `git rebase`, which performs many git commands in quick succession. When `auto-revert-mode` is enabled there is a very high chance that the following race will occur, git emacs ---------------------- ----------------------------- 1. git rebase checks out a commit, releases `index.lock` 2. `auto-revert-mode` notices change, firing off a `git` process and taking `index.lock`. 3. git rebase applies patch and attempts to commit. Notices that `index.lock` is taken and fails. 4. emacs' `git` process finishes, releasing lock In the end the user is left with a badly broken rebase process and an error message complaining that `index.lock` exists, which he then goes to confirm and finds no such file as emacs has already released the lock. We work around this by scheduling a worker to call `vc-fine-file-hook` at some point in the future when the repository is more likely to be idle (for instance, when there have been no change events for a second or so). Signed-Off-By: Ben Gamari --- lisp/autorevert.el | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/lisp/autorevert.el b/lisp/autorevert.el index 37ee8ee..0c25ac3 100644 --- a/lisp/autorevert.el +++ b/lisp/autorevert.el @@ -136,6 +136,11 @@ auto-revert-tail-mode (defvar auto-revert-timer nil "Timer used by Auto-Revert Mode.") +(defvar auto-revert-vc-check-timer nil + "Timer used by Auto-Revert Mode to schedule +checks of version control information. See +`auto-revert-schedule-vc-check' for details.") + (defcustom auto-revert-interval 5 "Time, in seconds, between Auto-Revert Mode file checks. The value may be an integer or floating point number. @@ -260,6 +265,13 @@ auto-revert-check-vc-info :type 'boolean :version "22.1") +(defcustom auto-revert-vc-check-idle-time 2 + "How much time to wait after noticing a changed file before calling +`vc-find-file-hook' or nil to check immediately." + :group 'auto-revert + :type 'number + :version "25.1") + (defvar-local global-auto-revert-ignore-buffer nil "When non-nil, Global Auto-Revert Mode will not revert this buffer. This variable becomes buffer local when set in any fashion.") @@ -671,7 +683,28 @@ auto-revert-handler ;; `preserve-modes' avoids changing the (minor) modes. But we do ;; want to reset the mode for VC, so we do it manually. (when (or revert auto-revert-check-vc-info) - (vc-find-file-hook)))) + (auto-revert-schedule-vc-check)))) + +(defun auto-revert-schedule-vc-check () + "Schedule a call to `vc-find-file-hook'. + +We need to be careful when calling `vc-find-file-hook' after file changes +as some version control utilities (e.g. git rebase) have a tendency +to do many successive calls and will fail ungracefully if they find +we have taken the repository lock. + +For this reason we wait for the repository to be idle for at least +`auto-revert-vc-check-idle-time' seconds before calling +`vc-find-file-hook'." + (if auto-revert-vc-check-idle-time + (progn + (when (timerp auto-revert-vc-check-timer) + (cancel-timer auto-revert-vc-check-timer)) + (setq auto-revert-vc-check-idle-timer + (run-at-time auto-revert-vc-check-idle-time nil + 'vc-find-file-hook)) + ) + (vc-find-file-hook))) (defun auto-revert-tail-handler (size) (let ((modified (buffer-modified-p)) -- 2.6.1