Фиксация изменений (commiting)
Теперь, когда хранилище было создано, пора создать что-нибудь для фиксации. Для этого примера я создал файл main.c со следующим содержимым (редактирование выполняется в блокноте или другом редакторе):
#include <stdio.h> int main(int argc, char **argv){ printf("Hello world!\n"); return 0;}Щелчок на кнопку Rescan (Перечитать) в git gui заставит его искать новые, измененные и удалённые файлы в директории. На следующем скриншоте git gui нашёл новый файл.
Что бы добавить этот файл в фиксацию, щёлкните на иконке слева от имени файла. Файл будет перемещён с Unstaged Changes (Измененено) панели на Staged Changes (Подготовлено) панель. Теперь мы можем добавить сообщение фиксации (commit message) и зафиксировать изменения Commit (Сохранить) кнопкой.
Говорить 'hello world' это конечно хорошо, но я хочу что бы моя программа была более персонализирована. Давайте скажем 'hello' пользователю. Вот как будет выглядеть измененный код (редактирование выполняется в блокноте или другом редакторе):
#include <stdio.h>#include <string.h> int main(int argc, char **argv){ char name[255]; printf("Enter your name: "); fgets(name, 255, stdin); printf("length = %d\n", strlen(name)); /* debug line */ name[strlen(name)-1] = '\0'; /* remove the newline at the end */ printf("Hello %s!\n", name); return 0;}У меня были проблемы с тем что новая линия печаталась после имени пользователя, поэтому я добавил отладочную линию кода, что бы помочь себе найти причину. Я бы хотел зафиксировать изменение без этой отладочной линии, но я хочу сохранить эту линию в моей рабочей копии что бы продолжить отладку. С git gui это не проблема. Сначала щёлкните Rescan (перечитать) для поиска изменений.
Изменения выделены красным (удаленные линии) или зеленым (добавленные линии).
Далее щёлкните на иконке слева от файла что бы подготовить (stage) изменения к фиксации. Файл будет перенесен в нижнее окно.
Затем правый щелчок на отладочной линии и выберите Unstage Line From Commit (Убрать строку из подготовленного).
Теперь отладочная линия не была подготовлена (unstaged) к фиксации, в то время как остальные изменения были. Осталось только заполнить сообщение фиксации и зафиксировать изменения щёлкнув по Commit (Сохранить).
Ветвление (branching)
Теперь, давайте предположим что мы хотим начать добавлять новые возможности в нашу следующую большую версию программы. Но мы так же хотим сохранить стабильную версию в которой исправлять ошибки. Что бы сделать это мы создадим ветку (branch) для наших новый разработок. Что бы создать новую ветку в git gui выберете Branch → Create (Ветвь → Создать). Большая возможность какую я хочу добавить это возможность спросить пользователя его фамилию, поэтому я назову ветку lastname. Опции по умолчанию подходят без изменений, так что просто введите имя и щёлкните Create.
Теперь когда я в lastname ветке, я могу делать мои новые модификации:
#include <stdio.h>#include <string.h> int main(int argc, char **argv){ char first[255], last[255]; printf("Enter your first name: "); fgets(first, 255, stdin); first[strlen(first)-1] = '\0'; /* remove the newline at the end */ printf("Now enter your last name: "); gets(last); /* buffer overflow? what's that? */ printf("Hello %s %s!\n", first, last); return 0;}Теперь я могу зафиксировать изменения. Замете что я фиксирую изменения используя другое имя. Мы рассмотрим это позже. Обычно вы всегда будете использовать одно и тоже имя для фиксаций.
Между тем, пользователь проинформировал нас что не показ запятой после прямого обращения к кому-то это серьёзная ошибка. Что бы исправить её в нашей стабильной ветке, вы сначала должны переключится назад на неё. Это достигается используя Branch → Checkout (Ветвь → Перейти).
Теперь мы можем исправить нашу большую ошибку.
Если мы выберем Repository → Visualize All Branch History (Репозиторий → Показать историю всех ветвей), мы увидим как складывается наша история.
Слияние (merging)
После напряжённой работы мы решили что наша lastname ветка достаточно стабильна, что бы влить её в master ветку. Что бы выполнить слияние, используйте Merge → Local Merge (Слияние → Локальное слияние).
Так как две разных фиксации делали два разных изменения на одной и той же линии, происходит конфликт (conflict).
Конфликт может быть разрешён используя любой текстовый редактор (оставляете в тексте только нужный вариант).
После разрешения конфликта, подготовьте изменения щёлкнув на иконке файла и зафиксируйте слияние щёлкнув по Commit кнопке: в редакторе внести изменения в файл и сохранить его - Перечитать — Подготовить - Сохранить.
Просмотр истории
Файл main.c становится немного большим, поэтому я решил вынести код, спрашивающий имя пользователя в отдельную функцию. Пока я это делал, я решил вынести функцию в отдельный файл. Хранилище теперь содержит файлы main.c, askname.c, и askname.h.
/* main.c */#include <stdio.h> #include "askname.h" int main(int argc, char **argv){ char first[255], last[255]; askname(first, last); printf("Hello, %s %s!\n", first, last); return 0;} /* askname.c */#include <stdio.h>#include <string.h> void askname(char *first, char *last){ printf("Enter your first name: "); fgets(first, 255, stdin); first[strlen(first)-1] = '\0'; /* remove the newline at the end */ printf("Now enter your last name: "); gets(last); /* buffer overflow? what's that? */} /* askname.h */void askname(char *first, char *last); Файлы создают в редакторе. Затем перечитать репозиторий, подготовить все и сохранить.
История хранилища может быть просмотрена и изучена выбрав Repository → Visualize All Branch History. На следующем скриншоте я пытаюсь найти в какой фиксации была добавлена last переменная, ища все фиксации в которых было добавлено или убрано слово last.
Фиксации, которые подходят под условия поиска отмечены жирным шрифтом, что бы быстро и легко обнаружить нужную фиксацию. Можно посмотреть старую и новую версии. Цветом выделены изменения.
Через пару дней, кто-то просматривая наш код увидел что gets функция может вызвать переполнение буфера. Будучи любителем показывать пальцем, этот человек решает запустить git blame что бы увидеть кто последний раз редактировал эту линию кода. Проблема в том что Боб, тот кто зафиксировал эту линию в хранилище, а я последний кто трогал её когда я переместил строку в другой файл. Очевидно, я не виноват (конечно же). Но так ли умен git что бы обнаружить это? Да, это так.
Что бы запустить blame, выберете Repository → Browse master's Files (Репозиторий → Показать файлы ветви master). Из дерева, которое появится, дважды щёлкните на файле с интересующей строкой, который в данном случае askname.c. Наведённая мышка на интересующую линию показывает нам подсказку, которая говорит нам всё что нам надо знать.
Здесь мы можем видеть что эта линия была зафиксирована Бобом в фиксации f6c0, а затем я её переместил в её новое месторасположение в фиксации b312.