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