Розуміння різниці між гілками SVN та Git


44

Я користувач SVN, і зараз я вивчаю Git.

У SVN я зазвичай оформлюю репо на своїй локальній машині, яка включає всі відділення в моєму проекті, і я вибирав папку для своєї філії, яка мені цікава, і там працюю.

Я бачу різницю за допомогою Git.

В даний час я клоную репо і клоную конкретну гілку за допомогою gitk.

Папка проекту містить лише вміст цієї гілки, і я не бачу всіх гілок, як у SVN, що для мене трохи заплутано.

Я не можу знайти простий спосіб переглянути всі гілки в моєму локальному сховищі за допомогою Git.

  • Мені хотілося б знати, чи описаний я процес Git є "стандартним", а який - правильним чи я щось пропускаю.

  • Також я хотів би знати, як керувати процесом, коли мені потрібно працювати над двома гілками одночасно, якщо, наприклад, мені потрібно зробити виправлення для master, але зберегти вміст іншої гілки.

  • Що таке рекомендації щодо імен, щоб зробити папки, які включають гілку, клоновану з репо в Git, наприклад myproject-branchname?


8
Цікаво - зазвичай за допомогою SVN ви б замовили лише магістраль або гілку, над якою працюєте, але я розумію, що ви маєте на увазі.
HorusKol

20
У вас був порушений робочий процес у SVN, тепер ви намагаєтеся відобразити його у Git (хоча навіть добрий SVN-робочий процес частково застосовується лише для Git). Найкраще рішення - забудьте всі SVN-звички і почніть в Git з нуля
Lazy Badger

6
git cloneбільше нагадує svnadmin hotcopyабо svnrdump+, svnadmin loadніж схоже svn checkout. З git, ви не питаєте біти і шматки з в сховище; ви копіюєте весь сховище і працюєте з ним локально, відсуваючи зміни назад у сховище "джерело", коли і якщо ви відчуваєте, що вам це подобається. Git і Subversion використовують дві абсолютно різні моделі для управління джерелами.
чепнер

1
щодо виправлень, подумайте про використанняgit-flow
Bakuriu

5
@LazyBadger це не порушено робочий процес, якщо це сприяє розробці та надає цінність. Існує не один правильний спосіб використання гілок.
дієтабудда

Відповіді:


67

Я користувач SVN, і зараз я вивчаю GIT.

Ласкаво просимо до банди!

Перевиховання СВН

У SVN я зазвичай [...]

Затримайтеся на хвилину. Хоча CVS та SVN та інші традиційні (тобто централізовані) системи управління версіями виконують (здебільшого) ту саму мету, що і сучасні (тобто розподілені) системи управління версіями, такі як mercurial і Git, вам буде набагато краще вивчити Git з нуля замість намагаючись перенести робочий процес SVN в Git.

http://hginit.com ( погляд на archive.org ) Джоел Спольський (один із самих засновників Stack Exchange) - це навчальний посібник для меркуріалу, а не Git, але це нульовий розділ, "Підвищення субверсії" - це корисно для людей, які переходять із SVN на будь-яку розповсюджену систему контролю версій, оскільки вона розповідає про те, які SVN-концепції потрібно (тимчасово) скасувати (або stashвдалині , як можуть сказати користувачі Git), щоб можна було обернути голову навколо розподіленої Концепції системи управління версіями та ідіоматичні робочі процеси, створені для роботи з ними.

Тож ви можете прочитати цю нульову главу і здебільшого просто замінити слово "меркурій" на "Git" і тим самим належним чином підготувати себе та свій розум до Git.

Дрібний шрифт

(Ви можете пропустити це зараз.) У той час як ртутний і Git набагато більше схожі один на одного , ніж SVN, є є деякі концептуальні відмінності між ними, так що деякі із заяв і рекомендацій в «Subversion перевиховання» стане технічно неправильно при заміні "mercurial" на "Git":

  • У той час як внутрішній обмін відстежує і зберігає набори змін, Git внутрішньо відстежує і зберігає зміни (тобто стани вмісту дерева каталогів), як і Subversion. Але крім Subversion Git виконує злиття, переглядаючи різницю між кожною залученою гілкою відповідно та звичайним переглядом предків (справжнє 3-кратне злиття), тому результат є майже таким же, як і для меркуріального: Об'єднання набагато простіше і менше помилок -прон, ніж у СВН.
  • Хоча ви можете розгалужувати Git, клонувавши сховище (як це прийнято в меркуріалі), набагато частіше створювати нову гілку у сховищі Git. (Це тому, що гілки Git - це просто (рухаються) покажчики на версії, тоді як меркуріальні гілки - це постійні мітки, застосовані до кожної редакції. Ці постійні мітки зазвичай небажані, тому робочі потоки меркуріалу зазвичай працюють шляхом клонування повного сховища для розбіжних розробок.)

У SVN все є каталогом (але не слід обов'язково ставитися до цього як до такого)

Але я тебе перебивав. Ви говорили?

У SVN я зазвичай оформлюю репо на своїй локальній машині, яка включає всі відділення в моєму проекті, і я вибирав папку для своєї філії, яка мені цікава, і там працюю.

Якщо, маючи на увазі, ви маєте на увазі, що ви перевірили кореневу папку репозиторію SVN (або будь-яку іншу папку, що відповідає більше ніж trunkодній гілці або, наприклад, у звичайній компоновці репортажу SVN branchesпапка, що містить усі гілки без стволів), то Смію сказати, що ви, мабуть, неправильно використовували SVN (ish), або принаймні трохи зловживали тим фактом, що стовбур, гілки та теги всі складені в єдиний (хоча ієрархічний) простір імен разом з каталогами в редакції / базі даних коду.

Хоча можливо змінити паралельно кілька гілок SVN, тобто AFAIK не є тим, як SVN призначений для використання. (Хоча я не впевнений у тому, які конкретні недоліки можуть діяти так.)

У Git лише каталоги - це каталоги

Кожен клон сховища Git є самим сховищем Git: за замовчуванням він отримує повну копію історії сховища походження, включаючи всі редакції, гілки та теги. Але це збереже все, що нам подобається: Git зберігає його у базі даних, що базується на файлах, у прихованій .git/підпапці кореневої папки сховища .

Але які не приховані файли ви бачите в папці репозиторію?

Коли ви git cloneсховане, Git робить кілька речей. Приблизно:

  1. Він створює цільову папку , а в ній .git/підпапку з "базою даних"
  2. Він передає посилання (теги, гілки тощо) бази даних сховища джерел і робить їх копію в новій базі даних, надаючи їм незначно змінене ім'я, яке позначає їх як "віддалені" посилання.
  3. Він передає всі версії (тобто стану дерев файлів), на які вказують ці посилання, а також усі зміни, на які ці редакції вказують прямо чи перехідно (їхні батьки та предки), до нової бази даних та зберігає їх, так що нові віддалені посилання фактично вкажіть на щось, що доступне в новому сховищі.
  4. Він створює локальну гілку, що відстежує віддалену редакцію, відповідну гілці за замовчуванням сховища походження (зазвичай master).
  5. Він перевіряє цю місцеву філію.

Останній крок означає, що Git шукає версію, на яку вказує ця гілка, і розпаковує збережене там дерево файлів (база даних використовує деякі засоби стиснення та дедуплікації) у кореневу папку репозиторію. Ця коренева папка та всі її папки (крім спеціальної .gitпідпапки) відомі як "робоча копія" вашого сховища. Ось де ви взаємодієте зі змістом поточної перевіреної редакції / відділення. Вони просто звичайні папки та файли. Однак, для взаємодії з сховищем per se se ("база даних" версій та посилань) ви використовуєте gitкоманди.

Бачити гілки Git та взаємодіяти з гілками Git

В даний час я клоную репо і клоную конкретну гілку за допомогою gitk.

Версія, яку gitkя отримав, не може клонувати сховища. Він може лише переглядати історію репо, створювати гілки та перевіряти гілки. Крім того, немає "клонування" гілки. Ви можете клонувати лише сховища.

Ви мали на увазі клонування репо, використовуючи, git clone ...а потім, використовуючи gitk, перевірити філію?

Папка проекту містить лише вміст цієї гілки, і я не бачу всіх гілок, як у SVN, що для мене трохи заплутано.

[...]

  • Мені хотілося б знати, чи описаний я процес git є "стандартним" і наскільки правильно [...]

Так, це досить стандартно:

  • Клоніруйте сховище за допомогою git clone ...
  • Ознайомтеся з галуззю, з якою ви хочете працювати, git checkout ...або використовуючи графічний інструмент, як-отgikt

Я не можу знайти простий спосіб переглянути всі гілки в моєму локальному сховищі за допомогою GIT.

  • [...] або я пропускаю смт.

Може бути:

  • ви можете перелічити місцеві відділення git branch
  • ви можете перелічити віддалені гілки з git branch -rабо всі гілки зgit branch -a
  • ви можете використовувати gitkдля перегляду всієї історії (усі теги гілок тощо, про які знає ваше місцеве репо), посилаючись на неї

    gitk --all
    

Як паралельно працювати з декількома гілками

  • Також я хотів би знати, як керувати процесом, коли мені потрібно працювати над двома гілками одночасно, якщо, наприклад, мені потрібно зробити виправлення для master, але зберегти вміст іншої гілки.

Тут різні сценарії:

До декількох гілок потрібно застосувати нову (ще не створену) зміну

Використовуйте цей робочий процес:

  1. Створіть нову гілку cз ревізії, яка вже є в родині всіх цих гілок (наприклад, редакція, яка ввела помилку, коли зміна буде помилкою) або з версії, яка (включаючи всіх її предків) прийнятна для введення в всі ці гілки.
  2. Внесіть і внесіть зміни в цю нову гілку c.
  3. Для кожної гілки, bяка потребує змін:

    1. Перевірте b:

      git checkout b
      
    2. Об’єднайтесь cу b:

      git merge c
      
  4. Видалити відділення c:

    git branch --delete c
    

Наявні зміни потрібні в іншій галузі

(... але без інших змін, внесених до місця перебування цієї зміни)

  1. Ознайомтеся з відділенням, де потрібні зміни
  2. Вишні виберіть редакцію, яка вносить зміни, в порядку

На одній гілці aпотрібно змінити один або декілька файлів у точний стан, який вони мають у іншій гілціb

  1. Перевірити a
  2. Отримайте вміст файлу у відділенні b:

    git checkout b -- path/to/a/file.txt path/to/another/file.cpp or/even/a/complete/directory/ ...
    

    (Окрім git checkoutбез проходження шляхів, це не перейде до гілки b, звідти лише отримуйте потрібний вміст файлу. Ці файли можуть або не існуватимуть a. Якщо вони є, вони перезаписуються вмістом b.)

Працюючи над однією гілкою, ви хочете подивитися, як все відбувається на іншій гілці

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

Потім, для перегляду іншої гілки,

  • або використовувати графічні інструменти, які дозволяють переглядати вміст не перевірених в даний час редакцій (наприклад, gitkнамагаючись переключити перемикачі з "латки" на "дерево")
  • або клонуйте сховище до тимчасового каталогу та перевірте іншу гілку там
  • або використовувати git worktreeдля створення окремого робочого каталогу того ж сховища (тобто, також використовуючи базу даних у .git/каталозі вашого поточного сховища), де ви можете перевірити цю іншу гілку

Для останнього робочого процесу stashідеально.
CAD97

@ CAD97 не, якщо ви хочете продовжувати працювати над першою гілкою, паралельно дивлячись на другу для довідок . git stashдобре перенести незакінчену роботу в сторону, наприклад, переключити гілки і пізніше повернутися назад.
дас-г

1
"Ртутні робочі процеси зазвичай працюють шляхом клонування повного сховища для розбіжних розробок" - Так, я чув про це, але більшість людей, які хочуть, щоб гілки Git просто використовували закладки замість клонування всього репо. Набагато простіше.
Кевін

@Kevin Це може бути. Деякий час тому я востаннє використовував ртутний, так що, можливо, тоді було інакше. (А може, це були лише робочі потоки спільноти, якими я користувався, таким був.)
das-g

Можливо, текст Hg Init "[...], оскільки ви дійсно повинні були розгалужувати Меркурійський шлях, шляхом клонування сховищ [...]" також слід оновити в цьому відношенні.
дас-г

31

У SVN я зазвичай оформлюю репо на своїй локальній машині, яка включає всі відділення в моєму проекті, і я вибирав папку для своєї філії, яка мені цікава, і там працюю.

Якщо ви не переглянете каталог, що знаходиться вище магістралі, у Subversion зазвичай не доступні всі гілки локально. У Git весь вміст (коміти, повідомлення, гілки тощо) завжди клонується до кожної копії.

В даний час я клоную репо і клоную конкретну гілку за допомогою gitk.

Неможливо, див. Вище. Можна git checkout branch-name, але не можеш git clone something branch-name. У Subversion гілки - це папки. У Git гілки є вказівниками на коміт.

Я не можу знайти простий спосіб переглянути всі гілки в моєму локальному сховищі за допомогою GIT.

Біжи git branch. За замовчуванням він показує лише локальні відділення. Використовуйте git branch --remoteдля перегляду віддалених гілок.


4
Гм. "За замовчуванням він показує лише локальні гілки." звучить, як є інші види гілок, які не є локальними. Але ви також говорите: "У Git весь вміст (коміти, повідомлення, гілки тощо) завжди клонується до кожної копії". . Я вважаю це трохи заплутаним, бо якщо всі гілки клоновані до вашої копії, то які таємничі не локальні гілки? Можливо, занадто складно відповісти в полі для коментарів.
труба

2
@pipe Коли ви здійснюєте зміни, ви робите це, створюючи локальну комісію, яка змінює комісію, на яку вказує гілка. Якщо ви хочете, щоб інші могли отримати ці зміни, вам потрібно перенести ці зміни до віддаленого сховища. Це призводить до того, що віддалена гілка вказує на цю нову команду. Тепер усі інші можуть перетягнути ці зміни звідти, і як результат, усі нарешті отримають повну копію сховища
Frozn

9
@pipe По-перше, ви можете фактично клонувати лише гілку, використовуючи --single-branch(навіть лише кінчик --depth 1). Різниця між місцевими та віддаленими гілками, відомими git, є лише своєрідною міткою. Віддалені гілки мають префікс із назвою віддаленого джерела (часто origin). Місцеві гілки не мають цього префікса. Зрештою, дані доступні локально (якщо ви це зробили --single-branchчи щось подібне). Коли ви працюєте git checkout $branchnameз гілкою, для якої не існує локальної, а віддаленої гілки, git автоматично встановлює локальну гілку, яка "відстежує" віддалену.
Йонас Шефер

"Якщо ви не переглянете каталог вище магістралі" - Мій досвід полягає в тому, що це досить часто, оскільки це робить об'єднання набагато простішим. (Хоча ми використовуємо одну "живу" гілку замість тегів версій, тому вона зазвичай становить лише 2-3 копії коду)
Izkata

1
@Izkata "це робить об'єднання набагато простіше", чи не так?
HorusKol

3

Оскільки це позначено я сподіваюся, що мій брак знань SVN нехтується.

В даний час я клоную репо і клоную конкретну гілку за допомогою gitk.

Ви клонуєте весь віддалений сховище не лише конкретної гілки.

Репозиторій найкраще уявляти як базу даних, тому ви робите клон поточного стану віддаленої бази даних. Але після цього ви працюєте над власною копією цієї бази даних; якщо ви берете на себе зобов’язання, ви змінюєте свою локальну базу даних.

fetchКоманда використовується , щоб зберегти локальну базу даних в синхронізації з віддаленим один.

Зазвичай з цієї локальної бази ви отримуєте замовлення у відділенні, над яким працюєте. Це не що інше, як внутрішній маркер для git, з якого почалася ваша поточна робота.

Скажімо, ви працюєте над простим сховищем, де крім цього немає гілки master, ви можете заглянути в .gitпапку, щоб розкрити "магію":

Припустимо, що ваш останній вчинок (на master) був 182e8220b404437b9e43eb78149d31af79040c66, ви точно знайдете це під cat .git/refs/heads/master.

Після цього ви відгалужите нову гілку git checkout -b mybranch, ви знайдете такий самий покажчик у файлі cat .git/refs/heads/mybranch.

Гілки - це не що інше, як «покажчики». "Робочий" маркер називається a HEAD.

Якщо ви хочете знати, де ви HEADперебуваєте:

cat .git/HEADякий говорить, наприклад ref: refs/heads/mybranch, що, в свою чергу, вказує ( cat .git/refs/heads/mybranch) на хеш-коміт78a8a6eb6f82eae21b156b68d553dd143c6d3e6f

Фактичні комісії зберігаються під objectsпапкою (як власна тема).

Папка проекту містить лише вміст цієї гілки, і я не бачу всіх гілок, як у SVN, що для мене трохи заплутано.

Не плутайте їх working directoryіз "git-базою" в цілому. Як я вже говорив вище, ваш робочий каталог - це лише знімок (можливо) підмножини.

Скажімо, у вас є різні гілки, ваш робочий каталог присвячений роботі лише над цією гілкою (хоча ви можете розмістити роботу звідти в іншому місці).

Зазвичай, якщо ви хочете побачити, які галузі визначені для проекту, у вас є можливість

  • git branch для місцевих відділень
  • git branch --remote для віддалених відділень
  • git branch -a для обох

(або git branch -v)

Оскільки git - це система управління розподіленою версією, не лише можна, але й рекомендується робити різні гілки локально / віддалено.

Мій типовий робочий процес:

  • відгалуження функції відгалуження
  • відгалужувати гілку WIP (незавершене виробництво)
  • працювати як завгодно - навіть якщо ви дотримуєтесь одного рядка; це не має значення

Коли функція завершена:

  • збивати / переробляти WIPгілку (з інтерактивним ребаузингам) = зробити з цього один комітет
  • об'єднайте WIPгілку в гілку функції та запропонуйте, що (якщо ви працюєте з github, ця пропозиція називатиметься "витягнутим запитом") інтегруватися в стабільну (головну) гілку.

Крім того, я хотів би знати, як обробити процес, коли мені потрібно одночасно працювати на двох гілках у разі, якщо, наприклад, мені потрібно зробити виправлення на master, але зберегти вміст іншої гілки.

Це залежить від структури вашого проекту:

Скажіть, у вас стабільний господар. І функції розвиваються лише з тієї стабільної гілки - тому вона зазвичай стоїть за галуззю функцій. Тоді у вас буде остання фіксація для master, яка буде коренем гілки функцій.

Тоді ви взяли б на себе головну гілку і могли б вирішити, об'єднати обидві гілки разом або перезавантажити (що так би мовити, є злиття для користувачів з розвиненими потребами).

Або ви завжди можете вносити зміни на гілках (наприклад master) і перебирати їх на інші гілки.

Що таке рекомендації щодо назви, щоб зробити папки, які включають гілку, клоновану з репо в GIT, наприклад myproject-branchname

Тобі вирішувати.

Як правило, ви отримуєте назву сховищ.

Але бувають випадки, коли цього не потрібно:

наприклад, ви клонуєте о-о-мі-шш з git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh Here .oh-my-zshтут чітко названий як ціль.


2

Git clone насправді клонує все сховище, але встановлює вашу робочу директорію за замовчуванням (як правило, головним).

Ви можете бачити інші гілки, використовуючи git branchдля перегляду місцевих гілок або git branch -rдля перегляду віддалених, а потім git checkoutдля переходу до існуючої гілки або створення нового на основі поточної гілки.

Ви можете прочитати документацію на git, щоб отримати докладнішу інформацію, і Atlassian також має кілька хороших статей про неї.


0

Гілки в git та svn - це принципово різні речі.

У svn гілка (або тег) - це каталог у репо.

В git гілка (або тег) - вказівник на коміт.

За допомогою svn ви можете, якщо хочете, оформити корінь репо. Це означає, що ви маєте одразу перевірити кожну гілку та тег. Афактично це не звичайний спосіб використання svn.

Гілка git не є каталогом, тому немає "еквіваленту" перевірки кореня репо ". Існує деяка підтримка декількох працюючих дерев, тож я гадаю, що ви могли б зв'язати сценарій, щоб перевірити кожну гілку одночасно, якщо ви дійсно хотіли, але це було б досить незвично.

Крім того, у SVN є рівно одне репо. З git у кожного розробника є власне репо. Це означає, що розробники можуть працювати в режимі офлайн, але це також означає, що різні розробники можуть мати різне уявлення про те, що є у кожній галузі.

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

Гіти Git з іншого боку насправді не мають історії. Існує "рефлог", але він призначений скоріше як механізм відновлення після катастроф, ніж багаторічна історія. Зокрема, рефлог не може бути прочитаний віддалено, і він за замовчуванням відключений для голих репост.

Комітети, звичайно, мають історію, але цих історій недостатньо, щоб відповісти на питання "що було на гілці x репортажу на дату z".

Я не можу знайти простий спосіб переглянути всі гілки в моєму локальному сховищі за допомогою Git.

Ви можете перелічити всі місцеві гілки, ввівши "git гілка".

Ви можете перелічити всі гілки як локальні, так і віддалені за допомогою "git branch -a"

Також я хотів би знати, як керувати процесом, коли мені потрібно працювати над двома гілками одночасно, якщо, наприклад, мені потрібно зробити виправлення для master, але зберегти вміст іншої гілки.

Пара варіантів.

Ви можете здійснити свої зміни на "іншій гілці", переключитися на майстра, щоб зробити там свою роботу, а потім переключитися назад.

Ви також можете створити додаткове робоче дерево. Google "git-worktree" для деталей синтаксису.

Що таке рекомендації щодо назви, щоб зробити папки, які включають гілку, клоновану з репо в Git, наприклад myproject-branchname?

Я не думаю, що існує конвенція. Перевірка декількох робочих дерев одночасно є виключенням, а не правилом.


2
ця відповідь виглядає неповною, чому?
гнат
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.