Я вже пару місяців використовую Git для проекту з іншим розробником. Я маю декілька років досвіду роботи зі SVN , тому, мабуть, я приношу багато багажу на стосунки.
Я чув, що Git чудово підходить для розгалуження та злиття, і поки що я просто не бачу цього. Звичайно, розгалуження мертве просто, але коли я намагаюся злитись, все йде в пекло. Зараз я звик до цього з SVN, але мені здається, що я просто торгував однією системою версій підрозділу на іншу.
Мій партнер каже мені, що мої проблеми випливають із мого бажання об'єднатися вольово-невольно, і що мені слід використовувати ребауз замість злиття у багатьох ситуаціях. Наприклад, ось цей робочий процес, який він заклав:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature
git checkout master
git merge my_new_feature
По суті, створіть функціональну гілку, ЗАВЖДИ перезавантажтеся з головного на гілку та об'єднайтеся з гілки назад у головну. Важливо зазначити, що гілка завжди залишається локальною.
Ось робочий процес, з якого я почав
clone remote repository
create my_new_feature branch on remote repository
git checkout -b --track my_new_feature origin/my_new_feature
..work, commit, push to origin/my_new_feature
git merge master (to get some changes that my partner added)
..work, commit, push to origin/my_new_feature
git merge master
..finish my_new_feature, push to origin/my_new_feature
git checkout master
git merge my_new_feature
delete remote branch
delete local branch
Є дві суттєві відмінності (я думаю): я використовую злиття завжди замість перезавантаження, і я висуваю свою функціональну гілку (і моя гілка функцій здійснює) до віддаленого сховища.
Моє міркування про віддалену гілку полягає в тому, що я хочу, щоб моя робота була підготовлена під час роботи. Наш сховище автоматично створюється резервна копія і може бути відновлена, якщо щось піде не так. Мій ноутбук не є чи не таким ретельним. Тому я ненавиджу код на своєму ноутбуці, який не відображений десь в іншому місці.
Моє міркування про злиття замість ребазування полягає в тому, що злиття здається стандартним, а повторне здавання є вдосконаленою функцією. Моє відчуття кишки полягає в тому, що те, що я намагаюся зробити, - це не вдосконалена установка, тому перезавантаження повинно бути непотрібним. Я навіть ознайомився з новою книгою «Прагматичне програмування» про Git, і вони широко висвітлюють злиття та ледве згадують про перезавантаження.
У будь-якому разі я слідкував за своїм робочим процесом на недавньому відділенні, і коли я намагався об'єднати його назад, щоб засвоїти, все пішло в пекло. Були тони конфліктів із речами, які не мали значення. Конфлікти просто не мали для мене сенсу. Мені знадобився день, щоб все розібратися, і в кінцевому підсумку завершився примусовий поштовх до віддаленого майстра, оскільки мій місцевий господар вирішив усі конфлікти, але віддалений все ще не був задоволений.
Який «правильний» робочий процес для подібного? Git повинен зробити розгалуження та злиття надлегким, і я просто не бачу цього.
Оновлення 2011-04-15
Це, здається, дуже популярне питання, тому я подумав, що я би вдосконалив свій досвід роботи за два роки, як я вперше запитав.
Виявляється, початковий робочий процес є правильним, принаймні в нашому випадку. Іншими словами, це те, що ми робимо, і це працює:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge my_new_feature
Насправді наш робочий процес дещо інший, оскільки ми, як правило, робимо злиття сквош замість сирих злиття. ( Примітка. Це суперечливо, див. Нижче. ) Це дозволяє нам перетворити всю нашу гілку функцій в єдину комісію для головного. Потім ми видаляємо нашу функціональну гілку. Це дозволяє нам логічно структурувати свої зобов'язання на майстра, навіть якщо вони трохи безладні на наших гілках. Отже, це ми робимо:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge --squash my_new_feature
git commit -m "added my_new_feature"
git branch -D my_new_feature
Суперечка злиття сквош - Як уже зазначали декілька коментаторів, злиття сквош викине всю історію на вашу функціональну галузь. Як випливає з назви, воно розбиває всі об'єднання в єдину. Для невеликих функцій це має сенс, оскільки воно конденсується в єдиний пакет. Що стосується більших можливостей, це, мабуть, не чудова ідея, особливо якщо ваші індивідуальні зобов'язання вже є атомними. Це дійсно зводиться до особистих переваг.
Запити на отримання Github та Bitbucket (інші?) - Якщо вам цікаво, як злиття / перезавантаження стосується Pull Requests, я рекомендую дотримуватися всіх вищезазначених кроків до тих пір, поки ви не будете готові до злиття назад до майстра. Замість того, щоб вручну зливатися з git, ви просто приймаєте PR. Зауважте, що це не призведе до злиття сквош (принаймні, не за замовчуванням), але не сквош, не швидкий перемотка вперед - це прийнята конвенція про злиття в спільноті Pull Request (наскільки я знаю). Зокрема, це працює так:
clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git push # May need to force push
...submit PR, wait for a review, make any changes requested for the PR
git rebase master
git push # Will probably need to force push (-f), due to previous rebases from master
...accept the PR, most likely also deleting the feature branch in the process
git checkout master
git branch -d my_new_feature
git remote prune origin
Я полюбив Git і ніколи не хочу повертатися до SVN. Якщо ви боретеся, просто дотримуйтесь цього, і врешті ви побачите світло в кінці тунелю.
rebase
розумінням