timbrel / GitSavvy

Full git and GitHub integration with Sublime Text
MIT License
1.91k stars 137 forks source link

Keeps asking me to initialise repository #589

Closed FPtje closed 6 years ago

FPtje commented 7 years ago

There are folders in my sublime project that don't have git initialised. That should be fine, but GitSavvy (Windows) complains at every possible opportunity. When I open the Ctrl + P file menu and type something, a popup appears asking whether I want to initialise a git repository.

I don't. Stop asking me.

Also, these errors are printed in the sublime console:

Traceback (most recent call last):
  File "core.git_command in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 133, in git
  File "core.git_command in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 215, in repo_path
  File "core.git_command in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 255, in _repo_path
  File "core.git_command in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 156, in git
  File "core.git_command in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 119, in raise_error
GitSavvy.core.git_command.GitSavvyError: `C:\Program Files\Git\cmd\git.EXE rev-parse --show-toplevel` failed with following output:

fatal: Not a git repository (or any of the parent directories): .git

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "common.ui in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 289, in run_async
  File "common.ui in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 65, in __init__
  File "common.ui in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 101, in render
  File "common.ui in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 117, in _render_template
  File "common.ui in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 155, in get_keyed_content
  File "./python3.3/collections/__init__.py", line 56, in __init__
SublimeLinter: glualint: sv_purchasing.lua ['C:\\Users\\fpeij\\Programs\\glualint\\dist\\build\\glualint\\glualint.exe']   File "./python3.3/collections/abc.py", line 578, in update

  File "common.ui in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 155, in <genexpr>
  File "core.interfaces.status in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 189, in render_stashes
  File "core.git_mixins.stash in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 13, in get_stashes
  File "core.git_command in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 141, in git
  File "core.git_command in C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Installed Packages\GitSavvy.sublime-package", line 119, in raise_error
GitSavvy.core.git_command.GitSavvyError: `C:\Program Files\Git\cmd\git.EXE rev-parse --show-toplevel` failed with following output:

fatal: Not a git repository (or any of the parent directories): .git

GitSavvy works fine on projects that do have git folder.

stoivo commented 7 years ago

I think we could make it so it would only ask as once per folder that is opened in a window. I'm not sure how to make it now but I think we can do something in these lines.

Is that fine?

stoivo commented 7 years ago

The exception happens because there is not a git repo and the status bar tries to update.

FPtje commented 7 years ago

Ideally I should only be asked to initialize git when I explicitly try to perform some git action in a file that is not controlled by git. Something automatic like the updating of a status bar should never open such a popup.

It makes sense to hide the status bar when not in a repo. Is that an option?

asfaltboy commented 7 years ago

It looks like this was already addressed a long time ago. Seems that we ask "to init" once per view.

@FPtje Could it be that you had multiple GitSavvy dashboard interface views open at the time; e.g git status dashboard, git branch dashboard, etc ? If so, the code as it is right now would ask once per view, per window.

To fix this duplicity, and since the "views_with_offer_made" is already in module global scope, we could store a (hash of) window/root-directory, thus asking only once per root directory in each window, instead of the view ID, which may contain many (e.g tabs) for the same window.

FPtje commented 7 years ago

It has nothing to do with open views or dashboard interfaces, as it even happens when I have zero open tabs. 2017-01-05_08-46-06

I press Ctrl+P, type some stuff and usually that causes that popup to open. It probably has something to do with previewing files. The error is (somewhat) consistently reproducible when I type in "Hash" in Ctrl+P. It previews a binary Haskell interface file that is nested deep inside a folder that is controlled by git.

stoivo commented 7 years ago

If you open this file and run this command in the console

print(view.settings().get('git_savvy.status_view'))
print(view.settings().get("git_savvy.interface"))

By the backtrace it looks like it tries to reload status dashboard

FPtje commented 7 years ago

both None.

stoivo commented 7 years ago

Hmm, Can un uninstall GitSavvy with package manager and install it the less simpel way. https://github.com/divmain/GitSavvy#less-simple

This will give us some better backtrace to look at.

FPtje commented 7 years ago

Well, it does give me a different error:

SublimeLinter: debug mode: on 
SublimeLinter: temp directory: c:\users\fpeij\appdata\local\temp\SublimeLinter3-fpeij 
Traceback (most recent call last):
  File "C:\Program Files\Sublime Text 3\sublime_plugin.py", line 513, in on_selection_modified_async
    callback.on_selection_modified_async(v)
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\Elm Language Support\elm_show_type.py", line 219, in on_selection_modified_async
    sel = view.sel()[0]
  File "C:\Program Files\Sublime Text 3\sublime.py", line 641, in __getitem__
    raise IndexError()
IndexError

(Above error repeated 9 more times)

Package Control: Skipping automatic upgrade, last run at 2017-01-13 21:12:36, next run at 2017-01-13 22:12:36 or after
Traceback (most recent call last):
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\commands\status_bar.py", line 38, in run_async
    short_status = self.get_branch_status_short()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_mixins\active_branch.py", line 99, in get_branch_status_short
    if self.in_rebase():
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_mixins\rewrite.py", line 207, in in_rebase
    return self.in_rebase_apply() or self.in_rebase_merge()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_mixins\rewrite.py", line 204, in in_rebase_apply
    return os.path.isdir(self._rebase_apply_dir)
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_mixins\rewrite.py", line 190, in _rebase_apply_dir
    return os.path.join(self.repo_path, ".git", "rebase-apply")
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 208, in repo_path
    return self._repo_path()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 248, in _repo_path
    throw_on_stderr=throw_on_stderr
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 147, in git
    command_str, stdout, stderr
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 110, in raise_error
    raise GitSavvyError(msg)
GitSavvy.core.exceptions.GitSavvyError: `C:\Program Files\Git\cmd\git.EXE rev-parse --show-toplevel` failed with following output:

fatal: Not a git repository (or any of the parent directories): .git

Note: None of my active repositories are being rebased.

FPtje commented 7 years ago

I just noticed that the first error has nothing to do with GitSavvy. I looked into the second, error, though. There might be a simple explanation: race condition.

In core\commands\status_bar.py, the function run_async suggests that it is being run asynchronously. On line 34, a check runs to see if gitsavvy is in a valid repository.

When the error occurs, that check must have failed, because the function didn't return then and there. The exception, however, is thrown from _repo_path, the exact same function that must have passed at the start. Necessarily, some state must have changed for _repo_path to have different outcomes in two subsequent calls in the same stack trace.

More reproductions of the bug make it more obvious to me: The bug doesn't happen when I type slowly in the file chooser. It does when I type the exact same thing fast.

Also, the bug doesn't happen when I turn off "git status in status bar", which of course makes perfect sense.

stoivo commented 7 years ago

I am very glad you are so competent, you make me feel we can solve this :) . This is quite difficult for me to fix since the error does not a happen to me.

I will come with some suggestions. Could you try to add

            print("working_dir: {}".format(working_dir))

before https://github.com/stoivo/GitSavvy/blob/7bd7aea27b490399820c433c47f7536d58905835/core/git_command.py#L244-L244

FPtje commented 7 years ago

I reproduced the case this time by quickly pasting and cutting and pasting the word hash into the file chooser until the bug happened. The rapid switcher causes sublime to switch between previewing the hash file (which is C:\Users\fpeij\Programs\glualint\.cabal-sandbox\x86_64-windows-ghc-8.0.1\hashable-1.2.4.0-Ctl752zbguF6QanxurLOm2\Data\Hashable.hi) and the file I had open in the currently opened tab. This is the output:

working_dir: C:\Program Files (x86)\Steam\steamapps\common\GarrysMod\garrysmod\lua
working_dir: C:\Program Files (x86)\Steam\steamapps\common\GarrysMod\garrysmod\lua
working_dir: C:\Program Files (x86)\Steam\steamapps\common\GarrysMod\garrysmod\lua
working_dir: C:\Program Files (x86)\Steam\steamapps\common\GarrysMod\garrysmod\lua
working_dir: C:\Users\fpeij\Programs\glualint\.cabal-sandbox\x86_64-windows-ghc-8.0.1\hashable-1.2.4.0-Ctl752zbguF6QanxurLOm2\Data
working_dir: C:\Users\fpeij\Programs\glualint\.cabal-sandbox\x86_64-windows-ghc-8.0.1\hashable-1.2.4.0-Ctl752zbguF6QanxurLOm2\Data
working_dir: C:\Users\fpeij\Programs\glualint\.cabal-sandbox\x86_64-windows-ghc-8.0.1\hashable-1.2.4.0-Ctl752zbguF6QanxurLOm2\Data
working_dir: C:\Program Files (x86)\Steam\steamapps\common\GarrysMod\garrysmod\lua
Traceback (most recent call last):
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 124, in git
    cwd=working_dir or self.repo_path,
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 208, in repo_path
    return self._repo_path()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 249, in _repo_path
    throw_on_stderr=throw_on_stderr
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 147, in git
    command_str, stdout, stderr
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 110, in raise_error
    raise GitSavvyError(msg)
GitSavvy.core.exceptions.GitSavvyError: `C:\Program Files\Git\cmd\git.EXE rev-parse --show-toplevel` failed with following output:

fatal: Not a git repository (or any of the parent directories): .git

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\commands\status_bar.py", line 38, in run_async
    short_status = self.get_branch_status_short()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_mixins\active_branch.py", line 103, in get_branch_status_short
    self._get_branch_status_components()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_mixins\active_branch.py", line 31, in _get_branch_status_components
    stdout = self.git("status", "-b", "--porcelain").strip()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 132, in git
    raise_error(e)
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 110, in raise_error
    raise GitSavvyError(msg)
GitSavvy.core.exceptions.GitSavvyError: `C:\Program Files\Git\cmd\git.EXE rev-parse --show-toplevel` failed with following output:

fatal: Not a git repository (or any of the parent directories): .git

working_dir: C:\Users\fpeij\Programs\glualint\.cabal-sandbox\x86_64-windows-ghc-8.0.1\hashable-1.2.4.0-Ctl752zbguF6QanxurLOm2\Data
working_dir: C:\Program Files (x86)\Steam\steamapps\common\GarrysMod\garrysmod\lua
working_dir: C:\Program Files (x86)\Steam\steamapps\common\GarrysMod\garrysmod\lua

Some things to note:

stoivo commented 7 years ago

Do you have multiple folder open in sublime at the same time or do you open sublime from root? Why does it suggest C:\Users\fpeij\Programs\glualint.cabal-sandbox\x86_64-windows-ghc-8.0.1\hashable-1.2.4.0-Ctl752zbguF6QanxurLOm2\Data ?

FPtje commented 7 years ago

sublime_text_2017-01-14_19-28-07

It's open

stoivo commented 7 years ago

ok, that is totally fine. GitSavvy should work with multiple folders open.

So far it looks like look to me that view.settings().get("git_savvy.repo_path") is returning a invalid git path, to confirm it could you add

        print("repo_path: {}".format(repo_path))

after https://github.com/stoivo/GitSavvy/blob/7bd7aea27b490399820c433c47f7536d58905835/core/git_command.py#L231-L231

asfaltboy commented 7 years ago

Guys this should be easy to reproduce by adding 2 folders to a project, 1 under git control, the other not under git control.

The reason this happens is due to the core functionality of the GitCommand.git method, which calls gs_offer_init if not a git repo.

The status bar command is called for every new/loaded/activated/saved view, which is created (and destroyed) for every file loaded in the background when running quick access (ctrl+p) and invokes _repo_path which in turns calls the aforementioned git method.

I would like to repeat my suggestion to fix this in the core of the offer_init command

we could store a (hash of) window/root-directory, thus asking only once per root directory in each window, instead of the view ID, which may contain many (e.g tabs) for the same window.

FPtje commented 7 years ago

@asfaltboy That's not necessarily the root cause of this problem. The root cause is the race condition affecting _repo_path. In the status bar's update path, it reads that variable multiple times, only validating it at the very beginning. Since it's async, switching between files fast enough causes _repo_path to be updated behind the status bar update's back, causing it to throw the exception saying that it's not in an active repository.

The exception is accompanied with the message asking to initialise the repository. This is fine in all cases where the user is explicitly entering some git command, but obviously not in status bar updates. The _repo_path check at the beginning usually prevents this, but will fail to do its job if _repo_path is changed right after by a different thread.

@stoivo same reproduction mechanism as before:

repo_path: None
repo_path: None
repo_path: None
repo_path: C:\Users\fpeij\Programs\glualint
repo_path: C:\Users\fpeij\Programs\glualint
repo_path: C:\Users\fpeij\Programs\glualint
repo_path: None
repo_path: C:\Users\fpeij\Programs\glualint
repo_path: C:\Users\fpeij\Programs\glualint
repo_path: C:\Users\fpeij\Programs\glualint
repo_path: None
repo_path: C:\Users\fpeij\Programs\glualint
repo_path: C:\Users\fpeij\Programs\glualint
repo_path: C:\Users\fpeij\Programs\glualint
repo_path: None
repo_path: None
Traceback (most recent call last):
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\commands\status_bar.py", line 38, in run_async
    short_status = self.get_branch_status_short()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_mixins\active_branch.py", line 99, in get_branch_status_short
    if self.in_rebase():
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_mixins\rewrite.py", line 207, in in_rebase
    return self.in_rebase_apply() or self.in_rebase_merge()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_mixins\rewrite.py", line 204, in in_rebase_apply
    return os.path.isdir(self._rebase_apply_dir)
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_mixins\rewrite.py", line 190, in _rebase_apply_dir
    return os.path.join(self.repo_path, ".git", "rebase-apply")
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 208, in repo_path
    return self._repo_path()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 249, in _repo_path
    throw_on_stderr=throw_on_stderr
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 147, in git
    command_str, stdout, stderr
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 110, in raise_error
    raise GitSavvyError(msg)
GitSavvy.core.exceptions.GitSavvyError: `C:\Program Files\Git\cmd\git.EXE rev-parse --show-toplevel` failed with following output:

fatal: Not a git repository (or any of the parent directories): .git

repo_path: None
repo_path: None
repo_path: None
repo_path: C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy
repo_path: C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy
repo_path: C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy
repo_path: C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy
repo_path: C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy
repo_path: C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy
repo_path: C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy
repo_path: C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy
asfaltboy commented 7 years ago

Ah, I see now what you mean, though I wouldn't really call it a race condition.

GitSavvy tries to get the branch of an actual repo (while previewing a repo file) then is quickly switched to a non-repo file (when previewing it) and the first command fails to complete with the new view (and related filepath) which changed under it.

Since we can't expect the view of the command called on to point to the same file (or even exist) when we continue, we should probably save the view we're running for and abort any file operations if current view isn't matched to the saved view.

This would resolve other nasty issues; e.g if we had 2 repos open in our project, we would then avoid showing a "wrong" branch in the status bar if we switch between them quickly.

FPtje commented 7 years ago

Where would you put the view check? In every file operation? If you don't do it before every time _repo_path is calculated, you risk not fully fixing the bug.

I reckon the proper solution for this problem, however you want to call it, is to fetch _repo_path once, namely at the start, and use that same path for the rest of the calculation. This pattern also solves your other nasty issues: fetch the view you're running for at the start. Fetch it again at the end. Don't show the status bar stuff if they differ.

That should prevent you from hacking it into file functions, which conceptually have an entirely different task.

stoivo commented 7 years ago

I do think that @FPtje is has a correct point there. I belive that is the correct solution but it will bring a lot of extra work to maintain passing repo_path in all git calls.

I have an other suggestion. Since the problem is that GsUpdateStatusBarCommand get called to frequent, let's a only allow it yo execute every 100 millisecond. If it get called twice then run once now and once in 100 milliseconds. As a user I would never blame the software for showing the wrong branch for 100 millisecond. Also I don't think the user will manage to do any other calls fast enough to reproduce the same issue.

FPtje commented 7 years ago

I don't think it's necessarily the statusbar conflicting with itself that's causing the problem. After all, the repo_path is changed by however sublime chooses what the current file is.

asfaltboy commented 7 years ago

@FPtje Yep, that sounds about right. Though I can't reproduce this as easily as I initially thought, yet to figure out the conditions - might be environmental.

Exactly @stoivo, it's not about how many times you get the path, but when. Our GsUpdateStatusBarCommand command runs sync initially, triggered by events, but it can start with one file, then later (during it's async phase) finish on another since the view (or the open file inside of it?) changed. The fact that the file_path is a "cached" property doesn't help either.

I'm suggest a simple patch like this:

diff --git a/core/commands/status_bar.py b/core/commands/status_bar.py
index 45ebdc3..bcf08e9 100644
--- a/core/commands/status_bar.py
+++ b/core/commands/status_bar.py
@@ -26,12 +26,13 @@ class GsUpdateStatusBarCommand(TextCommand, GitCommand):
     """

     def run(self, edit):
         if sublime.load_settings("GitSavvy.sublime-settings").get("git_status_in_status_bar"):
+            self._status_for_file = self.view.file_name()
             sublime.set_timeout_async(self.run_async, 0)

     def run_async(self):
         # Short-circuit update attempts for files not part of Git repo.
-        if not self._repo_path(throw_on_stderr=False):
+        if not self._repo_path(throw_on_stderr=False) or self._status_for_file != self.view.file_name():
             self.view.erase_status("gitsavvy-repo-status")
             return
FPtje commented 7 years ago

That would only check the file_name at the start of the async function, leaving it free to be changed at any point between that if statement and the end of the function, which is where the issue has been occurring thus far. Remember, this is a race condition. Depending on the order of Sublime's file choosing thread and the statusbar update thread, _repo_path is valid at one point, yet invalid (because of outside change) at some later point in the same call stack.

stoivo commented 7 years ago

I thought of something like this https://github.com/divmain/GitSavvy/compare/master...stoivo:statusbar_update?expand=1

This does not solve the problem directly but I think it would in practice.

FPtje commented 7 years ago

The issue occurs within a single run of that function. Why would adding time between two calls of it solve it in practice?

asfaltboy commented 7 years ago

You're right @FPtje, my bad. If sublime does replace the view's file when previewing, we have to check we're still operating on our initial file to continue executing _repo_path. Can you try this patch?

diff --git a/core/commands/status_bar.py b/core/commands/status_bar.py
index 45ebdc3..191335d 100644
--- a/core/commands/status_bar.py
+++ b/core/commands/status_bar.py
@@ -27,6 +27,7 @@ class GsUpdateStatusBarCommand(TextCommand, GitCommand):

     def run(self, edit):
         if sublime.load_settings("GitSavvy.sublime-settings").get("git_status_in_status_bar"):
+            self._run_for_file = self.view.file_name()
             sublime.set_timeout_async(self.run_async, 0)

     def run_async(self):
diff --git a/core/git_command.py b/core/git_command.py
index ac98acb..06651bf 100755
--- a/core/git_command.py
+++ b/core/git_command.py
@@ -231,6 +231,10 @@ class GitCommand(StatusMixin,
         repo_path = view.settings().get("git_savvy.repo_path")

         if not repo_path or not os.path.exists(repo_path):
+            if hasattr(self, '_run_for_file') and view.file_name() != self._run_for_file:
+                # command for this view MUST match given path
+                return None
+
             file_path = self.file_path
             file_dir = os.path.dirname(file_path) if file_path else None
             working_dir = file_path and os.path.isdir(file_dir) and file_dir
asfaltboy commented 7 years ago

@stoivo even if it won't solve our particular issue, that's a cool idea to throttle down some wasteful calls. Need to see how it works in practice.

stoivo commented 7 years ago

@FPtje, my patch would not solve the issue, but remove wasteful calls like @asfaltboy commented. I a reduce the change of witting you issue.

FPtje commented 7 years ago

Passing down repo_path would take some work, but has some benefits:

The only problem could be an early call to run_async being slow and overwriting the state of a later call. To solve that, just make sure that there is only one thread that calculates the status command. Pseudocode of run would be:

if self.gsStatusBarThread.Alive():
   self.gsStatusBarThread.Kill()

gsStatusBarThread = new Thread(self.run_async) 
gsStatusBarThread.Start()

This would also make sure that at no point there would be two or more threads calculating status bar info. You always only need one, so it makes sense to enforce that.

stoivo commented 7 years ago

@FPtje, Are you interested in some OS work?

FPtje commented 7 years ago

OS as in operating system work?

stoivo commented 7 years ago

Open Source, maybe more people say OSS for this Open Source Softwere

FPtje commented 7 years ago

Oh, of course. I'm not sure whether I can find the time to do it.

asfaltboy commented 7 years ago

@FPtje all git commands take some work; thus, we already "cache" repo_path for a given view, which is part of our problem; if the view is being reused.

We can confirm this by modifying the last print command @stoivo asked you to perform like so:

    print("repo_path: {} (view_id: {})".format(repo_path, view.id()))

You can also add another print right after getting file_path like so:

        print("file_path: {} (view_id: {}, actual view file: {})".format(
            file_path, view.id(), view.file_name()))

After you've confirmed our assumption of "view reuse for multiple files (during preview)", try to apply the latest patch I've pasted above. If you have trouble applying the patch, try checking out this branch instead.

Thank you again for being patient and helping out. Since currently only you can reproduce the issue, so your participation is appreciated.

FPtje commented 7 years ago
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 111)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 111)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 111)
repo_path: None (view_id: 112)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 112)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 112)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 112)
repo_path: None (view_id: 113)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 113)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 113)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 113)
repo_path: None (view_id: 114)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 114)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 114)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 114)
repo_path: None (view_id: 115)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 115)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 115)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 115)
repo_path: None (view_id: 116)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 116)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 116)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 116)
repo_path: None (view_id: 117)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 117)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 117)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 117)
repo_path: None (view_id: 118)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 118)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 118)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 118)
repo_path: None (view_id: 119)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 119)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 119)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 119)
repo_path: None (view_id: 120)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 120)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 120)
repo_path: None (view_id: 120)
Traceback (most recent call last):
  File "C:\Program Files\Sublime Text 3\sublime_plugin.py", line 812, in run_
    return self.run(edit, **args)
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\common\commands\log.py", line 15, in run
    panel_view = self.view.window().create_output_panel(PANEL_NAME)
AttributeError: 'NoneType' object has no attribute 'create_output_panel'
Traceback (most recent call last):
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 124, in git
    cwd=working_dir or self.repo_path,
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 208, in repo_path
    return self._repo_path()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 249, in _repo_path
    throw_on_stderr=throw_on_stderr
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 147, in git
    command_str, stdout, stderr
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 110, in raise_error
    raise GitSavvyError(msg)
GitSavvy.core.exceptions.GitSavvyError: `C:\Program Files\Git\cmd\git.EXE rev-parse --show-toplevel` failed with following output:

fatal: Not a git repository (or any of the parent directories): .git

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\commands\status_bar.py", line 38, in run_async
    short_status = self.get_branch_status_short()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_mixins\active_branch.py", line 103, in get_branch_status_short
    self._get_branch_status_components()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_mixins\active_branch.py", line 31, in _get_branch_status_components
    stdout = self.git("status", "-b", "--porcelain").strip()
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 132, in git
    raise_error(e)
  File "C:\Users\fpeij\AppData\Roaming\Sublime Text 3\Packages\GitSavvy\core\git_command.py", line 110, in raise_error
    raise GitSavvyError(msg)
GitSavvy.core.exceptions.GitSavvyError: `C:\Program Files\Git\cmd\git.EXE rev-parse --show-toplevel` failed with following output:

fatal: Not a git repository (or any of the parent directories): .git

repo_path: None (view_id: 122)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 122)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 122)
repo_path: C:\Users\fpeij\Programs\glualint (view_id: 122)
repo_path: None (view_id: 2)
repo_path: None (view_id: 2)
stoivo commented 7 years ago

@FPtje, We did you solve you exact issue but we added the limit you who often it updated the status bar. Can you see if you can reproduce the issue now? You should pull the latest first. At least release 2.14.0.

FPtje commented 7 years ago

I have seen the bug on 2.14.0 on my Linux installation.

stoivo commented 7 years ago

hmm, I know that we did not fix the error at all. But I hope it is less frequent.

I think I can do change it so it will only prompt once per window der folder.

p3lim commented 7 years ago

While at it, could you add an option to completely stop this popup from ever showing? If I want to initialize git in a directory I'll do it manually through the menu.

firelizzard18 commented 7 years ago

@p3lim I created #664 to explicitly request an option to disable this. Please +1 that issue. Maybe it will get some traction that way.

@asfaltboy @stoivo

stoivo commented 6 years ago

Since we have the option to disable the popup. Can we just close this?

If you work with folders outside a git repo you will disable it permanently and will call it from the command prompt when needed?

I still look at this as a UX which could be improved. Since none of us have unlimited time, I would rather spend the time fixing some other issues :D