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

Improve stg-rebase completion to list available branches #102

Closed
lthms opened this issue Apr 28, 2021 · 13 comments
Closed

Improve stg-rebase completion to list available branches #102

lthms opened this issue Apr 28, 2021 · 13 comments

Comments

@lthms
Copy link
Contributor

lthms commented Apr 28, 2021

The completion of stg rebase could be improved, notable by listing the branches available for rebasing against. As of now, when I want to use stg rebase, I end up writing git rebase , select the branch thanks to the completion utility of git, then changes git for stg :).

I am not really familiar with zsh completion framework, but I will definitely have a look at some point. In the meantime, opening this issue in case something more fluent than me wants to give it a try.

@jpgrayson
Copy link
Collaborator

It would be straightforward to make the completion options either stgit-enabled branches or all git branches by using either __stg_branch_stgit or __stg_branch_all with the new-base-id argument.

I.e.:

_stg-rebase() {
    __stg_add_args_help
    __stg_add_args_merged
    subcmd_args+=(
        '(-n --nopush)'{-n,--nopush}'[do not push patches after rebasing]'
        ':new-base-id:__stg_branch_stgit'
    )
    _arguments -s -S $subcmd_args
}

But that is much less full-featured than the set of options provided by the zsh completions for git rebase. So the next question is whether we to try to add that level of revision sophistication to StGit?

I personally almost never use stg rebase, so I'm willing to defer to others' opinions on what would constitute a sufficient completion strategy for stg rebase.

@lkraav
Copy link

lkraav commented Apr 30, 2021

I personally almost never use stg rebase

Interesting, why not? I use stg rebase -m consistently to get patches pushed back and cleaned quickly.

@jpgrayson
Copy link
Collaborator

When I pull from a remote repo, I use stg pull -m which has the effect of popping all applied patches, pulling from remote, fast-forward merging new commits from remote, and then reapplying patches until either a merge conflict is encountered or my previous topmost patch is reached. I.e., it's effectively a rebase, but in one step.

I am similarly interested in workflows where stg rebase is useful. Would love to hear about them.

@lkraav
Copy link

lkraav commented Apr 30, 2021

I am similarly interested in workflows where stg rebase is useful. Would love to hear about them.

I sometimes manually verify what I am about to rebase on top of, for example in the case of some more-live-than-your-average-bear app plugin situations, where running head first into a merge conflict that might take a while to look into, might be uncomfortable.

So I git fetch manually, check remote branch contents, then run stg rebase if I'm satisfied with what I see.

@lthms
Copy link
Contributor Author

lthms commented May 3, 2021

@jpgrayson I’ve tried to apply your suggestion, with it works well, and I think the only missing pieces are branches of remotes (e.g., origin/master and so forth). That being said, thanks for suggesting this first step!

Edit: The following change basically gives me what I want:

diff --git a/completion/stgit.zsh b/completion/stgit.zsh
index a36bd06..ee931be 100644
--- a/completion/stgit.zsh
+++ b/completion/stgit.zsh
@@ -388,7 +388,7 @@ _stg-rebase() {
     __stg_add_args_merged
     subcmd_args+=(
         '(-n --nopush)'{-n,--nopush}'[do not push patches after rebasing]'
-        ':new-base-id:'
+        ':new-base-id:__stg_branch_all'
     )
     _arguments -s -S $subcmd_args
 }
@@ -643,7 +643,8 @@ __stg_add_args_sign() {
 __stg_branch_all() {
     declare -a all_branches
     all_branches=(
-        ${${(f)"$(_call_program remote-branch-refs git for-each-ref --format='"%(refname)"' refs/heads 2>/dev/null)"}#refs/heads/}
+        ${${(f)"$(_call_program remote-branch-refs git branch 2>/dev/null | sed -e 's/^. //')"}#refs/heads/}
+        ${${(f)"$(_call_program remote-branch-refs git branch -r 2>/dev/null | sed -e 's/^. //')"}#refs/heads/}
     )
     local expl
     _wanted -V branches expl "branch" compadd $all_branches

Edit: Actually, not exactly, the proposal are poluted with unwanted entries like origin/HEAD\ -\>\ origin/master

@lthms
Copy link
Contributor Author

lthms commented Oct 24, 2022

As far as I can tell, the current stg 2.0 has a regression compared to stg 1.x wrt. stg rebase completion. Am I the only one having the issue? maybe I misinstalled it. @jpgrayson is it working as expected in your setup?

@jpgrayson
Copy link
Collaborator

@jpgrayson is it working as expected in your setup?

Yes? Here is an example of the completions I get:

% stg rebase <TAB>
 -- local head --
consistent-option-passthrough  HEAD                           ORIG_HEAD                    
FETCH_HEAD                     master                                                      
 -- remote head --
jpg/master                                    origin/dependabot/cargo/serde_json-1.0.86   
jpg/rust                                      origin/HEAD                                 
origin/ci-breakage                            origin/master                               
origin/dependabot/cargo/bstr-1.0.0            srht/master                                 
origin/dependabot/cargo/clap-3.2.20           srht/rust                                   
origin/dependabot/cargo/clap-4.0.11

Could you elaborate on the behaviors you are seeing versus what you're expecting, @lthms?

@jpgrayson jpgrayson reopened this Oct 25, 2022
@lthms
Copy link
Contributor Author

lthms commented Oct 25, 2022

stg rebase only gives me file completion. I guess for some reason I am using leftovers completion files? I will try to investigate a bit more. It’s nice to hear that the feature is working as expected, though!

@jpgrayson
Copy link
Collaborator

I'd really like to understand why changing the completions script name had the ostensible effect on your system before we merge #226.

On my system, zsh ships with its own old/defunct StGit completions. Those are installed at:

/usr/share/zsh/functions/Completion/Unix/_stgit

And the completion script that ships with StGit should nominally be installed to:

/usr/share/zsh/site-functions/_stg

or, if doing a manual install:

/usr/local/share/zsh/site-functions/_stg

This works on my system and should work on any system where $fpath is setup correctly, i.e. with /usr/share/zsh/site-functions ahead of /usr/share/zsh/functions/*.

It is more conventional for the completion script to have the same name as the executable it provides completions for (with a leading '_'), so there is nothing about _stgit that would make it superior/preferential to _stg, unless perhaps both scripts are installed in the same directory?

So, some things to check in your environment:

  1. The order of $fpath
  2. All the different places that _stg and/or _stgit may be installed
  3. Whether your zsh startup files (.zshrc, .zshenv, .zprofile, etc.) manipulate $fpath.

@lthms
Copy link
Contributor Author

lthms commented Oct 26, 2022

Actually, make install-completions puts the completion file at ~/.local/share/zsh/site-functions.

Considering $fpath, here the exact value of mine:

/usr/lib/kitty/shell-integration/zsh/completions /home/lthms/.local/share/zsh/site-functions /home/lthms/git/dotfiles/oh-my-zsh/plugins/ssh-agent /home/lthms/git/dotfiles/oh-my-zsh/plugins/gpg-agent /home/lthms/git/dotfiles/oh-my-zsh/plugins/history-substring-search /home/lthms/git/dotfiles/oh-my-zsh/plugins/per-directory-history /home/lthms/git/dotfiles/oh-my-zsh/plugins/git /home/lthms/git/dotfiles/oh-my-zsh/plugins/sudo /home/lthms/git/dotfiles/oh-my-zsh/functions /home/lthms/git/dotfiles/oh-my-zsh/completions /home/lthms/git/dotfiles/oh-my-zsh/cache/completions /usr/local/share/zsh/site-functions /usr/share/zsh/site-functions /usr/share/zsh/functions/Calendar /usr/share/zsh/functions/Chpwd /usr/share/zsh/functions/Completion /usr/share/zsh/functions/Completion/Base /usr/share/zsh/functions/Completion/Linux /usr/share/zsh/functions/Completion/Unix /usr/share/zsh/functions/Completion/X /usr/share/zsh/functions/Completion/Zsh /usr/share/zsh/functions/Exceptions /usr/share/zsh/functions/Math /usr/share/zsh/functions/MIME /usr/share/zsh/functions/Misc /usr/share/zsh/functions/Newuser /usr/share/zsh/functions/Prompts /usr/share/zsh/functions/TCP /usr/share/zsh/functions/VCS_Info /usr/share/zsh/functions/VCS_Info/Backends /usr/share/zsh/functions/Zftp /usr/share/zsh/functions/Zle

It’s manipulated in my .zshrc file as follows:

fpath=("${HOME}/.local/share/zsh/site-functions" ${fpath})

Maybe, contrary to PATH, the correct approach is to append, not prepend, with fpath?

As far as I can tell, there is not _stg{it,} files in other location than the one you mentioned (default, outdated file installed with zsh) and the one that is installed.

Question, out of the blue: does the fact that the function has a different name than the file (the function is _stgit) may be a reason why I see this issue?

@jpgrayson
Copy link
Collaborator

Maybe, contrary to PATH, the correct approach is to append, not prepend, with fpath?

No, prepending is correct. The paths defined first have priority over those defined later, like PATH. Your fpath setup is similar to mine (when installing certain tools from source, I also use ~/.local/).

Question, out of the blue: does the fact that the function has a different name than the file (the function is _stgit) may be a reason why I see this issue?

No, I don't think so. The #compdef stg line at the top tells the zsh completion system the command name(s) to be completed by the completion script. See the "Autoloaded files" section of zshcompsys(1).

One thing that has tripped me up in the past when dealing with zsh completion scripts is the method of starting a new zsh session to account for changed/added/removed completion scripts. The approach of running zsh as a child of a current zsh process is tempting, but didn't always seem to work for me. What I do now when iterating on the StGit zsh completions is to replace the current zsh session/process with a new one, i.e. by running exec zsh.

I wonder if it is possible that your zsh environment was not being reset fully or correctly after the renaming _stg to _stgit? If you fully exit out of all zsh sessions and their parent terminal processes and restart your terminal and zsh, does _stg still no longer work?

@lthms
Copy link
Contributor Author

lthms commented Oct 28, 2022

Though I only reported recently, I’ve had this issue for several weeks (probably since I’ve installed the rust based version of Stacked Git). There have been many full reboots involved. 😅

Not sure what we can do about this. At least I’m glad that I have found a way to have it work! But it may very well be that the issue is totally in my setup, especially since nobody else has complained about a similar problem. Feel free to close my PR if you think it is wiser!

@jpgrayson
Copy link
Collaborator

I am going to close this issue and the PR since I believe this problem to be peculiar to your environment.

One parting thought: is your fpath setup happening before compinit is called? I noticed from the fpath you posted that you're using ohmyzsh. Not sure how that framework ensures fpath modifications are done at the right time.

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

Successfully merging a pull request may close this issue.

3 participants