Статьи

Моя прогулка по книге Git

Я экспериментировал с git примерно в прошлом году, но большая часть работы, которую я проделал с ним до сих пор, была в режиме «один разработчик, взломай что-нибудь, подтолкни к github», который очень поверхностен.

Теперь, когда я буду работать с ним полный рабочий день (git — один из «полу дико принятых» SCM в Google), я подумал, что пора поближе взглянуть на некоторую мудрость, накопленную другими людьми, поэтому я наконец-то открыл Git книга и сделал проход по нему.

Книга отличная и обычно очень плавная. Он начинается с демонстрации простых сценариев использования, которые вы будете использовать с git, и заполняется короткими фрагментами кода, которые вы можете попробовать (даже в поезде без WiFi — в конце концов, это система управления исходным кодом). Некоторые из примеров не были кристально чистыми прямо из коробки и основывались на некоторых предыдущих знаниях, которые были у авторов (в конце концов, большая часть книги была собрана из разных источников, так что я полагаю, что было довольно легко случайно предположить, что немного знаний, которые его читатели не обязательно имеют в этот момент).

Вот краткое изложение вопросов, которые у меня возникли при чтении книги, а затем несколько интересных вещей, которые я нашел в конце. Я рекомендую, по крайней мере, некоторые знания о git для остальной части этой статьи, лучше всего сопровождаемой чтением самой книги Git. Как обычно, если вы обнаружите ошибку, пожалуйста, дайте мне знать. Еще одним связанным с этим рекомендуемым чтением является вопрос Git для начинающих .

Что происходит при добавлении двойного git?
git add используется не только для добавления новых файлов, но и для «добавления» изменений в существующие файлы.

Когда я делаю:

1
2
3
4
5
echo v1 > foo
git add foo
echo v2 > foo
git add foo
git commit -m bar

Добавлены ли обе версии foo в журнал фиксации или только последние?

Ответ в том, что на самом деле зафиксирована только последняя версия.

Нужен ли git коммит после git merge без конфликтов?
Исходя из svn, я ожидал, что после слияния изменений с моей локальной ветвью мне придется их зафиксировать. Проведение быстрого эксперимента показало, что в git это совсем не так — если слияние разрешается без ручного вмешательства (включая одновременное редактирование в разных местах одного и того же файла), то фиксация не требуется. Если есть какие-либо конфликты, которые разрешаются вручную (путем добавления файла git после исправления слияния), то требуется git commit.

Как работает Гитк? Иногда я вижу ветви, иногда нет … это очень запутанно
Этот долго меня озадачивал. Я обнаружил, что не могу доверять gitk, графическому инструменту для визуализации коммитов, ветвлений и слияний, потому что он продолжал давать мне противоречивые результаты, и я не мог понять почему.

Теперь я провел несколько экспериментов и копаний и обнаружил, что по умолчанию gitk будет показывать вам только текущую ветвь и любые объекты, которые являются ее потомками в графе версий . Если вы создадите ветку, переключитесь обратно на master и запустите gitk, вы не увидите эту ветку. Что меня смутило, так это то, что после обновления gitk повторно сканирует текущую ветвь и добавляет любые новые узлы на ее дисплей, сохраняя при этом все, что показывалось ранее — это означает, что если вы запустите gitk, переключитесь на новую ветвь и обновите gitk, новую ветвь и ее отношение к предыдущему теперь будет отображаться в gitk.

Конечно, как и все Linux, Gitk может управляться так, как вы этого хотите. Просто следуйте команде gitk с именами веток, которые вы хотите показать, или просто добавьте «–all», чтобы увидеть все ветки в вашем хранилище.

Как вы можете увидеть «ветвь структуры» хранилища?
В SVN есть четко определенный ориентированный граф между ветвями . Когда ветвь создается из ее родителя, это родительско-дочернее отношение создается и поддерживается, и инструменты с готовностью показывают вам этот граф ветвей.

Я мог бы догадаться об этом, но источники в Stack Overflow подтвердили, что в git нет прямого эквивалента. Вместо ветвей, имеющих родительские и дочерние отношения, между объектами есть родительско-дочерние отношения, поэтому отдельные файлы и каталоги могут иметь несколько родителей в графе версий, где другие файлы в той же ветви могут иметь полностью линейную историю. Модель более сложная, но более мощная, и, кажется, это основные причины, по которым слияния в git должны быть проще, чем в svn.

Что на самом деле означает «перемотка вперед»?
Используя git, я часто видел сообщения со словами «fast forward», но никогда не понимал, что это значит. Этот бит довольно хорошо объясняется в книге Git — быстрая перемотка вперед происходит, когда вы объединяете ветку b1 с b2, разрешаете любые возможные конфликты, а затем сливаете результат обратно в b1. b2 уже содержит версию, которая является потомком «головок» как b1, так и b2, что означает, что вся «работа по слиянию» в ней уже выполнена. Таким образом, когда эта структура объединяется с b1, на самом деле происходит то, что все изменения и работы по слиянию, которые произошли на b2, копируются в b1. После этого копирования ветка b1 (указатель на ревизионную группу DAG) «быстро пересылается» на узел-потомок, который является главой b2. По сути, результат слияния становится главой b1 простым и понятным способом.

Это радикально отличается от svn — у меня до сих пор иногда возникают ужасные воспоминания о попытке объединить ветку обратно в ствол. Сначала я всегда сливал транк в ветку, мне приходилось отрабатывать задницу, чтобы разрешить все конфликты и делать сборку зеленой, а затем иногда приходилось выполнять двойную работу при слиянии обратно в транк. С git вы уверены, что работа по разрешению конфликтов, которую вы выполняете в своей ветке, предварительно сохранена и используется для того, чтобы сделать слияние обратно с master (git-эквивалент trunk) так же просто, как пирог .

git pull, fetch, и что между ними
Говорят, что «git pull» эквивалентно «git fetch», за которым следует «git merge».
Возможность мгновенно извлечь весь контент из любого удаленного репозитория без необходимости его слияния прямо сейчас — это прекрасно, вы можете выполнять фактическую работу по слиянию и разрешению конфликтов отдельно, и вам нужно только подключение к удаленному репозиторию для извлечения. фаза. Когда я попытался сделать это, используя две локальные папки, git merge пожаловался, и мне не удалось понять, какие аргументы я должен передать «git merge» в этом случае?

Это оказалось простой технической проблемой . Чтобы объединить изменения вручную после выборки с произвольного пульта, просто запустите git merge FETCH_HEAD (иногда вам просто нужно знать волшебные слова). Обычно вы выбираете источник (обычно ветвь, которую вы клонировали) или другую удаленно отслеживаемую именованную ветку, поэтому вы просто указываете ее имя в качестве параметра «git merge».

Как на самом деле работает толчок?
Допустим, я настроил локальное «обычное» репо (оно должно быть пустым по причинам, объясненным в книге Git)

1
2
3
4
5
6
7
8
mkdir bare
cd bare
git init --bare
cd ..
git clone bare alice
cd alice
touch a && git add a && git commit -m "Added a"
git push # This fails

Почему толчок терпит неудачу?

Оказывается, проблема была в том, что я пытался вытолкнуть в пустой репозиторий. Если я сделаю «git push origin master», то последующее «git push» без аргументов завершится успешно.

А теперь для некоторых интересных вещей:

git bisect ftw
Предположим, вы только что нашли критическую ошибку и понятия не имеете, когда она появилась. Вы пишете простой (ручной / автоматизированный) тест для него и воспроизводите его, но не знаете, что это его вызвало. мерзавец попал на помощь!

git bisect позволяет вам выполнять бинарный поиск в вашем хранилище, чтобы найти точный коммит, который привел к ошибке. Хотя это возможно с другими VCS, в git это настолько естественно, что это прекрасно. Вы просто делаете «git bisect start», затем «git bisect good», чтобы указать, что текущая версия работает, и «git bisect bad», чтобы указать, что это не так, и git направит вас к правильной половине графа версий, пока Вы найдете точную версию, когда все стало плохо.

Настройте свои значения по умолчанию для удовольствия и прибыли
Вот некоторые трюки, которые я нашел в книге, которые вы, возможно, захотите сделать (если у вас есть какие-то другие твики, которые вы хотели бы порекомендовать, пожалуйста, прокомментируйте!)

сообщения журнала oneline
Если, как и я, вам легче читать сообщения журнала «один вкладыш», вы можете сделать его по умолчанию с

git config — глобальный формат.

Жизнь красочна
Сделайте git status и другие сообщения намного удобнее

git config –global color.ui true

Ссылка: моя прогулка по книге Git от нашего партнера по JCG Рона Гросса в блоге A Quantum Immortal .