git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 12/10] Teach bash about git-repo-config.
@ 2006-11-27  9:44 Shawn O. Pearce
  2006-11-28  1:17 ` Junio C Hamano
  0 siblings, 1 reply; 3+ messages in thread
From: Shawn O. Pearce @ 2006-11-27  9:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

This is a really ugly completion script for git-repo-config, but it has
some nice properties.  I've added all of the documented configuration
parameters from Documentation/config.txt to the script, allowing the
user to complete any standard configuration parameter name.

We also have some intelligence for the remote.*.* and branch.*.* keys
by completing not only the key name (e.g. remote.origin) but also the
values (e.g. remote.*.fetch completes to the branches available on the
corresponding remote).

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 Yes, that's it.  I'm finally done tinkering with bash
 completion support for this week.  Total of 12 patches.
 Sorry about the numbering Junio; when I sent the first 10
 I thought I was going to bed, but then decided to stay
 up and hack a bit more...

 I know Linus would like to see the space thing corrected.
 I'll try to look at it next week if nobody beats me to it.

 contrib/completion/git-completion.bash |  154 ++++++++++++++++++++++++++++++++
 1 files changed, 154 insertions(+), 0 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 47b393d..a957165 100755
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -43,6 +43,27 @@ __git_ps1 ()
 	fi
 }
 
+__git_heads ()
+{
+	local cmd i is_hash=y dir="${1:-$(__gitdir)}"
+	if [ -d "$dir" ]; then
+		for i in $(git --git-dir="$dir" \
+			for-each-ref --format='%(refname)' \
+			refs/heads ); do
+			echo "${i#refs/heads/}"
+		done
+		return
+	fi
+	for i in $(git-ls-remote "$dir" 2>/dev/null); do
+		case "$is_hash,$i" in
+		y,*) is_hash=n ;;
+		n,*^{}) is_hash=y ;;
+		n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
+		n,*) is_hash=y; echo "$i" ;;
+		esac
+	done
+}
+
 __git_refs ()
 {
 	local cmd i is_hash=y dir="${1:-$(__gitdir)}"
@@ -91,6 +112,23 @@ __git_refs2 ()
 	done
 }
 
+__git_refs_remotes ()
+{
+	local cmd i is_hash=y
+	for i in $(git-ls-remote "$1" 2>/dev/null); do
+		case "$is_hash,$i" in
+		n,refs/heads/*)
+			is_hash=y
+			echo "$i:refs/remotes/$1/${i#refs/heads/}"
+			;;
+		y,*) is_hash=n ;;
+		n,*^{}) is_hash=y ;;
+		n,refs/tags/*) is_hash=y;;
+		n,*) is_hash=y; ;;
+		esac
+	done
+}
+
 __git_remotes ()
 {
 	local i ngoff IFS=$'\n' d="$(__gitdir)"
@@ -520,6 +558,119 @@ _git_rebase ()
 	COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
 }
 
+_git_repo_config ()
+{
+	local cur="${COMP_WORDS[COMP_CWORD]}"
+	local prv="${COMP_WORDS[COMP_CWORD-1]}"
+	case "$prv" in
+	branch.*.remote)
+		COMPREPLY=($(compgen -W "$(__git_remotes)" -- "$cur"))
+		return
+		;;
+	branch.*.merge)
+		COMPREPLY=($(compgen -W "$(__git_refs)" -- "$cur"))
+		return
+		;;
+	remote.*.fetch)
+		local remote="${prv#remote.}"
+		remote="${remote%.fetch}"
+		COMPREPLY=($(compgen -W "$(__git_refs_remotes "$remote")" \
+			-- "$cur"))
+		return
+		;;
+	remote.*.push)
+		local remote="${prv#remote.}"
+		remote="${remote%.push}"
+		COMPREPLY=($(compgen -W "$(git --git-dir="$(__gitdir)" \
+			for-each-ref --format='%(refname):%(refname)' \
+			refs/heads)" -- "$cur"))
+		return
+		;;
+	*.*)
+		COMPREPLY=()
+		return
+		;;
+	esac
+	case "$cur" in
+	--*)
+		COMPREPLY=($(compgen -W "
+			--global --list --replace-all
+			--get --get-all --get-regexp
+			--unset --unset-all
+			" -- "$cur"))
+		return
+		;;
+	branch.*.*)
+		local pfx="${cur%.*}."
+		cur="${cur##*.}"
+		COMPREPLY=($(compgen -P "$pfx" -W "remote merge" -- "$cur"))
+		return
+		;;
+	branch.*)
+		local pfx="${cur%.*}."
+		cur="${cur#*.}"
+		COMPREPLY=($(compgen -P "$pfx" -S . \
+			-W "$(__git_heads)" -- "$cur"))
+		return
+		;;
+	remote.*.*)
+		local pfx="${cur%.*}."
+		cur="${cur##*.}"
+		COMPREPLY=($(compgen -P "$pfx" -W "url fetch push" -- "$cur"))
+		return
+		;;
+	remote.*)
+		local pfx="${cur%.*}."
+		cur="${cur#*.}"
+		COMPREPLY=($(compgen -P "$pfx" -S . \
+			-W "$(__git_remotes)" -- "$cur"))
+		return
+		;;
+	esac
+	COMPREPLY=($(compgen -W "
+		apply.whitespace
+		core.fileMode
+		core.gitProxy
+		core.ignoreStat
+		core.preferSymlinkRefs
+		core.logAllRefUpdates
+		core.repositoryFormatVersion
+		core.sharedRepository
+		core.warnAmbiguousRefs
+		core.compression
+		core.legacyHeaders
+		i18n.commitEncoding
+		diff.color
+		diff.renameLimit
+		diff.renames
+		pager.color
+		status.color
+		log.showroot
+		show.difftree
+		showbranch.default
+		whatchanged.difftree
+		http.sslVerify
+		http.sslCert
+		http.sslKey
+		http.sslCAInfo
+		http.sslCAPath
+		http.maxRequests
+		http.lowSpeedLimit http.lowSpeedTime
+		http.noEPSV
+		pack.window
+		repack.useDeltaBaseOffset
+		pull.octopus pull.twohead
+		merge.summary
+		receive.unpackLimit
+		receive.denyNonFastForwards
+		user.name user.email
+		tar.umask
+		gitcvs.enabled
+		gitcvs.logfile
+		branch. remote.
+	" -- "$cur"))
+}
+
 _git_reset ()
 {
 	local cur="${COMP_WORDS[COMP_CWORD]}"
@@ -572,6 +723,7 @@ _git ()
 	pull)        _git_pull ;;
 	push)        _git_push ;;
 	rebase)      _git_rebase ;;
+	repo-config) _git_repo_config ;;
 	reset)       _git_reset ;;
 	show)        _git_log ;;
 	show-branch) _git_log ;;
@@ -605,6 +757,7 @@ complete -o default            -F _git_name_rev git-name-rev
 complete -o default -o nospace -F _git_pull git-pull
 complete -o default -o nospace -F _git_push git-push
 complete -o default            -F _git_rebase git-rebase
+complete -o default            -F _git_repo_config git-repo-config
 complete -o default            -F _git_reset git-reset
 complete -o default            -F _git_log git-show
 complete -o default -o nospace -F _git_log git-show-branch
@@ -626,6 +779,7 @@ complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe
 complete -o default            -F _git_merge_base git-merge-base.exe
 complete -o default            -F _git_name_rev git-name-rev.exe
 complete -o default -o nospace -F _git_push git-push.exe
+complete -o default            -F _git_repo_config git-repo-config
 complete -o default -o nospace -F _git_log git-show.exe
 complete -o default -o nospace -F _git_log git-show-branch.exe
 complete -o default -o nospace -F _git_log git-whatchanged.exe
-- 

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 12/10] Teach bash about git-repo-config.
  2006-11-27  9:44 [PATCH 12/10] Teach bash about git-repo-config Shawn O. Pearce
@ 2006-11-28  1:17 ` Junio C Hamano
  2006-11-28  7:53   ` Shawn Pearce
  0 siblings, 1 reply; 3+ messages in thread
From: Junio C Hamano @ 2006-11-28  1:17 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git

"Shawn O. Pearce" <spearce@spearce.org> writes:

>  Yes, that's it.  I'm finally done tinkering with bash
>  completion support for this week.  Total of 12 patches.

Thanks.  I saw a funky behaviour when I tried this:

	$ git pull . ap<TAB>

==>
	$ git pull . apfatal: Not a git repository: '.'


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 12/10] Teach bash about git-repo-config.
  2006-11-28  1:17 ` Junio C Hamano
@ 2006-11-28  7:53   ` Shawn Pearce
  0 siblings, 0 replies; 3+ messages in thread
From: Shawn Pearce @ 2006-11-28  7:53 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Junio C Hamano <junkio@cox.net> wrote:
> "Shawn O. Pearce" <spearce@spearce.org> writes:
> 
> >  Yes, that's it.  I'm finally done tinkering with bash
> >  completion support for this week.  Total of 12 patches.
> 
> Thanks.  I saw a funky behaviour when I tried this:
> 
> 	$ git pull . ap<TAB>
> 
> ==>
> 	$ git pull . apfatal: Not a git repository: '.'

Doh.  Its the commit titled "Support bash completion of refs/remote".
The problem is I'm invoking git-for-each-ref wrong:

	git --git-dir=. for-each-ref ...

Clearly "." isn't a git directory.  But ./.git is.  The breakage is
the switch from git-peek-remote to git-for-each-ref.  git-peek-remote
nicely realized that "." wasn't a git directory but "./.git" was
and went into ./.git to get the refs.  I switched to for-each-ref
to get a potential speed boost (no need to dereference tags) but
broke the damn thing in the process.

I thought I had tested this for-each-ref change out.  Apparently I
missed a case.

I'll fix it tomorrow.

-- 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-11-28  7:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-11-27  9:44 [PATCH 12/10] Teach bash about git-repo-config Shawn O. Pearce
2006-11-28  1:17 ` Junio C Hamano
2006-11-28  7:53   ` Shawn Pearce

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).