Просте рішення: Видаліть гілку "робота" після об'єднання
Коротка відповідь: Ви можете використовувати git як завгодно (див. Нижче простий робочий процес), включаючи злиття. Просто переконайтеся, що слідкуйте за кожною роботою " git merge " та " git branch -d" ", щоб видалити тимчасову роботу.
Основне пояснення: Проблема злиття / dcommit полягає в тому, що щоразу, коли ви «git svn dcommit» гілку, історія з’єднання цієї гілки «сплющується»: git забуває про всі операції з’єднання, що увійшли до цієї гілки: Просто вміст файлу зберігається, але той факт, що цей вміст (частково) походив із певної іншої галузі, втрачається. Див.: Чому git svn dcommit втрачає історію комісій злиття для місцевих відділень?
(Примітка: git-svn може зробити з цим не так багато: svn просто не розуміє набагато більш потужні git злиття. Отже, всередині сховища svn ця інформація про злиття не може бути представлена жодним чином.)
Але це ціле проблема. Якщо ви видалите гілку 'work' після того, як вона була об'єднана в 'master branch', то ваше сховище git на 100% чисте і виглядає точно як ваше сховище svn.
Мій робочий процес:
Звичайно, я спершу клонував віддалений сховище svn у локальне сховище git (це може зайняти деякий час):
$> git svn clone <svn-repository-url> <local-directory>
Вся робота тоді відбувається всередині "local-каталогу". Щоразу, коли мені потрібно отримувати оновлення з сервера (наприклад, "svn update"), я роблю:
$> git checkout master
$> git svn rebase
Я всю свою розробку працюю в окремій галузі "робота", яка створена так:
$> git checkout -b work
Звичайно, ви можете створити скільки завгодно гілок для вашої роботи, з’єднати та відновити між ними місця, як вам подобається (просто видаліть їх, коли ви закінчите з ними --- як зазначено нижче). У своїй звичайній роботі я дотримуюся дуже часто:
$> git commit -am '-- finished a little piece of work'
Наступний крок (git rebase -i) - необов’язковий --- це просто очищення історії перед архівуванням на svn: Одного разу я дістався стійкого кілометражу, який я хочу поділитися з іншими, я переписав історію цього "твору" гілка та очищення повідомлень про фіксацію (іншим розробникам не потрібно бачити всі маленькі кроки та помилки, які я зробив на шляху --- лише результат). Для цього я і роблю
$> git log
і скопіюйте хеш sha-1 останнього комітету, який знаходиться у прямому сховищі svn (як зазначено git-svn-id). Тоді я дзвоню
$> git rebase -i 74e4068360e34b2ccf0c5869703af458cde0cdcb
Просто вставте ша-1 хеш нашого останнього свн-файлу замість мого. Ви можете прочитати документацію з "git help rebase" для деталей. Коротше кажучи: ця команда спочатку відкриває редактор, представляючи ваші зобов’язання ---- просто змініть "pick" на "squash" для всіх тих комітетів, які ви хочете скасувати з попередніми комітами. Звичайно, перший рядок повинен залишатися як "вибір". Таким чином, ви можете конденсувати свої численні дрібниці в одній або декількох значущих одиницях. Збережіть та вийдіть із редактора. Ви отримаєте інший редактор з проханням переписати повідомлення журналу фіксації.
Коротше кажучи: після того, як я закінчу "злом коду", я масажую свою "роботу" гілку, поки не з’явиться, як я хочу представити її іншим програмістам (або як я хочу побачити роботу за кілька тижнів, коли я переглядаю історію) .
Для того, щоб змінити зміни до сховища svn, я:
$> git checkout master
$> git svn rebase
Тепер ми повернулися до старої гілки 'master', оновленої всіма змінами, що відбулися в середній час у сховищі svn (ваші нові зміни приховані у відділенні 'work').
Якщо є зміни, які можуть суперечити вашим новим змінам роботи, вам доведеться вирішити їх локально, перш ніж ви зможете надіслати свою нову роботу (детальніше див. Нижче). Тоді ми можемо натиснути наші зміни на svn:
$> git checkout master
$> git merge work # (1) merge your 'work' into 'master'
$> git branch -d work # (2) remove the work branch immediately after merging
$> git svn dcommit # (3) push your changes to the svn repository
Примітка 1: Команда "git branch -d work" є досить безпечною: вона дозволяє лише видалити гілки, які вам більше не потрібні (тому що вони вже об'єднані у вашу поточну гілку). Якщо ви виконаєте цю команду помилково, перш ніж об’єднати свою роботу з гілкою 'master', ви отримаєте повідомлення про помилку.
Примітка 2: Переконайтесь, що ви видалите свою гілку з 'git branch -d робота' між об'єднанням і dcommit: Якщо ви спробуєте видалити гілку після dcommit, ви отримаєте повідомлення про помилку: Коли ви робите 'git svn dcommit', git забуває про це ваша філія була об'єднана з "господарем". Ви повинні видалити його за допомогою "git branch -D work", яке не робить перевірку безпеки.
Тепер я одразу створю нову гілку "робота", щоб випадково не зламати "гілку":
$> git checkout -b work
$> git branch # show my branches:
master
* work
Інтеграція вашої 'роботи' зі змінами на svn:
Ось, що я роблю, коли 'git svn rebase' виявляє, що інші змінили сховище svn, коли я працював над моєю гілкою 'work':
$> git checkout master
$> git svn rebase # 'svn pull' changes
$> git checkout work # go to my work
$> git checkout -b integration # make a copy of the branch
$> git merge master # integrate my changes with theirs
$> ... check/fix/debug ...
$> ... rewrite history with rebase -i if needed
$> git checkout master # try again to push my changes
$> git svn rebase # hopefully no further changes to merge
$> git merge integration # (1) merge your work with theirs
$> git branch -d work # (2) remove branches that are merged
$> git branch -d integration # (2) remove branches that are merged
$> git svn dcommit # (3) push your changes to the svn repository
Є більш потужні рішення:
представлений робочий процес спрощений: він використовує повноваження git лише в кожному раунді "update / hack / dcommit" ---, але залишає історію довгострокової роботи так само лінійною, як і сховище svn. Це нормально, якщо ви просто хочете почати використовувати git merges маленькими першими кроками у спадковому svn-проекті.
Коли ви ознайомитесь із об'єднанням git, сміливо вивчайте інші робочі процеси: якщо ви знаєте, що ви робите, ви можете змішати git merges зі svn merges ( Використовуючи git-svn (або подібне) просто для того, щоб допомогти зі злиттям svn? )