linrongbin16 / gitlinker.nvim

Maintained fork of ruifm's gitlinker, refactored with bug fixes, ssh aliases, blame support and other improvements.
GNU General Public License v3.0
163 stars 9 forks source link

Question about debugging #234

Closed hqkhan closed 6 months ago

hqkhan commented 7 months ago

Hello, I have a custom remote that I'm creating links for. It works great when I am on a branch. I'm running into an issue when I detach from tip to a specific commit in my history.

I get the error: [gitlinker] fatal: HEAD does not point to a branch. My git status shows:

 git status
HEAD detached at 9a54594

I wasn't sure how to go about debugging this. Thanks.

linrongbin16 commented 7 months ago

hi @hqkhan ,

you can set { debug = true, file_log = true } when setup this plugin, it will enable file logs.

see: https://github.com/linrongbin16/gitlinker.nvim/blob/839215b322b15b662c08a010534e8de00dae38a6/lua/gitlinker/configs.lua#L182

if you need to add more logs, you will have to clone this repo, and enable development mode on this repo with a plugin manager, say lazy.nvim.

linrongbin16 commented 7 months ago

@hqkhan ,

try to push your local commits to remote, and try again.

the error message looks like git says: this commit/branch doesn't exist in remote.

hqkhan commented 7 months ago

@linrongbin16 Thanks for letting me know about the debug flag. I will look into this more.

Here's a few situations that I'm playing with:

  1. No changes in current branch and HEAD is not detached -- Works
  2. In repos with my remote, I go to a previous commit in history (all have been pushed to remote) -- Doesn't work.
  3. In repos WITHOUT my remote (normal github repos), ''' -- Works
hqkhan commented 7 months ago

How do I enable debug and file_log? Here's my setup:

return {
  "linrongbin16/gitlinker.nvim",
  cmd = "GitLink",
  opts = { debug=true, file_log=true },
  keys = {
    { "<leader>gy", "<cmd>GitLink<cr>", mode = {"n", "v"}, desc = "Yank git link" },
  },
end
}

I put debug on the outmost layer but I didn't see anything in messages. Are logs stored in a specific place?

linrongbin16 commented 7 months ago

@hqkhan

sorry forgot to tell, it should be ~/.local/nvim. you can type :echo stdpath('data') in neovim, and get the log file path.

hqkhan commented 7 months ago

I apologize for my naive questions lol. I still couldn't find the log file. For me, stdpath is ~/.local/share.

.local/share/nvim on  main
 ls
lazy/  mason/  undodir/

That's what I see in there. I navigated to /local/home/hqkhan/.local/share/nvim/lazy/gitlinker.nvim. I was trying to find some log file to look at. Here's what I see when I search for log in the directory.

nvim/lazy/gitlinker.nvim on  master via 🌙 v5.1.4
 fd log
CHANGELOG.md
lua/gitlinker/commons/logging.lua
linrongbin16 commented 7 months ago

hi @hqkhan ,

sorry I didn't provide enough details:

the log file name should be gitlinker.log, and it's not in lazy.nvim folder (the lazy.nvim folder contains the plugin, not the log).

for my working machine, it looks like:

image
linrongbin16 commented 7 months ago

hi @hqkhan , do you have any other issues I could help?

hqkhan commented 7 months ago

Hi @linrongbin16 . Sorry for being Mia. I haven't gotten time to dig into this but I will do it soon. I can close this issue and come back to it with some info once I have it.

linrongbin16 commented 7 months ago

@hqkhan , no worry, we don't have a deadline here, just leave this issue here as a reminder.

hqkhan commented 7 months ago

Sweet, thank you!

hqkhan commented 7 months ago

Hi @linrongbin16. I'm still having trouble locating the log file 😅 . I think this may be an indication that it's not turned on properly. Do you know how I can turn it on in lazy?

Here's my config:

return {
  "linrongbin16/gitlinker.nvim",
  cmd = "GitLink",
  opts = { debug = true, file_log = true },
  keys = {
    { "<leader>gy", "<cmd>GitLink<cr>", mode = { "n", "v" }, desc = "Yank git link" },
  },
  config = function()
    local cfg = {
      router = {
        browse = {
          ["^git.**.com"] = "https://**/"
              .. "packages/"
              .. "{_A.REPO}/blobs/"
              .. "{_A.REV}/"
              .. "--/"
              .. "{_A.FILE}"
        },
      }
    }
    require "gitlinker".setup(cfg)
  end
}

Output of searching for log file:

/home/hqkhan/.local on  main
 fd gitlinker
share/nvim/lazy/gitlinker.nvim/
share/nvim/lazy/gitlinker.nvim/lua/gitlinker/
share/nvim/lazy/gitlinker.nvim/lua/gitlinker.lua
share/nvim/lazy/gitlinker.nvim/spec/gitlinker/
share/nvim/lazy/gitlinker.nvim/spec/gitlinker_spec.lua
share/nvim/undodir/%local%home%hqkhan%.config%nvim%lua%plugins%gitlinker.lua
state/nvim/lazy/readme/doc/gitlinker.nvim.md
linrongbin16 commented 7 months ago

the debug option looks good, it's will override the defaults here: https://github.com/linrongbin16/gitlinker.nvim/blob/839215b322b15b662c08a010534e8de00dae38a6/lua/gitlinker/configs.lua#L182

can you try to clone this project to your local machine, and in lazy.nvim, set it to dev?

see: 1.set dev for a local plugin: https://github.com/folke/lazy.nvim?tab=readme-ov-file#-plugin-spec

  1. config local plugin folder: https://github.com/folke/lazy.nvim?tab=readme-ov-file#%EF%B8%8F-configuration
hqkhan commented 6 months ago

I tried the above but still can't get the log file to show.

Lazy gitlinker info

image

Gitlinker config

return {
  "linrongbin16/gitlinker.nvim",
  cmd = "GitLink",
  dev = true,
  opts = { debug = true, file_log = true },
  keys = {
    { "<leader>gy", "<cmd>GitLink<cr>", mode = { "n", "v" }, desc = "Yank git link" },
  },
  config = function()
    local cfg = {
      router = {
        browse = {
          ["^git.**"] = "https://**/"
              .. "packages/"
              .. "{_A.REPO}/blobs/"
              .. "{_A.REV}/"
              .. "--/"
              .. "{_A.FILE}"
        },
      }
    }
    require "gitlinker".setup(cfg)
  end
}

Lazy config

lazy.setup("plugins", {
  defaults = { lazy = true },
  dev = {
    path = "~/Sources/nvim",
  },
  install = { colorscheme = { "lua-embark", "rogue" } },
  checker = { enabled = false },
  ui = {
    border = "rounded",
    custom_keys = {
      ["<localleader>l"] = false,
      ["<localleader>t"] = false,
    },
  },
  debug = false,
})

Trying to find gitlinker log file after going back to previous commits

hqkhan/.local/share on  main
 fd --glob *.log
nvim/mason/packages/lua-language-server/libexec/log/file_local_home_hqkhan_.config_nvim.log
nvim/mason/packages/lua-language-server/libexec/log/service.log
nvim/undodir/%local%home%hqkhan%.local%state%nvim%lsp.log

hqkhan/.local/share on  main
 fd gitlinker
nvim/undodir/%local%home%hqkhan%.config%nvim%lua%plugins%gitlinker.lua
linrongbin16 commented 6 months ago

hi @hqkhan ,

the Gitlinker config should be:

return {
  "linrongbin16/gitlinker.nvim",
  cmd = "GitLink",
  dev = true,
  opts = { 
      router = {
        browse = {
          ["^git.**"] = "https://**/"
              .. "packages/"
              .. "{_A.REPO}/blobs/"
              .. "{_A.REV}/"
              .. "--/"
              .. "{_A.FILE}"
        },
      }
      debug = true,
      file_log = true
  },
  keys = {
    { "<leader>gy", "<cmd>GitLink<cr>", mode = { "n", "v" }, desc = "Yank git link" },
  },
}

or:

return {
  "linrongbin16/gitlinker.nvim",
  cmd = "GitLink",
  dev = true,
  opts = { debug = true, file_log = true },
  keys = {
    { "<leader>gy", "<cmd>GitLink<cr>", mode = { "n", "v" }, desc = "Yank git link" },
  },
  config = function(opts)
      opts = opts or {}
      opts.router = {
        browse = {
          ["^git.**"] = "https://**/"
              .. "packages/"
              .. "{_A.REPO}/blobs/"
              .. "{_A.REV}/"
              .. "--/"
              .. "{_A.FILE}"
        },
      }
      opts.debug = true
      opts.file_log = true
    }
    require "gitlinker".setup(opts)
  end
}

Note the usage of opts and config in lazy.nvim PluginSpec.

hqkhan commented 6 months ago

Oh! Thank you! I do see log file now. I'll look into what the issue is now. Appreciate the help!

hqkhan commented 6 months ago

Writing out my thought process and whatever findings in case I don't find it.

I'm comparing against my detached from HEAD repo versus this repo detached from HEAD which works fine. Trying to locate the differences in calls.

Difference

Mine:

2024-04-17 00:59:47,592445 [@/local/home/hqkhan/Sources/nvim/gitlinker.nvim/lua/gitlinker/git.lua:48] DEBUG: |_run_cmd| args:{ "git", "rev-parse", "--show-toplevel" }, cwd:"/local/home/hqkhan/..."
2024-04-17 00:59:47,596745 [@/local/home/hqkhan/Sources/nvim/gitlinker.nvim/lua/gitlinker/git.lua:48] DEBUG: |_run_cmd| args:{ "git", "remote" }, cwd:"/local/home/hqkhan/..."
2024-04-17 00:59:47,601434 [@/local/home/hqkhan/Sources/nvim/gitlinker.nvim/lua/gitlinker/git.lua:48] DEBUG: |_run_cmd| args:{ "git", "rev-parse", "--abbrev-ref", "@{u}" }, cwd:"/local/home/hqkhan/..."

Calling git rev-parse --abrev-ref @{u} on detached HEAD returns error.

Gitlinker:

2024-04-17 01:00:14,084895 [@/local/home/hqkhan/Sources/nvim/gitlinker.nvim/lua/gitlinker/git.lua:48] DEBUG: |_run_cmd| args:{ "git", "rev-parse", "--show-toplevel" }, cwd:"/local/home/hqkhan/Sources/nvim/gitlinker.nvim"
2024-04-17 01:00:14,089462 [@/local/home/hqkhan/Sources/nvim/gitlinker.nvim/lua/gitlinker/git.lua:48] DEBUG: |_run_cmd| args:{ "git", "remote" }, cwd:"/local/home/hqkhan/Sources/nvim/gitlinker.nvim"
2024-04-17 01:00:14,094570 [@/local/home/hqkhan/Sources/nvim/gitlinker.nvim/lua/gitlinker/git.lua:48] DEBUG: |_run_cmd| args:{ "git", "remote", "get-url", "origin" }, cwd:"/local/home/hqkhan/Sources/nvim/gitlinker.nvim"
2024-04-17 01:00:14,099705 [@/local/home/hqkhan/Sources/nvim/gitlinker.nvim/lua/gitlinker/linker.lua:53] DEBUG: |make_linker| remote:"origin", parsed_url:{
  host = "github.com",
  host_pos = {
...

We're in the get_branch_remote function. If we have one remote, we simply return it. Otherwise, we continue to call the problematic line which returns error.

My repo has three remotes. Shouldn't we do a check before running this command? If we're on a detached HEAD, using @{u} won't work as we know but we can do something simple like potentially:

Sources/nvim/gitlinker.nvim (47d163f) via 🌙 v5.1.4
 git rev-parse HEAD
47d163f0ea6feeb7207ac39f24e97f41634338a2

That said, even in gitlinker repo, it does end up calling git rev-parse @{u} which throws an error:

Sources/nvim/gitlinker.nvim (47d163f) via 🌙 v5.1.4
 git rev-parse @{u}
fatal: HEAD does not point to a branch

Also seen in logs (I abbreviated earlier logs to not flood this comment):

}, parsed_err:nil
2024-04-17 01:00:14,100129 [@/local/home/hqkhan/Sources/nvim/gitlinker.nvim/lua/gitlinker/git.lua:48] DEBUG: |_run_cmd| args:{ "ssh", "-ttG", "github.com" }, cwd:"/local/home/hqkhan/Sources/nvim/gitlinker.nvim"
2024-04-17 01:00:14,107411 [@/local/home/hqkhan/Sources/nvim/gitlinker.nvim/lua/gitlinker/git.lua:48] DEBUG: |_run_cmd| args:{ "git", "rev-parse", "@{u}" }, cwd:"/local/home/hqkhan/Sources/nvim/gitlinker.nvim"
2024-04-17 01:00:14,112199 [@/local/home/hqkhan/Sources/nvim/gitlinker.nvim/lua/gitlinker/git.lua:48] DEBUG: |_run_cmd| args:{ "git", "config", "remote.origin.fetch" }, cwd:"/local/home/hqkhan/Sources/nvim/gitlinker.nvim"
2024-04-17 01:00:14,117377 [@/local/home/hqkhan/Sources/nvim/gitlinker.nvim/lua/gitlinker/git.lua:48] DEBUG: |_run_cmd| args:{ "git", "branch", "--remotes", "--contains", "HEAD" }, cwd:"/local/home/hqkhan/Sources/nvim/gitlinker.nvim"

but the above did not throw error otherwise, it would've failed.

linrongbin16 commented 6 months ago

hi @hqkhan ,

really thanks to your efforts, it seems when there're multiple remotes, and a detached HEAD, it would fail.

But can you educate me, how to create a detached HEAD with, for example, this linrongbin16/gitlinker.nvim repo? So I could reproduce this issue, and have a closer look at it.

hqkhan commented 6 months ago

Sorry, I may have worded it a bit weird. I simply check out an older commit from whichever branch I'm on. You should be able to simply do git checkout <commit_hash_short> to get to this state.

Thank you for looking into this!

linrongbin16 commented 6 months ago

hi @hqkhan ,

I failed to reproduce this issue, here are my steps:

  1. git pull in this linrongbin16/gitlinker.nvim repo, make sure it's the latest master (commit: 839215b, full: 839215b322b15b662c08a010534e8de00dae38a6).
  2. use git checkout 46ec82f8 to checkout an older commit (46ec82f89212f4792e7a32d7a8b0a8b7f183fce8).
  3. Open nvim (with gitlinker installed) in this repo, open the configs.lua source code file, and press <leader>gL to open the url in browser: https://github.com/linrongbin16/gitlinker.nvim/blob/46ec82f89212f4792e7a32d7a8b0a8b7f183fce8/lua/gitlinker/configs.lua?plain=1#L3
  4. It works correctly for me.

Update-1

I'm trying to use a forked git repo (https://github.com/linrongbin16/awesome-neovim) to reproduce this issue again.

I think it's forked from other people so it will contain multiple remotes, which may be easier to reproduce this issue.

The .git/config in this repo is:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
[remote "origin"]
    url = https://github.com/linrongbin16/awesome-neovim.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
    remote = origin
    merge = refs/heads/main
[branch "linrongbin16-fzfx-nvim"]
    remote = origin
    merge = refs/heads/linrongbin16-fzfx-nvim
[remote "upstream"]
    url = https://github.com/rockerBOO/awesome-neovim
    fetch = +refs/heads/*:refs/remotes/upstream/*

The linrongbin16/awesome-neovim is 2 commits ahead of, 30 commits behind of the upstream rockerBOO/awesome-neovim.

And in linrongbin16/awesome-neovim, there's my personal develop branch linrongbin16-fzfx-nvim.

Here're steps that seems can reproduce this issue:

  1. git clone https://github.com/linrongbin16/awesome-neovim to clone this repo.
  2. git switch linrongbin16-fzfx-nvim to switch to linrongbin16-fzfx-nvim branch.
  3. git checkout 63483f50 to switch to commit 63483f50, it's about ~7 commits before the latest commit in this branch.
  4. Open nvim and open the file README.md, press <leader>gL to try to open url in browser.

I got an error message:

image

Update-2

Interesting thing is, when I disabled the upstream remote, e.g. .git/config is:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
[remote "origin"]
    url = https://github.com/linrongbin16/awesome-neovim.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
    remote = origin
    merge = refs/heads/main
[branch "linrongbin16-fzfx-nvim"]
    remote = origin
    merge = refs/heads/linrongbin16-fzfx-nvim
; [remote "upstream"]
;   url = https://github.com/rockerBOO/awesome-neovim
;   fetch = +refs/heads/*:refs/remotes/upstream/*

This error just disappears. So this error is just happened when there's multiple remotes, and on older commits.

linrongbin16 commented 6 months ago

hi @hqkhan , the designed behavior (of this plugin) should be:

When there're multiple remotes, this plugin will just pick the first detected remote, unless you use remote=upstream arguments to specify a remote.

For example you can use: :GitLink! blame remote=upstream.


Fixed in #235 . Please pull latest master branch, and have a try!

hqkhan commented 6 months ago

Hi @linrongbin16, thank you for pushing that. It does work with :GitLink remote=origin for me now.

I wanted to understand this a bit better and specifically why having multiple remotes causes this issue on a detached HEAD. When we're on a detached HEAD or not on a branch, we shouldn't care about remotes should we? As you might be able to tell, my knowledge of git is not much lol

The first remote that shows up in the list for me causes an error. Specifying origin as the remote fixes the issue. I was trying to think of a better way to get this to work without having to specify a remote all the time.

This could be a way for me to detect which remote is "important":

 git config remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*

I can add additional code in my router but I was hoping to be able to run :GitLink most of the time unless there's a rare case not to.

linrongbin16 commented 6 months ago

hi @hqkhan ,

Now the designed flow of this plugin is:

  1. Running multiple git shell commands (the logs you see when you're debugging) to get the remote git host (for example: https://github.com/linrongbin16/awesome-neovim.git, this is the output of shell command: git remote get-url origin) and other information (for example commit ID: 63483f501758d9555600d08d0c8be8c5b7c3f21b).
  2. Get the relative file path of current buffer and selected line range. For example: README.md and line number 1.
  3. Found a mapped url constructor by host name (github.com), and make the final url ( for example: https://github.com/linrongbin16/awesome-neovim/blob/63483f501758d9555600d08d0c8be8c5b7c3f21b/README.md?plain=1#L1).
  4. Execute the action: copy to clipboard, or open in browser.

For this issue, the error is when there's multiple remotes, we don't know the commit ID 63483f501758d9555600d08d0c8be8c5b7c3f21b is either in origin (https://github.com/linrongbin16/awesome-neovim) or upstream (https://github.com/rockerBOO/awesome-neovim).

So the designed behavior is: user have to manually specify the remote with GitLink remote=origin.

If there's only 1 remote, then user don't need to specify it.

hqkhan commented 6 months ago

Ah. That makes sense. Ty for the explanation.

For now, I'll just have my default be for origin remote since that's the most common. Should work for 90% of the cases :)