Каждый отдельный скрипт, связанный с созданием вашего программного обеспечения, должен находиться под контролем версий. [1]
VCS — это система, которая отслеживает версии кода с течением времени. [2]
Демо
https://asciinema.org/a/487303
Исходный код
https://github.com/Абдулсаметилери/vX
Мотивация
Когда я прочитал прекрасную книгу , чтобы лучше понять системы, управляемые версиями при разработке, я нашел в книге очень хороший пример.
«В качестве аналогии представьте, что вы создаете систему контроля версий, такую как SVN или Git. Когда пользователь впервые изменяет файл, система сохраняет весь файл на диск. Последующие коммиты, отражающие изменения в этом файле, могут сохранить только дельту, то есть только те строки, которые были добавлены, изменены или удалены. Затем, когда пользователь извлекает определенную версию, система открывает файл версии 0 и добавляет все последующие дельты, чтобы получить версию, которую запросил пользователь». [3]
Я просто хотел внедрить систему VCS с этой стратегией. Поэтому я начал экспериментальный хобби-проект под названием vX. Все это всего за 4 дня моей кропотливой работы. 😅
Архитектура
Прежде всего, все связанные файлы находятся в папке .vx. ( Go tool игнорирует любые каталоги или файлы, имена которых начинаются с «_» или «.»)
v1, v2, .., vN — версии фиксации.
checkout — папка, содержащая результат слияния всех файлов с указанной версией коммита. Например, checkout/v2 включает в себя комбинацию commit/v1 + commit/v2.
Разумно создать каталог проверки, потому что «хорошая практика в мире UNIX заключается в развертывании каждой версии приложения в новом каталоге и наличии ссылки, указывающей на текущую версию ». В настоящее время я не реализовал это поведение.
Промежуточная область — это файлы, которые станут частью следующего коммита. В этом контексте это обычный текстовый файл с режимом только добавления. Потому что мы делаем обновления после редактирования файла. Например, часть содержимого этого файла отформатирована как путь к файлу | время модификации файла | Статус файла
Например, README.md — это своего рода файл, который создается с разным временем модификации и статусами перед операцией фиксации. Таким образом, последнее состояние этого файла — «Обновлено 14.04.2022 05:49:09».
status — это текстовый файл, который постоянно отслеживает все файлы. Я очищаю содержимое промежуточной области после успешного изменения файла. Поэтому мне нужно постоянно хранить файлы в системе контроля версий.
Структура проекта
Я следовал структуре проекта, рекомендованной для любого приложения на базе Cobra.
Я использовал каталог testdata.
В настоящее время я не знаю, как обнаружить удаленные файлы, поэтому я просто отслеживаю созданные и измененные файлы. Этот статус основан на времени модификации файла, предоставленном файловой системой.
При каждой операции коммита я сохранял файлы в staging area целиком.
Команды
init: создает каталоги и файлы.
status : читает текстовые файлы промежуточной области и анализирует их в соответствующей структуре и использует tablewriter для отображения результатов. Если вы посмотрите внимательно, я создал функции с интерфейсом io.Writer. В модульных тестах я легко передаю bytes.Buffer и Assert. Я рекомендую прочитать эту замечательную статью об интерфейсах в Go.
history: показывает все коммиты. Чтобы реализовать эту функциональность, я сохраняю файл metadata.txt в каждом каталоге В этом каталоге я храню сообщения коммитов и время, разделенные символом |.
add: добавляет указанные файлы и каталоги в status.txt и staging-area.txt. Как упоминалось ранее, чтобы показать обновленный статус для некоторых файлов, я сохраняю последнее состояние файлов status.txt, поэтому каждый раз я записываю новые данные. staging-area.txt — это данные только для добавления, поэтому нет необходимости выполнять какие-либо операции, просто добавляем новые данные. Дублирование данных не проблема. После успешной фиксации я вычисляю последнее состояние.
commit : читает файл staging-area.txt, копирует его в определенный каталог (v1, v2) и после завершения операции запись осуществляется в staging-area.txt.
Например, предположим, что в коммите v1 добавлен пользователем файл README.md testdata/, а в коммите v2 добавлен пользователем Makefile. Итак, папки коммитов будут выглядеть так
checkout : rsync из каталога commit/ в каталог checkout/ с определенным идентификатором. rsync также объединяет для нас два одинаковых файла.
Весь код:
https://github.com/Abdulsametileri/vX