Ещё интересно, как Git/Mercurial работает с tree conflicts. Это когда, например, в основной ветке фаил удалили, а в рабочей ветке в этот же фаил были внесены изменения.
И как дела обстаят с перемещениями фаилов и параллельным изменением их в другой ветке.
Команды svn приведённые в статье не раскрывают всех возможностей. Всё можно сделать немного проще. Но хотелось бы посмотреть на эквивалентную стратегию в hg. Могли бы вы привести аналогичные примеры?
«Once you have performed a reintegrate merge you should not continue to use it for development. The reason for this is that if you try to resynchronize your existing branch from trunk later on, merge tracking will see your reintegration as a trunk change that has not yet been merged into the branch, and will try to merge the branch-to-trunk merge back into the branch! The solution to this is simply to create a new branch from trunk to continue the next phase of your development.»
Тем не менее параметр --record-only просто устанавливает в свойство svn:mergeinfo ревизию транка, в которой были слиты изменения из ветки, без слития самих изменений и в дальнейшем merge не будет учитывать эту ревизию при слитии транка в ветку.
> cd my-calc-branch
> svn propget svn:mergeinfo .
/trunk:1680-3305
# Let's make the metadata list r3328 as already merged.
> svn merge -c 3328 --record-only ^/calc/trunk
> svn status
M .
При слитии trunk в ветку необязательно указывать ревизию последнего слития, достаточно указать ревизию создания ветки.
В дополнении к уже сказанному про reintegrate: если есть необходимость поддерживать ветку дальше, то необходимо заблокировать ревизию: > svn merge --reintegrate @branch
> svn ci -m "..."
Rev: 123
> svn sw @branch
> svn merge --record-only -c 123 @trunk
> svn ci -m "..."
Это анлагично n.equals(42), т.к. equals принимает Object, соответственно тут будет автобоксинг — именно поэтому первый вариант вернёт true, т.к. будут сравниваться не 42 == 42, а 9000 == 9000.
Не поможет. equals будет сравнивать value: Integer n = 42;
System.out.println(n.equals(42));
Выдаст true, но Integer n = new Integer(42);
System.out.println(n.equals(42));
Опять будет false.
А в чём спор?
> можно хоть так сравнивать: 5.Equals(5); но куда проще 5==5
Для примитивов в Java возможен только второй способ, более простой :)
Для объектов в любом руководстве по языку написано, что сравнивать объекты необходимо с помощью equals(), а не ==. Как по мне, разделение примитив-врапер удобно — разработчик сам решает что и где ему использовать (о том правильно ли он решит думать не хочется :).
К сожалению, не очень знаком с .net, поэтому не хочу развивать дискуссию «что лучше» далее.
Про концепцию ООП вообще молчу — всего должно быть в меру, примитивные типы — это как раз то разумное отступление, сделанное для удобства.
когда в первый раз взял в руки, меня смутило отсутствие клавиши "=". Во второй раз я уже проникся, было это классе в 6-7… спасибо, аж ностальгия нахлынула!
Мой питался от сети и я помню, как мама выдирала БП из розетки и заставляла меня идти гулять на улицу :)
И как дела обстаят с перемещениями фаилов и параллельным изменением их в другой ветке.
> svn copy ^/trunk ^/branches/name
2. Переключаемся на ветку
> svn switch ^/branches/name
3. Работаем…
> svn commit -m «Разработано что-то полезное»
4. Сливаем изменения из ствола в ветку
> svn mergeinfo --show-revs eligible ^/trunk
123
125
126
> svn merge --accept postpone -r 122:HEAD ^/trunk
5. Правим конфликты, если таковые имеются
6. Тестируем и комитим результаты слияния
> svn commit -m «Слияние trunk 123:126»
7. Переключаемся в основную ветку
> svn switch ^/trunk
8. Сливаем ветку в ствол
> svn merge --reintegrate ^/branches/name
9. Правим конфликты, но пока их тут никогда небыло и убираем изменения, которые сливать нет необходимости (например версия модуля в maven)
10. Тестируем и комитим результаты слияния
> svn commit -m «Слияние branches/name»
11. Удаляем ветку
> svn delete ^/branches/name
Шаг 3 автоматизирован.
Для шагов 7 и 8 так же есть скрипт.
Вижу, что по сравнению с hg действительно приходится делать больше телодвижений:
1. Получение версии для слияния
2. Комиты результатов слияния (2 шт.)
svn copy ^/trunk ^/branches/branch_name
Согласитесь, не намного сложнее?
Да и никто не мешает сделать скрипт, наподобии:
svn copy ^/trunk ^/branches/%1
И вызывать его:
svn_branch НАЗВАНИЕ_ВЕТКИ
Так сказано по ссылке приведённой в habrahabr.ru/blogs/webdev/120063/#comment_3932020
Тем не менее параметр --record-only просто устанавливает в свойство svn:mergeinfo ревизию транка, в которой были слиты изменения из ветки, без слития самих изменений и в дальнейшем merge не будет учитывать эту ревизию при слитии транка в ветку.
> cd my-calc-branch
> svn propget svn:mergeinfo .
/trunk:1680-3305
# Let's make the metadata list r3328 as already merged.
> svn merge -c 3328 --record-only ^/calc/trunk
> svn status
M .
> svn propget svn:mergeinfo .
/trunk:1680-3305,3328
> svn commit -m "Block r3328 from being merged to the branch."
Пример взят по ссылке svnbook.red-bean.com/nightly/en/svn.branchmerge.advanced.html которую я крайне рекомендую для ознакомления всем, кто так или иначе работает с ветками SVN.
В дополнении к уже сказанному про reintegrate: если есть необходимость поддерживать ветку дальше, то необходимо заблокировать ревизию:
> svn merge --reintegrate @branch
> svn ci -m "..."
Rev: 123
> svn sw @branch
> svn merge --record-only -c 123 @trunk
> svn ci -m "..."
Integer n = 42;
System.out.println(n.equals(42));
Выдаст true, но
Integer n = new Integer(42);
System.out.println(n.equals(42));
Опять будет false.
Но это ещё ладно, всё просто будет больше тормозить, но намного хуже когда:
Вуаля, много ли кто понимает, чем это опасно?
> можно хоть так сравнивать: 5.Equals(5); но куда проще 5==5
Для примитивов в Java возможен только второй способ, более простой :)
Для объектов в любом руководстве по языку написано, что сравнивать объекты необходимо с помощью equals(), а не ==. Как по мне, разделение примитив-врапер удобно — разработчик сам решает что и где ему использовать (о том правильно ли он решит думать не хочется :).
К сожалению, не очень знаком с .net, поэтому не хочу развивать дискуссию «что лучше» далее.
Про концепцию ООП вообще молчу — всего должно быть в меру, примитивные типы — это как раз то разумное отступление, сделанное для удобства.
int a = 1000;
int b = 1000;
a == b -> true
В то время, как Integer — это уже не примитивный тип данных, а полноценный объект и сравнивание для него работает как для всех объектов.
А помнить надо про auto boxing-unboxing — вот тут очень много тонкостей, и пул объектов, и утечки памяти
Мой питался от сети и я помню, как мама выдирала БП из розетки и заставляла меня идти гулять на улицу :)