Subversion rebase?

Я нахожу этот способ проще объединять ветки и меньше конфликтов:

Скопируйте соединительную линию в новую ветвь, объедините ее с ветвью функций. Когда все будет сделано, слейте новую ветку обратно в багажник. Этот метод похож на меркурийный и git rebasing.

Я использовал, чтобы объединить все переменные из сундука в функцию branche/s. Но позже, когда я объединил ветку функций обратно в багажник, часть материала из багажника снова будет объединена с багажником, что вызвало множество конфликтов. Есть выбор реинтеграции слияния, но он, похоже, не работает для меня.

Есть ли у кого-нибудь подобный подрывной перегиб? Я только начал делать это недавно и не видел никаких побочных эффектов. Может ли это вызвать какие-либо непредвиденные проблемы?

Ответ 1

Вообще говоря, rebasing является актом включения восходящих изменений в ветки признака, прежде чем слияние ветки функции обратно в ветвь вверх по течению.

В git процесс еще более сложный, поскольку изменения, которые были сделаны после создания ветки, сначала снимаются и буферизуются, применяются изменения восходящего потока, затем применяются буферизованные изменения. Вынос здесь заключается в слиянии ствола с веткой функций, которая не является перестановкой в ​​терминах git, там больше. Подход git имеет ряд преимуществ, но не может быть реализован очень строго в svn, поскольку все коммиты должны храниться на сервере (svn не распространяется), однако это можно сделать в svn.

An 'svn rebase' (путь git) может выглядеть примерно так:

  • svn cp trunk feature
  • фиксирует функцию и соединительную линию
  • svn cp trunk feature-rebase
  • svn co feature-rebase
  • cd feature-rebase
  • svn merge feature
  • svn commit
  • svn rm feature
  • svn mv feature-rebase feature
  • (обратно на WCF) svn switch feature

Затем, в конце концов, на рабочей копии туловища svn merge --reintegrate feature

Вы видите отличие от простого слияния магистрали с ветвью функций? В этом примере вы начинаете с последнего из восходящего потока, туловища, затем объединяете изменения с этой функцией.

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

Ответ 2

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

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

Я бы предпочел, чтобы обновление ветки путем слияния соединительных линий обратно в ветвь не приводило к тому, что последующая реинтеграция сливается с этой веткой, чтобы вытащить эти измененные изменения во время процесса. Это должно быть возможно на основе свойств merge-info, но в соответствии с тем, какие состояния jdehaan и что я опасаюсь, так это то, что для этого все еще требуется выбор вишни.

Обратите внимание, что правильная реализация переустановки также должна учитывать примеры лестничных крышек, где ветка выполнена из другой ветки.

Обновление:. Согласно документации Subversion, при использовании - реинтегрировать опцию, что Subversion должна быть способный правильно реинтегрировать работу, выполненную в ветки, таким образом, чтобы учесть любые возможные обновления, которые могли быть сделаны для внесения изменений в базу. Конечно, это технически немного отличается от перезагрузки, но я думаю, что он достаточно похож на использование, что его можно назвать перезагрузкой.

Ответ 3

В моей компании мы используем следующий подход:

  • для каждой задачи NK- $X в трекер-проблеме у нас есть отдельные ветки ветвей /NK - $X
  • мы начинаем работу над задачей svn cp trunk branch/NK- $X
  • мы никогда не вносим изменений непосредственно в багажник. Для каждого запланированного обновления UPDNK- $X мы имеем отдельные ветки /UPDNK - $X. Мы создаем его с svn cp trunk branch/UPDNK- $X непосредственно перед обновлением.
  • когда задание NK- $X запланировано для обновления UPDNK- $Y, мы объединяем ветки /NK - $X inot UPDNK- $Y. Это cd UPDNK- $Y; svn merge -r start: HEAD ветки /NK - $X
  • после того, как UPDNK- $Y готов, мы объединим его в багажник. Это cd trunk; svn merge -r start: HEAD ветки /UPDNK - $Y

Если это происходит, то задача NK- $X длится дольше, чем один итерационный цикл, и поэтому нуждается в обновлении, мы никогда, никогда, НИКОГДА не соединяем багажник с NK-X. У нас есть правило, которое вы передаете своей ветке только тем, что вы написали сами, что делает все проще. Вместо этого мы делаем:

cd NK-$X
svn log
//let L = the number of the last changeset to this branch changeset
//let F = the number of the first changeset to this branch
svn rm branches/NK-$X 
svn cp trunk branches/NK-$X 
svn up
svn merge -r F:L branches/[email protected] 
svn ci -m 'refereshed'

Таким образом, всякий раз, когда вы смотрите на журнал изменений /NK -X, вы видите только изменения, фактически выполненные разработчиком.

Update: Поскольку описанный выше рабочий процесс может быть автоматизирован, я начал проект по github: svn rebase.

Ответ 4

Я использую этот подход:

При перезагрузке вы должны позаботиться о том, чтобы не переупаковывать изменения, когда вы снова слились. Когда дело доходит до слияния, сделайте выбор вишни: выберите только изменения в ветки функции, которые реализуют что-то новое, а не переустанавливающие изменения. Тогда он должен работать нормально. КОММЕНТАРИЙ: Я никогда не мог вспомнить, что я использовал реинтеграцию для чего-то. Я думаю, что он предназначен только для очень простых случаев использования.

В вашем новом подходе не совсем ясно из описания того, как вы справляетесь с переустановкой из магистрали в свои ветки функций, если вам нужно. Вы хотите полностью запретить перезагрузку? Поскольку ветвление в svn является дешевой операцией, это тоже может быть вариант.

Ответ 5

Я использую скрипт, который делает git, как rebase для SVN:

#!/bin/bash

set_safe()
{
    set -eo pipefail
}

validate_number()
(
    if (! [ "$1" -eq "$1" ] 2>/dev/null ) then
    {
        echo "$1 is not a number"
        return 1
    }
    fi
)

get_line()
(
    set_safe
    #head -n "$1" | tail -n 1
    sed -n "${1}p;$(($1+1))q"
)

split_trim()
(
    set_safe
    tr "$1" '\n' | sed -e 's/^\s*//;' -e 's/\s*$//'
)

run_svn()
(
    set +x
    #echo "svn $*" 1>&2
    svn --non-interactive --password "$svn_password" "[email protected]"
)

rebase()
(
    set_safe

    url="$1"
    cur="$2"
    end="$3"

    validate_number "$cur"
    if ([ -z "$end" ] || [ "$end" = "HEAD" ]) then
    {
        end="$(run_svn info "$url" | grep "Last Changed Rev" | cut -d' ' -f4)"
        echo "end: $end"
    }
    else
    {
        validate_number "$end";
    }
    fi

    while (true) do
    {
        log="$(run_svn log "$url" -l1 -r "$cur:HEAD")"
        meta="$(echo -n "$log" | get_line 2 | split_trim '|')"
        next="$(echo -n "$meta" | get_line 1 | tail -c +2)"
        author="$(echo -n "$meta" | get_line 2)"
        date="$(echo -n "$meta" | get_line 3 | awk '{print $1, $2, $3}')"
        msg="$(echo -n "$log" | tail -n +4 | head -n -1)"
        cur=$next

        if ([ -z $cur ] || [ $cur -gt $end ]) then { break; } fi

        echo "$msg" > .msg

        echo "Merging revision $cur:"
        echo "========"
        cat .msg
        echo "========"

        run_svn merge "$url" -c $cur
        run_svn commit -F .msg
        rm -f .msg
        run_svn update

        echo "Success"
        echo

        cur=$(($cur + 1))
    }
    done
)

if ([ -z "$1" ]) then
{
    echo "Usage:"
    echo "    svn-rebase.sh <url> <begin revision> [end revision]"
    exit
}
fi

echo -n "svn password: "
read -s svn_password
echo

rebase "$1" "$2" "$3"
err=$?
if ([ $err -ne 0 ]) then { echo "rebase failed: $err"; } fi
exit $err

Он объединяет ревизии из другой ветки одна за другой.

Ответ 6

используйте git svn:

git svn clone -s <link to svn trunk/branches/tags parent>

тогда не стесняйтесь использовать команду git rebase