Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spacemacs interferes with external git usage #2868

Closed
bgamari opened this issue Sep 3, 2015 · 4 comments
Closed

Spacemacs interferes with external git usage #2868

bgamari opened this issue Sep 3, 2015 · 4 comments

Comments

@bgamari
Copy link
Contributor

bgamari commented Sep 3, 2015

If I have buffers open for files tracked in a git repository vc-mode starts git processes whenever a file is externally modified. This have very unfortunate consequences when I git rebase as something like the following occurs,

  1. rebase checks out a commit
  2. emacs notices files changed, tells vc which then fires up a git ls-files command
  3. git ls-files grabs the index lock
  4. rebase tries to commit, sees that the index lock is taken, fails with,
fatal: Unable to create '/opt/exp/ghc/ghc-landing/.git/index.lock': File exists.

If no other git process is currently running, this probably means a
git process crashed in this repository earlier. Make sure no other git
process is running and remove the file manually to continue.
  1. git ls-files finishes, releasing the lock

This is quite frustrating as it leaves your repository in an unknown state, which then requires careful gymastics to get out of.

Details

To work out what was responsible for emacs starting git processes I traced call-process invocations with,

(fset 'real-call-process 'call-process)
(defun call-process (prog &optional infile dest displ &rest args)
       (message "call-proces %s" prog)
       (backtrace)
       (real-call-process prog infile dest displ args))

This revealed that vc's auto-revert-handle hook is the culprit,

nil) nil ((((((((...)))))))))
  real-call-process("git" nil (t nil) nil ((((((((...)))))))))
  ... ;; Lots of repeated frames
  real-call-process("git" nil (t nil) nil ((((((((...)))))))))
  real-call-process("git" nil (t nil) nil ((((((((...)))))))))
  real-call-process("git" nil (t nil) nil ((((((((...)))))))))
  real-call-process("git" nil (t nil) nil (((((((("ls-files" "-c" "-z" "--" "rts/Libdw.h")))))))))
  real-call-process("git" nil (t nil) nil ((((((("ls-files" "-c" "-z" "--" "rts/Libdw.h"))))))))
  real-call-process("git" nil (t nil) nil (((((("ls-files" "-c" "-z" "--" "rts/Libdw.h")))))))
  real-call-process("git" nil (t nil) nil ((((("ls-files" "-c" "-z" "--" "rts/Libdw.h"))))))
  real-call-process("git" nil (t nil) nil (((("ls-files" "-c" "-z" "--" "rts/Libdw.h")))))
  real-call-process("git" nil (t nil) nil ((("ls-files" "-c" "-z" "--" "rts/Libdw.h"))))
  real-call-process("git" nil (t nil) nil (("ls-files" "-c" "-z" "--" "rts/Libdw.h")))
  real-call-process("git" nil (t nil) nil ("ls-files" "-c" "-z" "--" "rts/Libdw.h"))
  call-process("git" nil (t nil) nil "ls-files" "-c" "-z" "--" "rts/Libdw.h")
  apply(call-process "git" nil (t nil) nil ("ls-files" "-c" "-z" "--" "rts/Libdw.h"))
  process-file("git" nil (t nil) nil "ls-files" "-c" "-z" "--" "rts/Libdw.h")
  apply(process-file "git" nil (t nil) nil "ls-files" ("-c" "-z" "--" "rts/Libdw.h"))
  vc-git--call((t nil) "ls-files" "-c" "-z" "--" "rts/Libdw.h")
  apply(vc-git--call (t nil) "ls-files" ("-c" "-z" "--" "rts/Libdw.h"))
  vc-git--out-ok("ls-files" "-c" "-z" "--" "rts/Libdw.h")
  vc-git-registered("/opt/exp/ghc/ghc-dwarf/rts/Libdw.h")
  apply(vc-git-registered "/opt/exp/ghc/ghc-dwarf/rts/Libdw.h")
  vc-call-backend(Git registered "/opt/exp/ghc/ghc-dwarf/rts/Libdw.h")
  ;; A couple frames of garbage
  vc-registered("/opt/exp/ghc/ghc-dwarf/rts/Libdw.h")
  vc-backend("/opt/exp/ghc/ghc-dwarf/rts/Libdw.h")
  vc-find-file-hook()
  auto-revert-handler()
  auto-revert-notify-handler(((6 . "Libdw.h") attribute-changed "/opt/exp/ghc/ghc-dwarf/rts/Libdw.h"))
  file-notify-callback((6 (attrib) "Libdw.h" 0))
  file-notify-handle-event((file-notify (6 (attrib) "Libdw.h" 0) file-notify-callback))
  funcall-interactively(file-notify-handle-event (file-notify (6 (attrib) "Libdw.h" 0) file-notify-callback))
  call-interactively(file-notify-handle-event nil [(file-notify (6 (attrib) "Libdw.h" 0) file-notify-callback)])
  command-execute(file-notify-handle-event nil [(file-notify (6 (attrib) "Libdw.h" 0) file-notify-callback)] t)
@bgamari
Copy link
Contributor Author

bgamari commented Sep 3, 2015

I suspect spacemacs setting global-auto-revert-mode is the reason for this. I agree that this is a desirable default, but I don't see any way to make this safe in the face of external version control usage.

One imperfect solution would be to use some sort of hold-off strategy to defer running the vc-find-file-hook until the file appears idle. This will make this sort of race much less likely, although still possible.

@bgamari
Copy link
Contributor Author

bgamari commented Sep 3, 2015

In fact, it's not clear to me why vc-git is even enabled. Isn't magit supposed to be the preferred git layer?

@bgamari
Copy link
Contributor Author

bgamari commented Sep 28, 2015

I have finally tracked this one down and filed it as gnu bug #21559

@TheBB
Copy link
Collaborator

TheBB commented Oct 28, 2015

Good job tracking this down and good luck tackling the Emacs dev environment. :-)

Since this is reported upstream and it's likely to be a while (and we are doing a cleanup), I will close this now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants