Примітка: одна з найбільших різниць між Git та Mercurial - явна наявність індексу або області проміжного етапу .
Від Mercurial для користувача Git :
Git - єдиний DistributedSCM, який викриває поняття індексу або області проміжного етапу. Інші можуть реалізувати та приховати це, але ні в якому іншому випадку користувач не знає про це і не повинен з цим мати справу.
Грубим еквівалентом Mercurial є той DirState
, який контролює інформацію про стан робочої копії для визначення файлів, які будуть включені до наступного коміту. Але в будь-якому випадку цей файл обробляється автоматично.
Крім того, можна бути більш вибірковим під час коміту, вказавши файли, які ви хочете зробити в командному рядку, або використовуючи RecordExtension
.
Якщо вам було незручно мати справу з індексом, ви переходите на краще ;-)
Фокус у тому, що вам дійсно потрібно зрозуміти індекс, щоб повністю використовувати Git. Як нам тоді нагадує ця стаття від травня 2006 р. (І це все ще вірно зараз):
"Якщо ви заперечуєте Індекс, ви дійсно заперечуєте сам git".
Тепер ця стаття містить багато команд, які тепер простіші у використанні (тому не варто надто покладатися на її зміст;)), але загальна ідея залишається:
Ви працюєте над новою функцією і починаєте вносити незначні зміни у файл.
# working, add a few lines
$ git add myFile
# working, another minor modification
$ git add myFile
На цьому етапі ваш наступний коміт внесе 2 незначні зміни в поточну гілку
# working, making major modification for the new features
# ... damn! I cannot commit all this in the current branch: nothing would work
$ git commit
На даний момент реєструються лише зміни, додані до області індексації (індексу), а не основні зміни, видимі на даний момент у вашому робочому каталозі.
$ git branch newFeature_Branch
$ git add myFile
Наступний коміт зафіксує всі інші основні зміни в новій гілці 'newFrature_Branch'.
Тепер інтерактивне додавання або навіть розділення коміту - це функції, доступні в Mercurial за допомогою команди ' hg record
' або інших розширень: вам потрібно буде встановити RecordExtension
або CrecordExtension
.
Але це не є частиною звичайного робочого процесу для Mercurial.
Git розглядає коміт як серію " змін вмісту файлу " і дозволяє додавати ці зміни по черзі.
Вам слід вивчити цю функцію та її наслідки. Більша частина потужності Git (наприклад, можливість легко відновити злиття (або розділити проблему на дві частини, або скасувати коміт) , на відміну від Mercurial ) походить від цієї парадигми "вмісту файлу".
tonfa (у профілі: "Hg dev, pythonist": цифри ...) вписався, у коментарях:
В індексі немає нічого принципово "git-ish", hg міг би використовувати індекс, якщо він вважався цінним, фактично mq
або shelve
вже робить частину цього.
О, малюк. Ось ми знову.
По-перше, я тут не для того, щоб один інструмент виглядав краще, ніж інший. Я вважаю Hg чудовим, дуже інтуїтивно зрозумілим, з хорошою підтримкою (особливо у Windows, моїй основній платформі, хоча я працюю також на Linux та Solaris8 або 10).
Індекс насправді є фронтом і центром у тому, як Лінус Торвальдс працює з VCS :
Git використовував явні оновлення індексу з 1-го дня, навіть до того, як здійснив перше злиття. Це просто, як я завжди працював. У мене, як правило, брудні дерева з випадковим патчем у моєму дереві, який я не хочу робити, оскільки це просто оновлення Makefile для наступної версії
Тепер комбінація індексу (що не є поняттям, яке можна побачити лише в Git) і парадигма "content is king" робить його досить унікальним і "git-ish" :
git - це інструмент відстеження вмісту , і ім'я файлу не має значення, якщо воно не пов'язане з його вмістом. Отже, єдиною розумною поведінкою git add ім'я файлу є додавання вмісту файлу, а також його імені до індексу.
Примітка: тут "вміст" визначається таким чином :
Індекс Git в основному визначається як
- достатньо, щоб містити загальний " вміст " дерева (і це включає всі метадані: ім'я файлу, режим і вміст файлу - це всі частини "вмісту", і всі вони самі по собі безглузді! )
- додаткову "статистичну" інформацію, яка дозволяє зробити очевидну та тривіальну (але надзвичайно важливу!) оптимізацію порівняння файлової системи.
Таким чином , ви дійсно повинні побачити індекс , як бути змістом .
Вміст не є "ім'ям файлу" або "вмістом файлу" як окремі частини. Ви насправді не можете розділити ці два .
Назви файлів самі по собі не мають сенсу (вони також повинні мати вміст файлу), а вміст файлів сам по собі також безглуздий (ви повинні знати, як його отримати).
Я намагаюся сказати, що git принципово не дозволяє бачити ім'я файлу без його вмісту. Усе поняття божевільне і не дійсне. Це не має відношення до "реальності".
З часто заданих питань основними перевагами є:
- виконувати з тонкою деталізацією
- допоможе вам зберегти незавершену модифікацію у вашому дереві протягом досить тривалого часу
- виконайте кілька невеликих кроків для одного коміту, перевіряючи те, що ви робили
git diff
, і перевіряючи кожен невеликий крок за допомогою git add
або git add -u
.
- дозволяє відмінне управління конфліктів злиття:
git diff --base
, git diff --ours
, git diff --theirs
.
- дозволяє
git commit --amend
змінювати лише повідомлення журналу, якщо індекс тим часом не був змінений
Я особисто вважаю, що така поведінка не повинна бути за замовчуванням, ви хочете, щоб люди виконували щось тестоване або принаймні скомпільоване
Хоча ви в цілому праві (щодо "перевіреної або складеної" частини), спосіб, яким Git дозволяє вам розгалужуватись та зливати (збирати вишні або перебазувати), дозволяє вам робити коміти так часто, як ви хочете, у тимчасовій приватній гілці (лише до віддаленого сховища "резервного копіювання"), одночасно виконуючи ці "потворні коміти" у загальнодоступній гілці з усіма правильними тестами.