ohmybash / oh-my-bash

A delightful community-driven framework for managing your bash configuration, and an auto-update tool so that makes it easy to keep up with the latest updates from the community.
https://ohmybash.github.io
MIT License
5.53k stars 624 forks source link

Custom git completion does not work as expected #546

Open atrestis opened 3 months ago

atrestis commented 3 months ago

Tested on Centos 7, git version 2.35.2

Expected:

  1. Load a git.completion.bash file into ~/.ohmybash/custom/completions directory
  2. Make changes (e.g. custom git path binary in local_paths variable)
  3. Source bashrc (which sources oh-my-bash.sh script)
  4. Custom completions for git have been included

Actual:

  1. Custom completions for git have not been included, the completion only works for aliases under ~/.gitconfig configuration file

Workaround:

[bashrc]: source "$OSH/tools/git-completion.bash"

Am I missing something here? Thank you, Atrestis

akinomyoga commented 3 months ago

Do you have git in the array completions defined in ~/.bashrc? The completion module is only loaded when it is registered to the array completions in ~/.bashrc before sourcing oh-my-bash.sh

3. Source bashrc (which sources oh-my-bash.sh script)

Another possibility would be that the git completion is loaded but the actual processing is kipped because a function __gitdir is already defined. Did you source ~/.bashrc in a session where OMB is already loaded? Could you check the behavior when you start a new Bash session?

atrestis commented 3 months ago

Do you have git in the array completions defined in ~/.bashrc? The completion module is only loaded when it is registered to the array completions in ~/.bashrc before sourcing oh-my-bash.sh

Correct, git is in array completions, defined in bashrc.

Another possibility would be that the git completion is loaded but the actual processing is kipped because a function __gitdir is already defined. Did you source ~/.bashrc in a session where OMB is already loaded? Could you check the behavior when you start a new Bash session?

I did check, same behavior, it only loads aliases on ~/.gitconfig, not commonly used commands like status and commit.

akinomyoga commented 3 months ago

Thanks.

What is the result of the following command in the session where the completion settings are not correctly loaded?

$ complete -p git

Also, could you share the content of the custom git completion file (after your modification)?

atrestis commented 3 months ago

What is the result of the following command in the session where the completion settings are not correctly loaded?

$ complete -p git

This is the result. complete -o bashdefault -o default -o nospace -F __git_wrap__git_main git

Also, could you share the content of the custom git completion file (after your modification)?

Sure, this is the content of ~/.ohmybash/custom/completions/git.completion.bash:

#! bash oh-my-bash.module
# bash completion support for Git.
function _omb_completion_git_initialize {
    if ! _omb_util_function_exists __gitdir; then
        local git_paths path
        IFS=$'\n' read -r -d '' -a git_paths <<< "$(type -aP git)"
        # Note: Falling back on /usr (should already be in the array)
        git_paths+=("/nfs/devel/tools/git/2.35.2/bin/git")
        for path in "${git_paths[@]}"; do
            if [[ -L $path ]]; then
                path=$(_omb_util_readlink "$path")
            fi
            # Note: In the case of symbolic link, the true binary name can
            # contain prefix or suffix for architectures and versions.
            path="${path%/*}"
            local files
            local prefix="${path%/bin}" file
            _omb_util_glob_expand files '"$prefix"/share/{bash-completion/completions/git,{,doc/}git-*/contrib/completion/git-completion.bash}'
            for file in "${files[@]}"; do
                if [[ -f $file && -r $file && -s $file ]]; then
                    source "$file"
                    return $?
                fi
            done
        done
        source "$OSH/tools/git-completion.bash"
    fi
}
_omb_completion_git_initialize
unset -f _omb_completion_git_initialize
akinomyoga commented 2 months ago

Sorry for the delay. The completion settings seem to be correctly loaded. Maybe the specific version of the completion in /nfs/devel/tools/git/2.35.2 has an issue. I would like to check in which file the configured completion function is provided. What is the result of the following command?

$ (shopt -s extdebug; declare -F __git_wrap__git_main )

This should show the filename that defined the shell function __git_wrap__git_main.

atrestis commented 2 months ago
$ (shopt -s extdebug; declare -F __git_wrap__git_main )

yields: __git_wrap__git_main 3523 /<my_home_dir>/.oh-my-bash/tools/git-completion.bash

Keep in mind I had to manually add: source "$OSH/tools/git-completion.bash" to my bashrc.

Thanks for the help!

akinomyoga commented 2 months ago

Thanks. What is the result of the same command in a session where the completion doesn't properly work (i.e., the session without the manual source "$OSH/tools/git-completion.bash")?

I'd like the result in a session with the problem since I'm currently asking the question to identify the cause of the problem. You can temporarily comment out the line of the manual source "$OSH/tools/git-completion.bash" in your ~/.bashrc and start the session to see the result. After checking, you can revert the comment out of the line.

atrestis commented 2 months ago

The culprit is the default bash completion: __git_wrap__git_main 2734 /etc/bash_completion.d/git as it seems.

(Ran this in a shell while the manual source was commented out)

atrestis commented 2 months ago

Any idea why this is happening?

akinomyoga commented 2 months ago

Sorry for the delay. I think bash-completion is already loaded when ~/.bashrc is sourced, so __gitdir already exists. In such a case, the test ! _omb_util_function_exists __gitdir at the beginning of the function fails, so the entire processing of the function is not performed.

Is the system git (i.e., /usr/bin/git) in your system older than the one that you are using (i.e., /nfs/devel/tools/git/2.35.2/bin/git)? The completion setting /etc/bash_completion.d/git is supposed to be git-completion.bash of the system git (/usr/bin/git). I guess the completion interface of the old git that /etc/bash_completion/git uses is incompatible with the new git you use, which causes the problem.

As a workaround, I think you can perform unset -f __gitdir to remove the function before source "$OSH"/oh-my-bash.sh.

atrestis commented 2 months ago

Is the system git (i.e., /usr/bin/git) in your system older than the one that you are using (i.e., /nfs/devel/tools/git/2.35.2/bin/git)? The completion setting /etc/bash_completion.d/git is supposed to be git-completion.bash of the system git (/usr/bin/git). I guess the completion interface of the old git that /etc/bash_completion/git uses is incompatible with the new git you use, which causes the problem.

Correct, the /usr/bin/git is older than the /nfs counterpart.

As a workaround, I think you can perform unset -f __gitdir to remove the function before source "$OSH"/oh-my-bash.sh.

I will give it a shot and get back with the test results, thanks once again for your help :)

atrestis commented 2 months ago

Update: Unfortunately, this workaround does not work for me. I think I will keep the manual source source "$OSH/tools/git-completion.bash" for the time being.