|
| 1 | +== Базові операції == |
| 2 | + |
| 3 | +Перш ніж занурюватися в нетрі численних команд Git, спробуйте скористатися наведеними нижче простими прикладами, щоб трохи освоїтися. Кожен із них корисний, незважаючи на свою простоту. Насправді перші місяці використання Git я не виходив за рамки матеріалу цього розділу. |
| 4 | + |
| 5 | +=== Збереження стану === |
| 6 | + |
| 7 | +Збираєтеся спробувати внести якісь радикальні зміни? Попередньо створіть знімок всіх файлів у поточному каталозі за допомогою команд |
| 8 | + |
| 9 | + $ git init |
| 10 | + $ git add . |
| 11 | + $ git commit -m "Моя перша резервна копія" |
| 12 | + |
| 13 | +Тепер, якщо нові правки все зіпсували, можна відновити початкову версію: |
| 14 | + |
| 15 | + $ git reset --hard |
| 16 | + |
| 17 | +Щоб зберегти стан знову: |
| 18 | + |
| 19 | + $ git commit -a -m "Друга резервна копія" |
| 20 | + |
| 21 | +=== Додавання, видалення, перейменування === |
| 22 | + |
| 23 | +Наведений вище приклад відстежує лише ті файли, які існували при першому запуску *git add*. Якщо ви створили нові файли або підкаталоги, доведеться сказати Git'у: |
| 24 | + |
| 25 | + $ git add readme.txt Documentation |
| 26 | + |
| 27 | +Аналогічно, якщо хочете, щоб Git забув про деякі файли: |
| 28 | + |
| 29 | + $ git rm kludge.h obsolete.c |
| 30 | + $ git rm -r incriminating/evidence/ |
| 31 | + |
| 32 | +Git видалить ці файли, якщо ви не видалили їх самі. |
| 33 | + |
| 34 | +Перейменування файлу - це те ж саме, що й видалення старого імені та додавання нового. Для цього є *git mv*, яка має той же синтаксис, що і команда *mv*. наприклад: |
| 35 | + |
| 36 | + $ git mv bug.c feature.c |
| 37 | + |
| 38 | +=== Розширені скасування/повернення === |
| 39 | + |
| 40 | +Іноді просто хочеться повернутися назад і забути всі зміни до певного моменту, тому що всі вони були неправильними. У такому випадку |
| 41 | + |
| 42 | + $ git log |
| 43 | + |
| 44 | +покаже список останніх коммітов і їх хеші SHA1: |
| 45 | + |
| 46 | +---------------------------------- |
| 47 | +commit 766f9881690d240ba334153047649b8b8f11c664 |
| 48 | +Author: Bob <bob@example.com> |
| 49 | +Date: Tue Mar 14 01:59:26 2000 -0800 |
| 50 | + |
| 51 | + Замінив printf() на write(). |
| 52 | + |
| 53 | +commit 82f5ea346a2e651544956a8653c0f58dc151275c |
| 54 | +Author: Alice <alice@example.com> |
| 55 | +Date: Thu Jan 1 00:00:00 1970 +0000 |
| 56 | + |
| 57 | + Початковий комміт. |
| 58 | +---------------------------------- |
| 59 | + |
| 60 | +Для вказівки комміта достатньо перших декількох символів його хешу, але можете скопіювати і весь хеш. Наберіть: |
| 61 | + |
| 62 | + $ git reset --hard 766f |
| 63 | + |
| 64 | +для відновлення стану до зазначеного комміта і видалення всіх наступних безповоротно. |
| 65 | + |
| 66 | +Можливо, іншим разом ви захочете швидко перескочити до старого стану. У цьому випадку наберіть |
| 67 | + |
| 68 | + $ git checkout 82f5 |
| 69 | + |
| 70 | +Ця команда перенесе вас назад у часі, зберігши при цьому більш нові комміти. Однак, як і у фантастичних фільмах про подорожі в часі, якщо тепер ви відредагуєте і закоммітите код, то потрапите в альтернативну реальність, тому що ваші дії відрізняються від тих, що були минулого разу. |
| 71 | + |
| 72 | +Ця альтернативна реальність називається «гілкою» і <<branch,трохи пізніше ми поговоримо про це докладніше>>. А зараз просто запам'ятайте, що команда |
| 73 | + |
| 74 | + $ git checkout master |
| 75 | + |
| 76 | +поверне вас назад у теперішнє. Крім того, щоб не отримувати попереджень від Git, завжди робіть commit або скидайте зміни перед запуском checkout. |
| 77 | + |
| 78 | +Ще раз скористаємося аналогією з комп'ютерними іграми: |
| 79 | + |
| 80 | +- *git reset --hard*: завантажує раніше збережену гру і видаляє всі версії, збережені після тількищо завантаженої. |
| 81 | + |
| 82 | +- *git checkout*: завантажує стару гру, але якщо ви продовжуєте грати, стан гри буде відрізнятися від більш нових збережень, які ви зробили в перший раз. Будь-яка гра, яку ви тепер зберігаєте, потрапляє в окрему гілку, що представляє альтернативну реальність, в яку ви потрапили. <<branch,Ми обговоримо це пізніше>>. |
| 83 | + |
| 84 | +Можна також відновити тільки певні файли і підкаталоги, перерахувавши їх імена після команди: |
| 85 | + |
| 86 | + $ git checkout 82f5 якийсь.файл інший.файл |
| 87 | + |
| 88 | +Будьте уважні: така форма *checkout* може мовчки перезаписати файли. Щоб уникнути неприємних несподіванок, виконуйте commit перед checkout, особливо якщо ви тільки вивчаєте Git. Взагалі, якщо ви не впевнені у якісь операції, чи то команда Git чи ні, виконайте попередньо *git commit -a*. |
| 89 | + |
| 90 | +Не любите копіювати і вставляти хеші? Використовуйте |
| 91 | + |
| 92 | + $ git checkout :/"Моя перша р" |
| 93 | + |
| 94 | +для переходу на комміт, опис якого починається з наведеного рядка. |
| 95 | + |
| 96 | +Можна також запитати 5-й з кінця збережений стан: |
| 97 | + |
| 98 | + $ git checkout master~5 |
| 99 | + |
| 100 | +=== Відкати === |
| 101 | + |
| 102 | +У залі суду пункти протоколу можуть викреслювати прямо під час слухання. Подібним чином і ви можете вибирати комміти для скасування. |
| 103 | + |
| 104 | + $ git commit -a |
| 105 | + $ git revert 1b6d |
| 106 | + |
| 107 | +скасує комміт із заданим хешем. Відкат буде збережений у вигляді нового комміта. Можете запустити *git log*, щоб переконатися в цьому. |
| 108 | + |
| 109 | +=== Создание списка изменений === |
| 110 | + |
| 111 | +Некоторым проектам нужен http://en.wikipedia.org/wiki/Changelog[список изменений] (changelog, прим. пер.). Создайте его такой командой: |
| 112 | + |
| 113 | + $ git log > ChangeLog |
| 114 | + |
| 115 | +=== Скачивание файлов === |
| 116 | + |
| 117 | +Получить копию проекта под управлением Git можно, набрав |
| 118 | + |
| 119 | + $ git clone git://сервер/путь/до/файлов |
| 120 | + |
| 121 | +Например, чтобы получить все файлы, которые я использовал для создания этого документа, |
| 122 | + |
| 123 | + $ git clone git://git.or.cz/gitmagic.git |
| 124 | + |
| 125 | +Позже мы поговорим о команде *clone* подробнее. |
| 126 | + |
| 127 | +=== Держа руку на пульсе === |
| 128 | + |
| 129 | +Если вы уже загрузили копию проекта с помощью *git clone*, можете обновить ее до последней версии, используя |
| 130 | + |
| 131 | + $ git pull |
| 132 | + |
| 133 | +=== Безотлагательная публикация === |
| 134 | + |
| 135 | +Допустим, вы написали скрипт, которым хотите поделиться с другими. Можно просто предложить им скачивать его с вашего компьютера, но если они будут делать это когда вы дорабатываете его или добавляете экспериментальную функциональность, у них могут возникнуть проблемы. Очевидно, поэтому и существуют циклы разработки. Разработчики могут постоянно работать над проектом, но общедоступным они делают свой код только после того, как приведут его в приличный вид. |
| 136 | + |
| 137 | +Чтобы сделать это с помощью Git, выполните в каталоге, где лежит ваш скрипт, |
| 138 | + |
| 139 | + $ git init |
| 140 | + $ git add . |
| 141 | + $ git commit -m "Первый релиз" |
| 142 | + |
| 143 | +Затем скажите вашим пользователям запустить |
| 144 | + |
| 145 | + $ git clone ваш.компьютер:/путь/до/скрипта |
| 146 | + |
| 147 | +чтобы загрузить ваш скрипт. Здесь подразумевается, что у них есть доступ по ssh. Если нет, запустите *git daemon* и скажите пользователям запустить эту команду вместо вышеприведенной: |
| 148 | + |
| 149 | + $ git clone git://ваш.компьютер/путь/до/скрипта |
| 150 | + |
| 151 | +С этих пор всякий раз, когда ваш скрипт готов к релизу, выполняйте |
| 152 | + |
| 153 | + $ git commit -a -m "Следующий релиз" |
| 154 | + |
| 155 | +и ваши пользователи смогут обновить свои версии, перейдя в каталог, с вашим скриптом и набрав |
| 156 | + |
| 157 | + $ git pull |
| 158 | + |
| 159 | +Ваши пользователи никогда не наткнутся на версию скрипта, которую вы не хотите им показывать. |
| 160 | + |
| 161 | +=== Что я сделал? === |
| 162 | + |
| 163 | +Выясните, какие изменения вы сделали со времени последнего коммита: |
| 164 | + |
| 165 | + $ git diff |
| 166 | + |
| 167 | +Или со вчерашнего дня: |
| 168 | + |
| 169 | + $ git diff "@{yesterday}" |
| 170 | + |
| 171 | +Или между определенной версией и версией, сделанной 2 коммита назад: |
| 172 | + |
| 173 | + $ git diff 1b6d "master~2" |
| 174 | + |
| 175 | +В каждом случае на выходе будет патч, который может быть применен с помощью *git apply*. Попробуйте также: |
| 176 | + |
| 177 | + $ git whatchanged --since="2 weeks ago" |
| 178 | + |
| 179 | +Часто вместо этого я использую для просмотра истории http://sourceforge.net/projects/qgit[qgit], из-за приятного интерфейса, или http://jonas.nitro.dk/tig[tig] с текстовым интерфейсом, который хорошо работает через медленное соединение. Как вариант, установите веб-сервер, введите *git instaweb* и запустите любой веб-браузер. |
| 180 | + |
| 181 | +=== Упражнение === |
| 182 | + |
| 183 | +Пусть A, B, C, D — четыре последовательных коммита, где В отличается от A лишь несколькими удаленными файлами. Мы хотим вернуть эти файлы в D. Как мы можем это сделать? |
| 184 | + |
| 185 | +Существует как минимум три решения. Предположим, что мы находимся на D. |
| 186 | + |
| 187 | + 1. Разница между A и B — удаленные файлы. Мы можем создать патч, отражающий эти изменения, и применить его: |
| 188 | + |
| 189 | + $ git diff B A | git apply |
| 190 | + |
| 191 | + 2. Поскольку в коммите A мы сохранили файлы, то можем восстановить их: |
| 192 | + |
| 193 | + $ git checkout A foo.c bar.h |
| 194 | + |
| 195 | + 3. Мы можем рассматривать переход от A к B как изменения, которые хотим отменить: |
| 196 | + |
| 197 | + $ git revert B |
| 198 | + |
| 199 | +Какой способ лучше? Тот, который вам больше нравится. С помощью Git легко получить желаемое, и часто существует много способов это сделать. |
0 commit comments