From c3b3da48316b95cf5e4023f318703c8f9ac48c51 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=D0=92=D0=BE=D0=BB=D0=BE=D0=B4=D0=B8=D0=BC=D0=B8=D1=80=20?= =?utf8?q?=D0=91=D0=BE=D0=B4=D0=B5=D0=BD=D1=87=D1=83=D0=BA?= Date: Tue, 30 Oct 2012 01:47:55 +0200 Subject: [PATCH] =?utf8?q?=D0=BF=D0=BE=D0=B2=D0=BD=D1=96=D1=81=D1=82=D1=8E?= =?utf8?q?=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BA=D0=BB=D0=B0=D0=B4=D0=B5=D0=BD?= =?utf8?q?=D0=BE=20uk/grandmaster.txt?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- uk/grandmaster.txt | 364 ++++++++++++++++++++++++++--------------------------- 1 file changed, 182 insertions(+), 182 deletions(-) rewrite uk/grandmaster.txt (63%) diff --git a/uk/grandmaster.txt b/uk/grandmaster.txt dissimilarity index 63% index 4ad48f3..0bb9a66 100644 --- a/uk/grandmaster.txt +++ b/uk/grandmaster.txt @@ -1,182 +1,182 @@ -== Гросмейстерство Git == - -Тепер ви вже повинні вміти орієнтуватися в сторінках *git help* і розуміти майже все. Однак точний вибір команди, необхідної для вирішення конкретної проблеми, може бути виснажливим. Можливо, я збережу вам трохи часу: нижче наведені рецепти, які знадобилися мені в минулому. - -=== Релізи вихідних кодів === - -У моїх проектах Git управляє в точності тими файлами, які я збираюся архівувати і пускати в реліз. Щоб створити тарбол з вихідними кодами, я виконую: - - $ git archive --format=tar --prefix=proj-1.2.3/ HEAD - -=== Комміт змін === - -У деяких проектах може бути трудомістким повідомляти Git про кожне додавання, видаленні та перейменування файлу. Замість цього ви можете виконати команди - - $ git add . - $ git add -u - -Git прогляне файли в поточному каталозі і сам подбає про деталі. Замість другої команди add, виконайте `git commit -a`, якщо ви збираєтеся відразу зробити комміт. Дивіться * git help ignore *, щоб дізнатися як вказати файли, які повинні ігноруватися. - -Ви можете виконати все це одним махом: - - $ git ls-files -d -m -o -z | xargs -0 git update-index --add --remove - -Опції *-z* і *-0* запобігають невірну обробку файлових імен, що містять спеціальні символи. Оскільки ця команда додає ігноровані файли, ви можливо захочете використовувати опції `-x` або `-X`. - -=== Мій комміт занадто великий === - -Ви нехтували коммітамі занадто довго? Затято писали код і згадали про управління вихідними кодами тільки зараз? Внесли ряд незв'язаних змін, тому що це ваш стиль? - -Немає причин для занепокоєння. Виконайте - - $ git add -p - -Для кожної зробленої вами правки Git покаже змінену ділянку коду і запитає, чи повинна ця зміна потрапити в наступний комміт. Відповідайте "y" (так) або "n" (ні). У вас є й інші варіанти, наприклад відкласти вибір; введіть "?" Щоб дізнатися більше. - -Коли закінчите, виконайте - - $ git commit - -для внесення саме тих правок, що ви вибрали ('буферизованих' змін). Переконайтеся, що ви не вказали опцію *-a*, інакше Git закоммітить всі правки. - -Що робити, якщо ви змінили безліч файлів в багатьох місцях? Перевірка кожної окремої зміни стає обтяжливою рутиною. У цьому випадку використовуйте *git add -i*. Її інтерфейс не такий простий, але більш гнучкий. У декілька натискань можна додати або прибрати з буфера кілька файлів одночасно, або переглянути і вибрати зміни лише в окремих файлах. Як варіант, запустіть *git commit \--interactive*, яка автоматично зробить комміт коли ви закінчите. - -=== Індекс - буферна зона Git === - -До цих пір ми уникали знаменитого 'індексу' Git, але тепер ми повинні розглянути його, для пояснення вищесказаного. Індекс це тимчасовий буфер. Git рідко переміщує дані безпосередньо між вашим проектом і його історією. Замість цього Git спочатку записує дані в індекс, а вже потім копіює їх з індексу за місцем призначення. - -Наприклад, *commit -a* насправді двоетапний процес. Спочатку зліпок поточного стану кожного з відстежуваних файлів поміщається в індекс. Потім зліпок, що знаходиться в індексі, записується в історію. Комміт без опції *-a* виконує тільки другий крок, і має сенс тільки після виконання команд, що змінюють індекс, таких як *git add*. - -Зазвичай ми можемо не звертати уваги на індекс і робити вигляд, що взаємодіємо безпосередньо з історією. Але в даному випадку ми хочемо більш тонкого контролю, тому управляємо індексом. Ми поміщаємо зліпок деяких (але не всіх) наших змін в індекс, після чого остаточно записуємо цей акуратно сформований зліпок. - -=== Не теряй «головы» === - -Тег HEAD (англ. «голова», прим. пер.) — как курсор, который обычно указывает на последний коммит, продвигаясь с каждым новым коммитом. Некоторые команды Git позволяют перемещать этот курсор. Например, - - $ git reset HEAD~3 - -переместит HEAD на три коммита назад. Теперь все команды Git будут работать так, как будто вы не делали последних трех коммитов, хотя файлы останутся в текущем состоянии. В справке описано несколько способов использования этого приема. - -Но как вернуться назад в будущее? Ведь предыдущие коммиты о нем ничего не знают. - -Если у вас есть SHA1 изначальной «головы», то: - - $ git reset 1b6d - -Но допустим, вы его не записывали. Не беспокойтесь: для комнад такого рода Git сохраняет оригинальную «голову» как тег под названием ORIG_HEAD, и вы можете вернуться надежно и безопасно: - - $ git reset ORIG_HEAD - -=== Охота за «головами» === - -Предположим ORIG_HEAD недостаточно. К примеру, вы только что осознали, что допустили громадную ошибку, и вам нужно вернуться к древнему коммиту в давно забытой ветке. - -По умолчанию Git хранит коммиты не меньше двух недель, даже если вы приказали уничтожить содержащую их ветку. Проблема в нахождении соответствующего хеша. Вы можете просмотреть все значения хешей в .git/objects и методом проб и ошибок найти нужный. Но есть путь значительно легче. - -Git записывает каждый подсчитанный им хеш коммита в .git/logs. В подкатлоге refs содержится полная история активности на всех ветках, а файл HEAD содержит каждое значение хеша, которое когда-либо принимал HEAD. Последнее можно использовать чтобы найти хеши коммитов на случайно обрубленных ветках. - -Команда reflog предоставляет удобный интерфейс работы с этими журналами. Используйте - - $ git reflog - -Вместо копирования хешей из reflog, попробуйте - - $ git checkout "@{10 minutes ago}" # 10 минут назад, прим. пер. - -Или сделайте чекаут пятого с конца из посещенных коммитов с помощью - - $ git checkout "@{5}" - -Смотрите раздел «Specifying Revisions» в *git help rev-parse* для дополнительной информации. - -Вы можете захотеть удлинить отсрочку для коммитов, обреченных на удаление. Например, - - $ git config gc.pruneexpire "30 days" - -означает, что удаляемые коммиты будут окончательно исчезать только по прошествии 30 дней и после запуска *git gc*. - -Также вы можете захотеть отключить автоматический вызов *git gc*: - - $ git config gc.auto 0 - -В этом случае коммиты будут удаляться только когда вы будете запускать *git gc* вручную. - -=== Git как основа === - -Дизайн Git, в истинном духе UNIX, позволяет легко использовать его как низкоуровневый компонент других программ: графических и веб-интерфейсов; альтернативных интерфейсов командной строки; инструментов управления патчами; средств импорта или конвертации, и так далее. Многие команды Git на самом деле — скрипты, стоящие на плечах гигантов. Небольшой доработкой вы можете переделать Git на свой вкус. - -Простейший трюк — использование алиасов Git для сокращения часто используемых команд: - - $ git config --global alias.co checkout - $ git config --global --get-regexp alias # отображает текущие алиасы - alias.co checkout - $ git co foo # то-же, что и «git checkout foo» - -Другой пример: можно выводить текущую ветку в приглашении командной строки или заголовке окна терминала. Запуск - - $ git symbolic-ref HEAD - -выводит название текущей ветки. На практике вы скорее всего захотите убрать «refs/heads/» и сообщения об ошибках: - - $ git symbolic-ref HEAD 2> /dev/null | cut -b 12- - -Подкаталог +contrib+ это целая сокровищница инструментов, построенных на Git. Со временем некоторые из них могут становиться официальными командами. В Debian и Ubuntu этот каталог находится в +/usr/share/doc/git-core/contrib+. - -Один популярный инструмент из этого каталога — +workdir/git-new-workdir+. Этот скрипт создает с помощью символических ссылок новый рабочий каталог, имеющий общую историю с оригинальным хранилищем: - - $ git-new-workdir существующее/хранилище новый/каталог - -Новый каталог и файлы в нем можно воспринимать как клон, с той разницей, что два дерева автоматически остаются синхронизированными ввиду общей истории. Нет необходимости в merge, push и pull. - -=== Рискованные трюки === - -Нынешний Git делает случайное уничтожение данных очень сложным. -Но если вы знаете, что делаете, вы можете обойти защиту для распространенных команд. - -*Checkout*: Наличие незакоммиченных изменений прерывает выполнение checkout. Чтобы перейти к нужному коммиту, даже уничтожив свои изменения, используйте «принуждающий» (force, прим. пер.) флаг *-f*: - - $ git checkout -f HEAD^ - -С другой стороны, если вы укажете checkout конкретные пути, проверки на безопасность не будет: указанные файлы молча перезапишутся. Будьте осторожны при таком использовании checkout. - -*Reset*: сброс также прерывается при наличии незакоммиченных изменений. Чтобы заставить его сработать, запустите - - $ git reset --hard 1b6d - -*Branch*: Удаление ветки прервётся, если оно привело бы к потере изменений. Для принудительного удаления введите - - $ git branch -D мертвая_ветка # вместо -d - -Аналогично, попытка перезаписи ветки путем перемещения будет прервана, если может привести к потере данных. Для принудительного перемещений ветки введите - - $ git branch -M источник цель # вместо -m - -В отличии от checkout и reset, эти две команды дают отсрочку в удалении данных. Изменения остаются в каталоге .git и могут быть возвращены восстановлением нужного хеша из .git/logs (смотрите выше раздел «Охота за „головами“»). По умолчанию они будут храниться по крайней мере две недели. - -*Clean*: Некоторые команды могут не сработать из опасений повредить неотслеживаемые файлы. Если вы уверены, что все неотслеживаемые файлы и каталоги не нужны, то безжалостно удаляйте их командой - - $ git clean -f -d - -В следующий раз эта досадная команда сработает! - -=== Предотвращаем плохие коммиты === - -Глупые ошибки загрязняют мои хранилища. Самое ужасное это проблема недостающих файлов, вызванная забытым *git add*. - -Примеры менее серьезных проступков: завершающие пробелы и неразрешённые конфликты слияния. Несмотря на безвредность, я не хотел бы, чтобы это появлялось в публичных записях. - -Если бы я только поставил защиту от дурака, используя _хук_, который бы предупреждал меня об этих проблемах: - - $ cd .git/hooks - $ cp pre-commit.sample pre-commit # В старых версиях Git: chmod +x pre-commit - -Теперь Git отменит коммит, если обнаружит лишние пробелы или неразрешенные конфликты. - -Для этого руководства я в конце концов добавил следующее в начало хука *pre-commit*, чтобы защититься от своей рассеянности: - -if git ls-files -o | grep '\.txt$'; then - echo ПРЕРВАНО! Неотслеживаемые .txt файлы. - exit 1 -fi - -Хуки поддерживаются несколькими различными операциями Git, смотрите *git help hooks*. Мы использовали пример хука *post-update* раньше, при обсуждении использования Git через http. Он запускался при каждом перемещении «головы». Пример скрипта *post-update* обновляет файлы, которые нужны Git для связи через не считающиеся с ним средства сообщения, такие как HTTP. +== Гросмейстерство Git == + +Тепер ви вже повинні вміти орієнтуватися в сторінках *git help* і розуміти майже все. Однак точний вибір команди, необхідної для вирішення конкретної проблеми, може бути виснажливим. Можливо, я збережу вам трохи часу: нижче наведені рецепти, які знадобилися мені в минулому. + +=== Релізи вихідних кодів === + +У моїх проектах Git управляє в точності тими файлами, які я збираюся архівувати і пускати в реліз. Щоб створити тарбол з вихідними кодами, я виконую: + + $ git archive --format=tar --prefix=proj-1.2.3/ HEAD + +=== Комміт змін === + +У деяких проектах може бути трудомістким повідомляти Git про кожне додавання, видаленні та перейменування файлу. Замість цього ви можете виконати команди + + $ git add . + $ git add -u + +Git прогляне файли в поточному каталозі і сам подбає про деталі. Замість другої команди add, виконайте `git commit -a`, якщо ви збираєтеся відразу зробити комміт. Дивіться * git help ignore *, щоб дізнатися як вказати файли, які повинні ігноруватися. + +Ви можете виконати все це одним махом: + + $ git ls-files -d -m -o -z | xargs -0 git update-index --add --remove + +Опції *-z* і *-0* запобігають невірну обробку файлових імен, що містять спеціальні символи. Оскільки ця команда додає ігноровані файли, ви можливо захочете використовувати опції `-x` або `-X`. + +=== Мій комміт занадто великий === + +Ви нехтували коммітамі занадто довго? Затято писали код і згадали про управління вихідними кодами тільки зараз? Внесли ряд незв'язаних змін, тому що це ваш стиль? + +Немає причин для занепокоєння. Виконайте + + $ git add -p + +Для кожної зробленої вами правки Git покаже змінену ділянку коду і запитає, чи повинна ця зміна потрапити в наступний комміт. Відповідайте "y" (так) або "n" (ні). У вас є й інші варіанти, наприклад відкласти вибір; введіть "?" Щоб дізнатися більше. + +Коли закінчите, виконайте + + $ git commit + +для внесення саме тих правок, що ви вибрали ('буферизованих' змін). Переконайтеся, що ви не вказали опцію *-a*, інакше Git закоммітить всі правки. + +Що робити, якщо ви змінили безліч файлів в багатьох місцях? Перевірка кожної окремої зміни стає обтяжливою рутиною. У цьому випадку використовуйте *git add -i*. Її інтерфейс не такий простий, але більш гнучкий. У декілька натискань можна додати або прибрати з буфера кілька файлів одночасно, або переглянути і вибрати зміни лише в окремих файлах. Як варіант, запустіть *git commit \--interactive*, яка автоматично зробить комміт коли ви закінчите. + +=== Індекс - буферна зона Git === + +До цих пір ми уникали знаменитого 'індексу' Git, але тепер ми повинні розглянути його, для пояснення вищесказаного. Індекс це тимчасовий буфер. Git рідко переміщує дані безпосередньо між вашим проектом і його історією. Замість цього Git спочатку записує дані в індекс, а вже потім копіює їх з індексу за місцем призначення. + +Наприклад, *commit -a* насправді двоетапний процес. Спочатку зліпок поточного стану кожного з відстежуваних файлів поміщається в індекс. Потім зліпок, що знаходиться в індексі, записується в історію. Комміт без опції *-a* виконує тільки другий крок, і має сенс тільки після виконання команд, що змінюють індекс, таких як *git add*. + +Зазвичай ми можемо не звертати уваги на індекс і робити вигляд, що взаємодіємо безпосередньо з історією. Але в даному випадку ми хочемо більш тонкого контролю, тому управляємо індексом. Ми поміщаємо зліпок деяких (але не всіх) наших змін в індекс, після чого остаточно записуємо цей акуратно сформований зліпок. + +=== Не втрачай "голови" === + +Тег HEAD подібний курсору, який зазвичай вказує на останній комміт, просуваючись з кожним новим коммітом. Деякі команди Git дозволяють переміщати цей курсор. Наприклад, + + $ git reset HEAD~3 + +перемістить HEAD на три комміти назад. Тепер всі команди Git будуть працювати так, ніби ви не робили останніх трьох коммітів, хоча файли залишаться в поточному стані. У довідці описано кілька способів використання цього прийому. + +Але як повернутися назад у майбутнє? Адже попередні комміти про нього нічого не знають. + +Якщо у вас є SHA1 вихідної "голови", то: + + $ git reset 1b6d + +Але припустимо, ви його не записували. Не турбуйтеся: для комнад такого роду Git зберігає оригінальну "голову" як тег під назвою ORIG_HEAD, і ви можете повернутися надійно і безпечно: + + $ git reset ORIG_HEAD + +=== Полювання за "головами" === + +Припустимо ORIG_HEAD недостатньо. Приміром, ви тільки що усвідомили, що допустили величезну помилку, і вам потрібно повернутися до давнього комміту в давно забутій гілці. + +За замовчуванням Git зберігає комміти не менше двох тижнів, навіть якщо ви наказали знищити гілку, що їх містить. Проблема в знаходженні відповідного хешу. Ви можете проглянути всі значення хешів в `.git/objects` і методом проб та помилок знайти потрібний. Але є шлях значно легший. + +Git записує кожен підрахований ним хеш комміта в `.git/logs`. У підкаталозі `refs` міститься повна історія активності на всіх гілках, а файл `HEAD` містить кожне значення хешу, яке коли-небудь приймав HEAD. Останній можна використовувати щоб ​​знайти хеши коммітів на випадково обрубаних гілках. + +Команда reflog надає зручний інтерфейс роботи з цими журналами. Використовуйте + + $ git reflog + +Замість копіювання хешів з reflog, спробуйте + + $ git checkout "@{10 minutes ago}" + +Чи зробіть чекаут п'ятого з кінця з відвіданих коммітів за допомогою + + $ git checkout "@{5}" + +Дивіться розділ ``Specifying Revisions'' в *git help rev-parse* для додаткової інформації. + +Ви можете захотіти подовжити відстрочку для коммітів, приречених на видалення. Наприклад, + + $ git config gc.pruneexpire "30 days" + +означає, що комміти, які видаляються, будуть остаточно зникати тільки після 30 днів і після запуску *git gc*. + +Також ви можете захотіти відключити автоматичний виклик *git gc*: + + $ git config gc.auto 0 + +У цьому випадку комміти будуть видалятися тільки коли ви будете запускати *git gc* вручну. + +=== Git як основа === + +Дизайн Git, в істинному дусі UNIX, дозволяє легко використовувати його як низькорівневий компонент інших програм: графічних та веб-інтерфейсів; альтернативних інтерфейсів командного рядка; інструментів управління патчами; засобів імпорту або конвертації, і так далі. Багато команд Git насправді - скрипти, які стоять на плечах гігантів. Невеликим доопрацюванням ви можете переробити Git на свій смак. + +Найпростіший трюк — використання аліасів Git для скорочення часто використовуваних команд: + + $ git config --global alias.co checkout + $ git config --global --get-regexp alias # відображає поточні аліаси + alias.co checkout + $ git co foo # те ж саме, що і 'git checkout foo' + +Інший приклад: можна виводити поточну гілку в запрошенні командного рядка або заголовку вікна терміналу. Запуск + + $ git symbolic-ref HEAD + +виводить назву поточної гілки. На практиці ви швидше за все захочете прибрати "refs/heads/" і повідомлення про помилки: + + $ git symbolic-ref HEAD 2> /dev/null | cut -b 12- + +Підкаталог +contrib+ — це ціла скарбниця інструментів, побудованих на Git. З часом деякі з них можуть ставати офіційними командами. В Debian та Ubuntu цей каталог знаходиться у +/usr/share/doc/git-core/contrib+. + +Один популярний інструмент з цього каталогу — +workdir/git-new-workdir+. Цей скрипт створює за допомогою символічних посилань новий робочий каталог, який має спільну історію з оригінальним сховищем: + + $ git-new-workdir існуюче/сховище новий/каталог + +Новий каталог і файли в ньому можна сприймати як клон, з тією різницею, що два дерева автоматично залишаються синхронізованими зважаючи на спільну історію. Немає необхідності в merge, push і pull. + +=== Ризиковані трюки === + +Нинішній Git робить випадкове знищення даних дуже складним. +Але якщо ви знаєте, що робите, ви можете обійти захист для розповсюджених команд. + +*Checkout*: Наявність незакомміченних змін перериває виконання checkout. Щоб перейти до потрібного комміту, навіть знищивши свої зміни, використовуйте прапор змушування (force) *-f*: + + $ git checkout -f HEAD^ + +З іншої сторони, якщо ви вкажете checkout конкретні шляхи, перевірки на безпеку не буде: вказані файли мовчки перезапишуть. Будьте обережні при такому використанні checkout. + +*Reset*: скидання також переривається при наявності незакомміченних змін. Щоб змусити його спрацювати, запустіть + + $ git reset --hard 1b6d + +*Branch*: Видалення гілки припиниться, якщо воно призвело б до втрати змін. Для примусового видалення введіть + + $ git branch -D мертва_гілка # замість -d + +Аналогічно, спроба перезапису гілки шляхом переміщення буде перервана, якщо може призвести до втрати даних. Для примусового переміщення гілки введіть + + $ git branch -M джерело ціль # замість -m + +У відмінності від checkout і reset, ці дві команди дають відстрочку у видаленні даних. Зміни залишаються в каталозі.git і можуть бути повернуті відновленням потрібного хешу з `.git/logs` (дивіться вище розділ "Полювання за головами"). За замовчуванням вони будуть зберігатися принаймні два тижні. + +*Clean*: Деякі команди можуть не спрацювати через побоювання пошкодити невідслідковувані файли. Якщо ви впевнені, що все невідслідковувані файли і каталоги не потрібні, то безжально видаляйте їх командою + + $ git clean -f -d + +Наступного разу ця прикра команда спрацює! + +=== Запобігаємо поганим коммітам === + +Дурні помилки забруднюють мої сховища. Найжахливіше це проблема відсутніх файлів, викликана забутим *git add*. + +Приклади менш серйозних проступків: завершальні пропуски і невирішені конфлікти злиття. Незважаючи на нешкідливість, я не хотів би, щоб це з'являлося в публічних записах. + +Якби я тільки поставив захист від дурня, використовуючи _хук_, який би попереджав мене про ці проблеми: + + $ cd .git/hooks + $ cp pre-commit.sample pre-commit # В старих версіях Git: chmod +x pre-commit + +Тепер Git скасує комміт, якщо виявить зайві пробіли або невирішені конфлікти. + +Для цього керівництва я в кінці кінців додав наступне в початок хука *pre-commit*, щоб захиститися від своєї неуважності: + +if git ls-files -o | grep '\.txt$'; then + echo ПЕРЕРВАНО! Невідслідковувані .txt файли. + exit 1 +fi + +Хукі підтримуються кількома різними операціями Git, дивіться *git help hooks*. Ми використовували приклад хука *post-update* раніше, при обговоренні використання Git через http. Він запускався при кожному переміщенні голови. Простий скрипт post-update оновлює файли, які потрібні Git для зв'язку через засоби повідомлення такі як HTTP. -- 2.11.4.GIT