Как выкачать репозиторий GIT от ручного и до автоматизированного
Как мы рассказали в статье Доступные хранилища кода такие как git, svn и другие если доступна директория .git/
, то есть возможность получить как некоторую информацию, так и код проекта. Давайте посмотрим на получение кода проекта :)
Как выкачать гит руками
Для того, чтобы понять как выкачать репозиторий – нужно понимать некоторые моменты, вокруг которых крутится работа гита. Для этого я завел тестовый репозиторий и рассмотрим только саму директорию .git/
➜ accessible-code-repositories git:(master) tree .git/
.git
├── COMMIT_EDITMSG
├── HEAD
├── config
├── description
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
...
│ ├── push-to-checkout.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ └── master
├── objects
│ ├── 0d
│ │ └── bdf010a109633802481d9674fedb3a87a6ec53
│ ├── 43
│ │ └── 5724585b13f9c994c23a3d2d71eb59687da225
...
│ ├── f7
│ │ └── 89d2f8f608528af8c322bacda45605d7afc69a
│ ├── fa
│ │ └── a5334b6a24349633168b7f79bfe32ef7938d2b
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
└── tags
27 directories, 37 files
Тут мы уже видим знакомые нам файлы .git/config
и .git/index
, но еще и две интересных дирректориии .git/logs/
и .git/objects/
на них мы и остановимся поподробнее.
На самом деле с директорией .git/logs/
все более-менее понятно и там можно в файле .git/logs/HEAD
посмотреть хэши коммитов (для нас это важно), автора и его почту.
Давайте посмотрим на хэши коммитов – они ведут с нулевого коммита 0000000000000000000000000000000000000000
на первой строке до следующих хэшей коммитов со второй позии на строке в первую на следующей и так далее
Это как раз хранит историю разработок и изменений в проектах. Но где эти данные хранятся, где код проекта? А эти данные как раз находятся в директории .git/objects/
, но там странная структура скажете вы, и как угадать все эти имена диреткорий и файлов? На самом деле это очень просто – первые два символа от хэша это название директории, а остальные – это имя файла в этой директории. Такой формат хранения нахывается радужными таблицами1 и сделан для ускорения работы с файловой системой.
Давайте рассмотрим коммит e9b86766a600279c4c15404563ebf8d179fe296a deca8152bbecb2cce5f2903ebe9522c17faa66d3 Roman Ananev <REDACTED@gmail.com> 1741511834 +0400 commit: update db password
. Тут мы моэем увидеть такие данные как
e9b86766a600279c4c15404563ebf8d179fe296a
родительский коммитdeca8152bbecb2cce5f2903ebe9522c17faa66d3
коммит как раз в котором сделано изменениеRoman Ananev <REDACTED@gmail.com>
автор коммита1741511834 +0400
время коммита в timestamp с часовым поясомcommit: update db password
информация о коммите
Как говорили ранее – рассмотрим сам коммит deca8152bbecb2cce5f2903ebe9522c17faa66d3
и попробуем найти информацию с данными в диреткории .git/objects/
. Обладая знаниями что первые два символа это имя директории, а остальные имя файла у нас получается такой путь .git/objects/de/ca8152bbecb2cce5f2903ebe9522c17faa66d3
. Смотрим файл (или скачиваем его, но нужно положить именно в такой же структуре как и откуда скачали)
Какая-то ерунда и не понятно что там – да, это формат который может прочитать гит сам, для этого мы просто воспользуемся низкоуровневыми командами git
git ls-tree deca8152bbecb2cce5f2903ebe9522c17faa66d3
для получения содержимого. Да, можно использовать только часть хэша, но я люблю полный использовать. Тут мы берем blob файла, который нам нужен и смотрим его следующей командой.git cat-file -p b979ef42e04bbe1ce868d7219c8d29621b88146c
которая нам уже возвращает содержимое файла
Я показал простой путь на локальном репозитории, но вы можете это же сделать рекурсивно скачивая все файлы и восстанавливая структуру так, как она должна быть.
А можно автоматически выкачать репозиторий?
На самом деле очень давно уже утилиты для выкачивания репозиториев доступны и вы можете ими пользоваться, скачав из открытых источников
- https://github.com/davtur19/DotGit работает как браузерное расширение
- https://github.com/kost/dvcs-ripper Позволяет выкачивать GIT, Mercurial/HG, Bazaar/bzr, SVN и CVS
- https://github.com/0xHJK/dumpall работает с
.git/
,.svn/
,.DS_Store
- https://github.com/0x90/dvcs-arsenal как сборка ссылок на разные утилиты
Да, кажется что утилиты давно не обновлялись – но это и не нужно, структура и подходы не меняются :)