about summary refs log tree commit diff
path: root/Functions/VCS_Info
diff options
context:
space:
mode:
Diffstat (limited to 'Functions/VCS_Info')
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_git64
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_hg57
-rw-r--r--Functions/VCS_Info/VCS_INFO_hexdump16
-rw-r--r--Functions/VCS_Info/VCS_INFO_patch2subject67
-rw-r--r--Functions/VCS_Info/VCS_INFO_quilt64
-rw-r--r--Functions/VCS_Info/VCS_INFO_set-patch-format79
-rw-r--r--Functions/VCS_Info/vcs_info3
7 files changed, 222 insertions, 128 deletions
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
index 472c10d5d..f3dd95dcb 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
@@ -120,41 +120,15 @@ VCS_INFO_git_getbranch () {
 }
 
 VCS_INFO_git_handle_patches () {
-    local git_applied_s git_unapplied_s gitmsg git_all
+    local git_applied_s git_unapplied_s gitmsg
     git_patches_applied=(${(Oa)git_patches_applied})
     git_patches_unapplied=(${(Oa)git_patches_unapplied})
-    (( git_all = ${#git_patches_applied} + ${#git_patches_unapplied} ))
 
-    if VCS_INFO_hook 'gen-applied-string' "${git_patches_applied[@]}"; then
-        if (( ${#git_patches_applied} )); then
-            git_applied_s=${git_patches_applied[1]}
-        else
-            git_applied_s=""
-        fi
-    else
-        git_applied_s=${hook_com[applied-string]}
-    fi
-    hook_com=()
-    if VCS_INFO_hook 'gen-unapplied-string' "${git_patches_unapplied[@]}"; then
-        git_patches_unapplied=${#git_patches_unapplied}
-    else
-        git_patches_unapplied=${hook_com[unapplied-string]}
-    fi
-
-    if (( ${#git_patches_applied} )); then
-        zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" patch-format gitmsg || gitmsg="%p (%n applied)"
-    else
-        zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" nopatch-format gitmsg || gitmsg="no patch applied"
-    fi
-    hook_com=( applied "${git_applied_s}"     unapplied "${git_patches_unapplied}"
-               applied-n ${#git_patches_applied} unapplied-n ${#git_patches_unapplied} all-n ${git_all} )
-    if VCS_INFO_hook 'set-patch-format' "${gitmsg}"; then
-        zformat -f gitmisc "${gitmsg}" "p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \
-                                          "n:${#git_patches_applied}" "c:${#git_patches_unapplied}" "a:${git_all}"
-    else
-        gitmisc=${hook_com[patch-replace]}
-    fi
-    hook_com=()
+    VCS_INFO_set-patch-format 'git_patches_applied' 'git_applied_s' \
+                              'git_patches_unapplied' 'git_unapplied_s' \
+                              ":vcs_info:${vcs}:${usercontext}:${rrn}" gitmsg \
+                              '' ''
+    gitmisc=$REPLY
 }
 
 gitdir=${vcs_comm[gitdir]}
@@ -182,7 +156,7 @@ if (( querystaged || queryunstaged )) && \
    [[ "$(${vcs_comm[cmd]} rev-parse --is-inside-work-tree 2> /dev/null)" == 'true' ]] ; then
     # Default: off - these are potentially expensive on big repositories
     if (( queryunstaged )) ; then
-        ${vcs_comm[cmd]} diff --no-ext-diff --ignore-submodules=dirty --quiet --exit-code ||
+        ${vcs_comm[cmd]} diff --no-ext-diff --ignore-submodules=dirty --quiet --exit-code 2> /dev/null ||
             gitunstaged=1
     fi
     if (( querystaged )) ; then
@@ -205,6 +179,7 @@ local patchdir=${gitdir}/patches/${gitbranch}
 if [[ -d $patchdir ]] && [[ -f $patchdir/applied ]] \
    && [[ -f $patchdir/unapplied ]]
 then
+    # stgit
     git_patches_applied=(${(f)"$(< "${patchdir}/applied")"})
     git_patches_unapplied=(${(f)"$(< "${patchdir}/unapplied")"})
     VCS_INFO_git_handle_patches
@@ -213,11 +188,15 @@ elif [[ -d "${gitdir}/rebase-merge" ]]; then
     local p
     [[ -f "${patchdir}/done" ]] &&
     for p in ${(f)"$(< "${patchdir}/done")"}; do
-        # remove action
-        git_patches_applied+=("${${(s: :)p}[2,-1]}")
+        # pick/edit/fixup/squash/reword: Add "$hash $subject" to $git_patches_applied.
+        # exec: Add "exec ${command}" to $git_patches_applied.
+        # (anything else): As 'exec'.
+        p=${p/(#s)(p|pick|e|edit|r|reword|f|fixup|s|squash) /}
+        p=${p/(#s)x /exec }
+        git_patches_applied+=("$p")
     done
     if [[ -f "${patchdir}/git-rebase-todo" ]] ; then
-        git_patches_unapplied=(${(f)"$(grep -v '^$' "${patchdir}/git-rebase-todo" | grep -v '^#')"})
+        git_patches_unapplied=( ${${(f)${"$(<"${patchdir}/git-rebase-todo")"}}:#[#]*} )
     fi
     VCS_INFO_git_handle_patches
 elif [[ -d "${gitdir}/rebase-apply" ]]; then
@@ -228,10 +207,19 @@ elif [[ -d "${gitdir}/rebase-apply" ]]; then
         local cur=$(< $next)
         local p subject
         for ((p = 1; p < cur; p++)); do
-            git_patches_applied+=("$(printf "%04d" $p) ?")
+            printf -v "git_patches_applied[$p]"  "%04d ?" "$p"
         done
         if [[ -f "${patchdir}/msg-clean" ]]; then
             subject="${$(< "${patchdir}/msg-clean")[(f)1]}"
+        elif local this_patch_file
+             printf -v this_patch_file "%s/%04d" "${patchdir}" "${cur}"
+             [[ -f $this_patch_file ]]
+        then
+            () {
+              local REPLY
+              VCS_INFO_patch2subject "${this_patch_file}"
+              subject=$REPLY
+            }
         fi
         if [[ -f "${patchdir}/original-commit" ]]; then
             if [[ -n $subject ]]; then
@@ -257,6 +245,7 @@ elif [[ -f "${gitdir}/MERGE_HEAD" ]]; then
     # This is 'git merge --no-commit'
     local -a heads=( ${(@f)"$(<"${gitdir}/MERGE_HEAD")"} )
     local subject;
+    # TODO: maybe read up to the first blank line
     IFS='' read -r subject < "${gitdir}/MERGE_MSG"
     # $subject is the subject line of the would-be commit
     # Maybe we can get the subject lines of MERGE_HEAD's commits cheaply?
@@ -282,6 +271,7 @@ elif [[ -f "${gitdir}/CHERRY_PICK_HEAD" ]]; then
     # ### be "1".  The %u/%c tuple will assume the values [(1,2), (1,1), (1,0)],
     # ### whereas the correct sequence would be [(1,2), (2,1), (3,0)].
     local subject
+    # TODO: maybe read up to the first blank line
     IFS='' read -r subject < "${gitdir}/MERGE_MSG"
     git_patches_applied=( "$(<${gitdir}/CHERRY_PICK_HEAD) ${subject}" )
     if [[ -f "${gitdir}/sequencer/todo" ]]; then
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg b/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
index f35ad5965..d4030125c 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_hg
@@ -13,7 +13,7 @@ local hgbase bmfile branchfile rebasefile dirstatefile mqseriesfile \
     hgbmstring hgmqstring applied_string unapplied_string guards_string
 
 local -a hgid_args defrevformat defbranchformat \
-    hgbmarks mqpatches mqseries mqguards mqunapplied hgmisc \
+    hgbmarks mqpatches mqguards mqunapplied hgmisc \
     i_patchguards i_negguards i_posguards
 
 local -A hook_com
@@ -40,9 +40,10 @@ VCS_INFO_adjust
 # Disabled by default anyway, so no harm done.
 if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" get-revision ; then
     if zstyle -t ":vcs_info:${vcs}:${usercontext}:${rrn}" use-simple \
-            && ( VCS_INFO_check_com hexdump ) && [[ -r ${dirstatefile} ]] ; then
-        # Calling hexdump is (much) faster than hg but doesn't get the local rev
-        r_csetid=$(hexdump -n 20 -e '1/1 "%02x"' ${dirstatefile})
+            && VCS_INFO_hexdump ${dirstatefile} 20 ; then
+        # Calling VCS_INFO_hexdump is (much) faster than hg but doesn't get
+        # the local rev
+        r_csetid=$REPLY
     else
         # Settling for a short (but unique!) hash because getting the full
         # 40-char hash in addition to all the other info we want isn't
@@ -174,9 +175,6 @@ if zstyle -T ":vcs_info:${vcs}:${usercontext}:${rrn}" get-mq \
             # Skip commented lines
             [[ ${i_patch} == [[:space:]]#"#"* ]] && continue
 
-            # Keep list of all patches
-            mqseries+=( $i_patch )
-
             # Separate negative and positive guards to more easily find the
             # intersection of active guards with patch guards
             i_patchguards=( ${(s: :)i_patchguards} )
@@ -202,50 +200,21 @@ if zstyle -T ":vcs_info:${vcs}:${usercontext}:${rrn}" get-mq \
         done < ${mqseriesfile}
     fi
 
-    if VCS_INFO_hook 'gen-applied-string' "${mqpatches[@]}"; then
-        (( ${#mqpatches} )) && applied_string=${mqpatches[1]}
-    else
-        applied_string=${hook_com[applied-string]}
-    fi
-
-    hook_com=()
-
-    if VCS_INFO_hook 'gen-unapplied-string' "${mqunapplied[@]}"; then
-        unapplied_string=${#mqunapplied}
-    else
-        unapplied_string=${hook_com[unapplied-string]}
-    fi
-
-    hook_com=()
-
     if VCS_INFO_hook 'gen-mqguards-string' "${mqguards[@]}"; then
         guards_string=${(j:,:)mqguards}
+        # TODO: %-escape extra_zformats[g:...] value
     else
         guards_string=${hook_com[guards-string]}
     fi
 
-    if (( ${#mqpatches} )); then
-        zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" patch-format \
-            hgmqstring || hgmqstring="%p (%n applied)"
-    else
-        zstyle -s ":vcs_info:${vcs}:${usercontext}:${rrn}" nopatch-format \
-            hgmqstring || hgmqstring="no patch applied"
-    fi
-
-    hook_com=( applied "${applied_string}" unapplied "${unapplied_string}"
-               applied-n ${#mqpatches}     unapplied-n ${#mqunapplied}     all-n ${#mqseries}
-               guards "${guards_string}"   guards-n ${#mqguards} )
+    local -A extra_hook_com=( guards "${guards_string}"   guards-n ${#mqguards} )
+    local -a extra_zformats=( "g:${extra_hook_com[guards]}" "G:${#mqguards}" )
 
-    if VCS_INFO_hook 'set-patch-format' ${qstring}; then
-        zformat -f hgmqstring "${hgmqstring}" \
-            "p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \
-            "n:${#mqpatches}" "c:${#mqunapplied}" "a:${#mqseries}" \
-            "g:${hook_com[guards]}" "G:${#mqguards}"
-    else
-        hgmqstring=${hook_com[patch-replace]}
-    fi
-
-    hook_com=()
+    VCS_INFO_set-patch-format 'mqpatches' 'applied_string' \
+                              'mqunapplied' 'unapplied_string' \
+                              ":vcs_info:${vcs}:${usercontext}:${rrn}" hgmqstring \
+                              extra_hook_com extra_zformats
+    hgmqstring=$REPLY
 fi
 
 
diff --git a/Functions/VCS_Info/VCS_INFO_hexdump b/Functions/VCS_Info/VCS_INFO_hexdump
new file mode 100644
index 000000000..11f1c1a50
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_hexdump
@@ -0,0 +1,16 @@
+## vim:ft=zsh
+
+# VCS_INFO_hexdump FILENAME BYTECOUNT
+#
+# Return in $REPLY a hexadecimal representation (lowercase, no whitespace)
+# of the first BYTECOUNT bytes of FILENAME.
+
+if [[ -r $1 ]]; then
+  setopt localoptions nomultibyte extendedglob
+  local val
+  read -k $2 -u 0 val <$1
+  REPLY=${(Lj::)${(l:2::0:)${(@s//)val}//(#m)*/$(( [##16] ##$MATCH ))}}
+else
+  return 1
+fi
+
diff --git a/Functions/VCS_Info/VCS_INFO_patch2subject b/Functions/VCS_Info/VCS_INFO_patch2subject
new file mode 100644
index 000000000..e222e8382
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_patch2subject
@@ -0,0 +1,67 @@
+# This function takes as an argument a filename of a patch and sets $REPLY to
+# a single-line "subject", or unsets it if no subject could be extracted.
+{
+    setopt localoptions extendedglob
+    integer i
+    integer -r LIMIT=10
+    local -a lines
+    local needle
+    if [[ -f "$1" ]]; then
+        # Extract the first LIMIT lines, or up to the first empty line or the start of the unidiffs,
+        # whichever comes first.
+        while (( i++ < LIMIT )); do
+            IFS= read -r "lines[$i]"
+            if [[ -z ${lines[$i]} ]] || [[ ${lines[$i]} == (#b)(---|Index:)* ]]; then
+                lines[$i]=()
+                break
+            fi
+        done < "$1"
+        
+        if needle=${lines[(i)Subject:*]}; (( needle <= $#lines )); then
+            # "Subject: foo" line, plus rfc822 whitespace unfolding.
+            #
+            # Example: 'git format-patch' patches.
+            REPLY=${lines[needle]}
+            REPLY=${REPLY#*: }
+            REPLY=${REPLY#\[PATCH\] }
+            while [[ ${${lines[++needle]}[1]} == ' ' ]]; do
+                REPLY+=${lines[needle]}
+            done
+        elif needle=${lines[(r)Description:*]}; [[ -n $needle ]]; then
+            # "Description: foo" line.
+            #
+            # Example: DEP-3 patches.
+            REPLY=${needle#*: }
+        elif [[ ${lines[1]} == '# HG changeset patch' ]] && { needle=${${lines:#([#]*)}[1]}; [[ -n $needle ]] }; then
+            # Mercurial patch
+            REPLY=$needle
+        elif [[ ${lines[1]} == "commit "[0-9a-f](#c40) ]] &&
+             [[ ${lines[2]} == "Author:"* && ${lines[3]} == "Date:"* ]] &&
+             (( ! ${+lines[4]} )); then
+            # `git show` output.
+            #
+            # The log message is after the first blank line, so open() the file
+            # again.  Also check whether the following line (second line of the
+            # log message itself) is empty.
+            {
+              repeat 4 { IFS= read -r }
+              IFS= read -r needle; needle=${needle#'    '}
+              if IFS= read -r; REPLY=${REPLY#'    '}; [[ -n $REPLY ]]; then
+                needle+='...'
+              fi
+            } < "$1"
+            REPLY=$needle
+        elif (( ${+lines[1]} )); then
+            # The first line of the file is not part of the diff.
+            REPLY=${lines[1]}
+        else
+            # The patch has no subject.
+            unset REPLY
+            return 0
+        fi
+    else
+        # The patch cannot be examined, or invalid arguments.
+        unset REPLY
+        return 1
+    fi
+}
diff --git a/Functions/VCS_Info/VCS_INFO_quilt b/Functions/VCS_Info/VCS_INFO_quilt
index c3c3d864d..381b58489 100644
--- a/Functions/VCS_Info/VCS_INFO_quilt
+++ b/Functions/VCS_Info/VCS_INFO_quilt
@@ -80,6 +80,10 @@ function VCS_INFO_quilt-dirfind() {
     return ${ret}
 }
 
+function VCS_INFO_quilt-patch2subject() {
+    VCS_INFO_patch2subject "$@"
+}
+
 function VCS_INFO_quilt() {
     emulate -L zsh
     setopt extendedglob
@@ -87,7 +91,7 @@ function VCS_INFO_quilt() {
     local patches pc tmp qstring root
     local -i ret
     local context
-    local -a applied unapplied all applied_string unapplied_string quiltcommand quilt_env
+    local -a applied unapplied applied_string unapplied_string quiltcommand quilt_env
     local -A hook_com
 
     context=":vcs_info:${vcs}.quilt-${mode}:${usercontext}:${rrn}"
@@ -119,7 +123,7 @@ function VCS_INFO_quilt() {
             applied=()
         fi
         patches=$(<$pc/.quilt_patches)
-        patches=`builtin cd -q "${pc:h}" && print -r - ${patches:A}`
+        patches=`builtin cd -q "${pc:h}" && print -r - ${patches:P}`
     fi
     if zstyle -t "${context}" get-unapplied; then
         # This zstyle call needs to be moved further up if `quilt' needs
@@ -147,27 +151,19 @@ function VCS_INFO_quilt() {
 
     if [[ -n $patches ]]; then
       () {
-        local i line
+        local i
         for ((i=1; i<=$#applied; i++)); do
-          if [[ -f "$patches/$applied[$i]" ]] &&
-             read -r line < "$patches/$applied[$i]" &&
-             [[ $line != (#b)(---|Index:)* ]] &&
-             true
-            ;
+          if VCS_INFO_quilt-patch2subject "$patches/$applied[$i]" && (( $+REPLY ))
           then
-            applied[$i]+=" $line"
+            applied[$i]+=" $REPLY"
           else
             applied[$i]+=" ?"
           fi
         done
         for ((i=1; i<=$#unapplied; i++)); do
-          if [[ -f "$patches/$unapplied[$i]" ]] &&
-             read -r line < "$patches/$unapplied[$i]" &&
-             [[ $line != (#b)(---|Index:)* ]] &&
-             true
-            ;
+          if VCS_INFO_quilt-patch2subject "$patches/$unapplied[$i]" && (( $+REPLY ))
           then
-            unapplied[$i]+=" $line"
+            unapplied[$i]+=" $REPLY"
           else
             unapplied[$i]+=" ?"
           fi
@@ -175,41 +171,15 @@ function VCS_INFO_quilt() {
       }
     fi
 
-    all=( ${(Oa)applied} ${unapplied} )
-
-    if VCS_INFO_hook 'gen-applied-string' "${applied[@]}"; then
-        if (( ${#applied} )); then
-            applied_string=${applied[1]}
-        else
-            applied_string=""
-        fi
-    else
-        applied_string=${hook_com[applied-string]}
-    fi
-    hook_com=()
-    if VCS_INFO_hook 'gen-unapplied-string' "${unapplied[@]}"; then
-        unapplied_string="${#unapplied}"
-    else
-        unapplied_string=${hook_com[unapplied-string]}
-    fi
-
-    if (( ${#applied} )); then
-        zstyle -s "${context}" patch-format qstring || qstring="%p (%n applied)"
-    else
-        zstyle -s "${context}" nopatch-format qstring || qstring="no patch applied"
-    fi
-    hook_com=( applied "${applied_string}" unapplied "${unapplied_string}"
-               applied-n ${#applied}       unapplied-n ${#unapplied}       all-n ${#all} )
-    if VCS_INFO_hook 'set-patch-format' ${qstring}; then
-        zformat -f qstring "${qstring}" "p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \
-                                        "n:${#applied}" "c:${#unapplied}" "a:${#all}"
-    else
-        qstring=${hook_com[patch-replace]}
-    fi
-    hook_com=()
+    VCS_INFO_set-patch-format 'applied' 'applied_string' \
+                              'unapplied' 'unapplied_string' \
+                              ${context} qstring \
+                              '' ''
+    qstring=$REPLY
 
     case ${mode} in
     (standalone)
+        backend_misc[patches]=${qstring}
         VCS_INFO_formats '' '' "${root}" '' '' '' "${qstring}"
         VCS_INFO_set
         ;;
diff --git a/Functions/VCS_Info/VCS_INFO_set-patch-format b/Functions/VCS_Info/VCS_INFO_set-patch-format
new file mode 100644
index 000000000..cdf2d303e
--- /dev/null
+++ b/Functions/VCS_Info/VCS_INFO_set-patch-format
@@ -0,0 +1,79 @@
+# This function is the common guts of the gen-applied-string /
+# gen-unapplied-string / set-patch-format dance of several backends.
+#
+# Parameters:
+# $1 - name of an array parameter to be the argument to gen-applied-string
+# $2 - name of a parameter to store the applied-string in
+# $3 - name of an array parameter to be the argument to gen-unapplied-string
+# $4 - name of a parameter to store the unapplied-string in
+# $5 - context argument for use in zstyle getters
+# $6 - name of a parameter to store a patch-format format string in
+# $7 - name of an assoc parameter with extra $hook_com key-value pairs for the
+#      set-patch-format hook invocation, or '' for none
+# $8 - name of an array parameter with extra arguments for the patch-format zformat call, or '' for empty
+#
+# The expanded patch-format string is returned in $REPLY.
+#
+# Output:
+# - $hook_com is overwritten and the keys 'applied', 'applied-n',
+#   'unapplied', 'unapplied-n', 'all-n' are set.
+{
+    local applied_needs_escaping='unknown'
+    local unapplied_needs_escaping='unknown'
+    if VCS_INFO_hook 'gen-applied-string' "${(@P)1}"; then
+        if (( ${(P)#1} )); then
+            REPLY=${(P)1[1]}
+        else
+            REPLY=""
+        fi
+        applied_needs_escaping='yes'
+    else
+        REPLY=${hook_com[applied-string]}
+    fi
+    : ${(P)2::=$REPLY}
+    hook_com=()
+
+    if VCS_INFO_hook 'gen-unapplied-string' "${(@P)3}"; then
+        REPLY=${(P)#3}
+        unapplied_needs_escaping='yes'
+    else
+        REPLY=${hook_com[unapplied-string]}
+    fi
+    : ${(P)4::=$REPLY}
+    hook_com=()
+
+    if (( ${(P)#1} )); then
+        zstyle -s "${5}" patch-format REPLY || REPLY="%p (%n applied)"
+    else
+        zstyle -s "${5}" nopatch-format REPLY || REPLY="no patch applied"
+    fi
+    : ${(P)6::=$REPLY}
+
+    hook_com=(
+      applied-n ${(P)#1}
+      applied "${(P)2}"
+      unapplied-n ${(P)#3}
+      unapplied "${(P)4}"
+    )
+    hook_com[all-n]=$(( ${hook_com[applied-n]} + ${hook_com[unapplied-n]} ))
+    hook_com+=( ${7:+"${(@kvP)7}"} )
+    if VCS_INFO_hook 'set-patch-format' "${(P)6}"; then
+        # Escape the value for use in $PS1
+        if [[ $applied_needs_escaping == 'yes' ]]; then
+          hook_com[applied]=${hook_com[applied]//'%'/%%}
+        fi
+        if [[ $unapplied_needs_escaping == 'yes' ]]; then
+          hook_com[unapplied]=${hook_com[unapplied]//'%'/%%}
+        fi
+
+        zformat -f REPLY "${(P)6}" "p:${hook_com[applied]}" "u:${hook_com[unapplied]}" \
+                                        "n:${hook_com[applied-n]}" "c:${hook_com[unapplied-n]}" \
+                                        "a:${hook_com[all-n]}" \
+                                        ${8:+"${(@P)8}"}
+    else
+        unset applied_needs_escaping unapplied_needs_escaping # the hook deals with escaping
+        REPLY=${hook_com[patch-replace]}
+    fi
+    hook_com=()
+
+}
diff --git a/Functions/VCS_Info/vcs_info b/Functions/VCS_Info/vcs_info
index f13f6b501..4e9ac6c6a 100644
--- a/Functions/VCS_Info/vcs_info
+++ b/Functions/VCS_Info/vcs_info
@@ -19,9 +19,12 @@ static_functions=(
     VCS_INFO_check_com
     VCS_INFO_formats
     VCS_INFO_get_cmd
+    VCS_INFO_hexdump
     VCS_INFO_hook
+    VCS_INFO_set-patch-format
     VCS_INFO_maxexports
     VCS_INFO_nvcsformats
+    VCS_INFO_patch2subject
     VCS_INFO_quilt
     VCS_INFO_realpath
     VCS_INFO_reposub