diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | Functions/VCS_Info/VCS_INFO_quilt | 42 |
2 files changed, 41 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog index 5f0cae6ce..5ff60c6f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2016-06-06 Daniel Shahaf <d.s@daniel.shahaf.name> + * 38610: Functions/VCS_Info/VCS_INFO_quilt: vcs_info quilt: + Extract a patch subject, 2.0. + * 38609: Functions/VCS_Info/VCS_INFO_quilt: vcs_info quilt: Factor out a helper function. No functional change. diff --git a/Functions/VCS_Info/VCS_INFO_quilt b/Functions/VCS_Info/VCS_INFO_quilt index e31deb0bd..e7cd89f78 100644 --- a/Functions/VCS_Info/VCS_INFO_quilt +++ b/Functions/VCS_Info/VCS_INFO_quilt @@ -83,15 +83,49 @@ function VCS_INFO_quilt-dirfind() { # 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. function VCS_INFO_quilt-patch2subject() { - local line - if [[ -f "$1" ]] && read -r line < "$1"; then - if [[ $line != (#b)(---|Index:)* ]]; then - REPLY=$line + 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]} )); 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 |