svn diff, включая аннотацию / аналогичную информацию о том, когда ВОЗ внесла изменения

можете ли вы добавить аннотировать / обвинять подобную информацию в svn diff, так что для каждой измененной строки Она включает в себя, какой пользователь и редакция изменили эту строку?

например, Сравнение аннотаций-diff ревизий 8-10 может выдать что-то вроде:

9    user1   - some line that user1 deleted in revision 9
10   user2   + some line that user2 added in revision 10

контекст, линии вокруг него не изменилась, может быть также включен или нет, неважно.

дело не только в "быстром" написании скрипта оболочки, объединяющего вывод svn diff и svn комментировать. аннотирование, например, никогда не покажет вам, кто удалил строку. Это также не вопрос аннотации к ревизии в прошлом: нас не интересует, кто первоначально добавил строку, которая была удалена (это не тот, кто "вызвал" разницу), мы хотим знать, кто ее удалил.
Я подозреваю, что единственный способ реализовать что-то сделать это-проверить каждый коммит между двумя сравниваемыми ревизиями (и каким-то образом отобразить все изменения в отдельных различиях в строки в общей сложности разность.)..

существует ли инструмент, который делает нечто подобное?

30
задан Wouter Coekaerts
07.05.2023 7:54 Количество просмотров материала 3625
Распечатать страницу

5 ответов

Я не совсем уверен, что понял, чего именно вы хотите, но я сделал это с TortoiseSVN:

  1. создать вину из ревизии 1 в ревизию A-сохранить как A.txt
  2. создать вину из ревизии 1 в ревизию B-сохранить как B.txt
  3. удалить первый столбец (строку) из обоих текстовых файлов (я использовал редактор Pspad, который может удалить столбец текстового файла)
  4. объединить A.txt и B.txt (TortoiseMerge.ехе /основание:"a.txt" /я:"b.txt" )

Он показывает измененные, добавленные и удаленные строки между ревизиями A и B вместе с датой, пользователем и ветвью, я думаю, что это то, что вы хотели.

1
отвечен Odin 2023-05-08 15:42

SVN diff принимает ровно две ревизии и генерирует вывод на лету. SVN annotate принимает ровно одну ревизию. Ваше подозрение, что предлагаемая утилита должна будет выполнить итерацию по N ревизиям, верно; SVN хранит состояния ревизии как целые объекты.

возможно, вам больше повезет с Git и git-svn gateway...

1
отвечен qneill 2023-05-08 17:59

в вашей базовой настройке vanilla SVN нет команды, которая может объединить выходы blame и diff на определенной ревизии. Если вы указали конкретный клиент SVN, который вы использовали, я мог бы найти плагин, который делает это, но вы этого не сделали, поэтому я не мог его искать.

единственная альтернатива - использовать скрипт или небольшую программу для сопоставления двух выходных данных. Это не должно быть так сложно, если вы можете получить номера строк на дифф и виноват. Хотя это не ответ, на который вы надеялись, что это ответ, и этот вопрос открыт с 2009 года.

0
отвечен Daisetsu 2023-05-08 20:16

Это не совсем то, что вам нужно, но вы можете получить аннотированное представление об изменениях в OpenGrok.

0
отвечен Peter Loron 2023-05-08 22:33

существует ли инструмент, который делает нечто подобное?

Ну, я думаю, что теперь есть.

использование; blameDiff <path> [rev1] [rev2]

функция bash

function blameDiff() {
    file=""
    rev1=""
    rev2=""

    #default to HEAD if omitted
    if [ -n "$rev1" ]
    then
        title1="(revision $rev1)"
    else
        title1="(working copy)"
        rev1='HEAD'
    fi
    if [ -n "$rev2" ]
    then
        title2="(revision $rev2)"
    else
        title2="(working copy)"
        rev2='HEAD'
    fi

    #check that the svn urls are the same
    tmp1="$(svn info -r $rev1 "$file" |\
        grep '^Relative URL' |\
        sed 's/Relative URL: //' \
    )"
    tmp2="$(svn info -r $rev2 "$file" |\
        grep '^Relative URL' |\
        sed 's/Relative URL: //' \
    )"
    if [ "$tmp1" != "$tmp2" ]
    then
        #if not, then one of these revisions is in another branch
        #lets have this in the output
        title1="($tmp1) $title1"
        title2="($tmp2) $title2"
    fi

#can just print this but you wont get deleted revision/blame
#    diff -u \
#        <(svn blame -r "$rev1" "$file") \
#        <(svn blame -r "$rev2" "$file") \
#    | sed "s|^--- .*$|--- $file $title1|" \
#    | sed "s|^+++ .*$|+++ $file $title2|"
#    return 0

    #an array of commitNumber|committer pairs for the file
    history=()
    #a map between elements in `history` and a list of line numbers changed.
    #each item in the list is a lineNumber|newLineNumber pair
    declare -A revisions

    #the sed match and replace expressions to pull data from the
    #diff-line-number&cat-line-number combo and give it to the cache
    grabData='^ *\([0-9]\+\)\t\([0-9]\+\)$'
    formatData=' '

    #for each revision between the ones given
    last=''
    while read -r line
    do
        #read in the revision number and submitter
        IFS=' |' read next by tmp <<<"$line"

        if [ -n "$last" ]
        then
            #save them
            history+=("$next $by")
            #associate and format the list
            revisions["${history[-1]}"]="$(\
                diff \
                    --unchanged-line-format="%dn%c'2'" \
                    --new-line-format="?%c'2'" \
                    --old-line-format='' \
                    <(svn cat -r "$last" "$file") \
                    <(svn cat -r "$next" "$file") \
                | cat -n \
                | grep -v '?$' \
                | sed "s/$grabData/$formatData/" \
            )"
        fi

        #remember the last revision looked at
        last="$next"
    done <<<"$(
        svn log -r "$rev1:$rev2" "$file" \
        | grep '^r[0-9]\+ | ' \
        | sed 's/^r//' \
    )"

    #pull the full diff
    diff \
        --new-line-format='+%L' \
        --old-line-format='-%L' \
        --unchanged-line-format='=%L' \
        <(svn blame -r "$rev1" "$file") \
        <(svn blame -r "$rev2" "$file") \
    | {
        #header stuff
        echo "Index: $file"
        echo '==================================================================='
        echo "--- $file $title1"
        echo "+++ $file $title2"

        #count the line number we're up to for the original file
        origLine=0
        #count the line number we're up to for the new file
        newLine=0

        #keep a few of the output lines, and their line number contexts
        buffer=()
        origContext=()
        newContext=()

        #tells the script to print the buffer if <3;
        #the context lines around real differences
        printing=4
        #whether or not the next print needs to show line numbers
        needsContext=true

        #the sed match and replace expressions to pull data from diff
        #and give it to read
        grabData='^\([+=-]\)\( *[0-9]\+\)\( *[^ ]\+\)\(.*\)$'
        formatData='\v\v\v'

        #for each line in the full diff
        while read -r data
        do
            IFS=$'\v' read flag committed who line <<<"$(\
                sed $'s/\t/    /g' \
                <<<"$data" \
                | sed "s/$grabData/$formatData/" \
            )"
            #the last surviving revision of the line
            edited="$rev2"
            #who killed this line
            by=''

            case "$flag" in
            +)
                #a new line was introduced
                ((++newLine))
                printing=0
            ;;
            -)
                #an old line was removed
                ((++origLine))
                printing=0
                #the line number that changes throughout history
                number="$origLine"
                #for each commit
                for revision in "${history[@]}"
                do
                    #read in the two line numbers from the matching change
                    number="$(grep "^$number " <<<"${revisions["$revision"]}")"
                    IFS=' ' read edited by <<<"$revision"

                    #not present; this was the revision where it was destroyed
                    if [ -z "$number" ]
                    then
                        break
                    fi

                    #pull the new line number for the next revision
                    IFS=' ' read tmp number <<<"$number"
                done
            ;;
            =)
                #an old line continues to exist in the new file
                ((++newLine))
                ((++origLine))
                flag=' '
                ((++printing))
            ;;
            esac

            #format the line to print
            buffer+=("$(printf "%s %s:%-${#committed}s%s:%-${#who}s%s" \
                "$flag" \
                "$committed" \
                "$edited" \
                "$who" \
                "$by" \
                "$line" \
            )")
#can just end it here, but it will print the whole file/s
#            echo "${buffer[-1]}"
#            buffer=()
#            continue
            #and add the context
            origContext+=("$origLine")
            newContext+=("$newLine")

            if ((printing < 4))
            then
                if $needsContext
                then
                    echo "@@ -${origContext[0]} +${newContext[0]} @@"
                    needsContext=false
                fi

                #print all lines in the buffer
                for line in "${buffer[@]}"
                do
                    echo "$line"
                done

                #and reset it
                origContext=()
                newContext=()
                buffer=()
            fi

            #if there are too many lines in the buffer
            if ((${#buffer[@]} > 3))
            then
                #remove the overflow
                origContext=("${origContext[@]:1}")
                newContext=("${newContext[@]:1}")
                buffer=("${buffer[@]:1}")
                #and note that we now need to show the context because of this
                needsContext=true
            fi
        done
    }
}

я добавил комментарии в качестве объяснения, поэтому я не буду вдаваться здесь.

Протестировано для работы с выходами diff (fedora 27),svn info (1.10.2) на моей системе, YMMV (но за все мои усилия, я надеюсь, не так много!).

это в принципе повторно реализует с svn diff через просто svn cat и регулярно diff учитывать ревизию и номера строк, отслеживая, где именно в истории была удалена данная строка.

Даже учитывает, находятся ли файлы в разных ветвях и отображает его как svn.

вот скриншоты двух следующих команд, с кодом, отредактированным по причинам работы.

~/data/<redacted>/svn-2.4.2/$ svn diff -r 6600 services/<redacted>.w3p | gvim -
~/data/<redacted>/svn-2.4.2/$ blameDiff services/<redacted>.w3p 6600 | gvim -

enter image description here

как вы можно увидеть кучу дополнительной информации в новом формате справа; первые столбцы показывают, что Эшли добавил пару строк назад в r6631 и удалил целую кучу в r6639, первоначально совершенном zes давно @r6466&6483.

0
отвечен Hashbrown 2023-05-09 00:50

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх