diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | Doc/Zsh/contrib.yo | 15 | ||||
-rw-r--r-- | Functions/VCS_Info/Backends/VCS_INFO_detect_p4 | 78 |
3 files changed, 92 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog index 6f225124f..202a2fd7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2008-09-23 Peter Stephenson <pws@csr.com> + * 25732: Functions/VCS_Info/Backends/VCS_INFO_detect_p4, + Doc/Zsh/contrib.yo: make vcs_info detect Perforce from server + if style use-server is set. + * Rocky Bernstein: 25727: Src/hist.c, Test/B06fc.ztst: remove restriction on interactive use of fc and test another problem. diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo index a3a74134e..44b918aac 100644 --- a/Doc/Zsh/contrib.yo +++ b/Doc/Zsh/contrib.yo @@ -502,6 +502,21 @@ A list of VCSs, you don't want var(vcs_info) to test for repositories (checked in the var(-init-) context, too). Only used if tt(enable) contains tt(ALL). ) +kindex(use-server) +item(tt(use-server))( +This is used by the Perforce backend (tt(p4)) to decide if it should +contact the Perforce server to find out if a directory is managed +by Perforce. This is the only reliable way of doing this, but runs +the risk of a delay if the server name cannot be found. If the +server (more specifically, the var(host)tt(:)var(port) pair describing the +server) cannot be contacted its name is put into the associative array +tt(vcs_info_p4_dead_servers) and not contacted again during the session +until it is removed by hand. If you do not set this style, the tt(p4) +backend is only usable if you have set the environment variable +tt(P4CONFIG) to a file name and have corresponding files in the root +directories of each Perforce client. See comments in the function +tt(VCS_INFO_detect_p4) for more detail. +) kindex(use-simple) item(tt(use-simple))( If there are two different ways of gathering diff --git a/Functions/VCS_Info/Backends/VCS_INFO_detect_p4 b/Functions/VCS_Info/Backends/VCS_INFO_detect_p4 index 3cd649a0d..d9475fa01 100644 --- a/Functions/VCS_Info/Backends/VCS_INFO_detect_p4 +++ b/Functions/VCS_Info/Backends/VCS_INFO_detect_p4 @@ -2,8 +2,76 @@ ## perforce support by: Phil Pennock ## Distributed under the same BSD-ish license as zsh itself. -[[ -n ${P4CONFIG} ]] || return 1 -VCS_INFO_check_com p4 || return 1 -vcs_comm[detect_need_file]="${P4CONFIG}" -VCS_INFO_bydir_detect . -return $? +# If user-server is true in the :vcs_info:p4:... context, contact the +# server to decide whether the directory is handled by Perforce. This can +# cause a delay if the network times out, in particular if looking up the +# server name failed. Hence this is not the default. If a timeout +# occurred, the server:port pair is added to the associative array +# vcs_info_p4_dead_servers and the server is never contacted again. The +# array must be edited by hand to remove it. +# +# If user-server is false or not set, the function looks to see if there is +# a file $P4CONFIG somewhere above in the hierarchy. This is far from +# foolproof; in fact it relies on you using the particular working practice +# of having such files in all client root directories and nowhere above. + + +VCS_INFO_p4_get_server() { + emulate -L zsh + setopt extendedglob + + local -a settings + settings=(${(f)"$(p4 set)"}) + serverport=${${settings[(r)P4PORT=*]##P4PORT=}%% *} + case $serverport in + (''|:) + serverport=perforce:1666 + ;; + + (:*) + serverport=perforce${serverport} + ;; + + (*:) + serverport=${serverport}1666 + ;; + + (<->) + serverport=perforce:${serverport} + ;; + esac +} + + +VCS_INFO_detect_p4() { + local serverport p4where + + if zstyle -t ":vcs_info:p4:${usercontext}:${rrn}" use-server; then + # Use "p4 where" to decide whether the path is under the + # client workspace. + if (( ${#vcs_info_p4_dead_servers} )); then + # See if the server is in the list of defunct servers + VCS_INFO_p4_get_server + [[ -n $vcs_info_p4_dead_servers[$serverport] ]] && return 1 + fi + if p4where="$(p4 where 2>&1)"; then + return 0 + fi + if [[ $p4where = *"Connect to server failed"* ]]; then + # If the connection failed, mark the server as defunct. + # Otherwise it worked but we weren't within a client. + typeset -gA vcs_info_p4_dead_servers + [[ -z $serverport ]] && VCS_INFO_p4_get_server + vcs_info_p4_dead_servers[$serverport]=1 + fi + return 1 + else + [[ -n ${P4CONFIG} ]] || return 1 + VCS_INFO_check_com p4 || return 1 + vcs_comm[detect_need_file]="${P4CONFIG}" + VCS_INFO_bydir_detect . + return $? + fi +} + +VCS_INFO_detect_p4 "$@" |