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