Если вы достаточно длительное время используете UNIX/Linux, то у вас уже вероятно имеются хорошо «заточенные» файлы конфигурации Bash, Vim, Emacs и других приложений. Копирование вручную этих файлов между всеми системами, с которыми вы работаете, может быть весьма утомительным процессом. Git может существенно облегчить ваши мучения из-за копирования ваших конфигурационных файлов на новые компьютеры.
Обычно в своей работе я пользуюсь Dropbox, однако как быть с конфиг-файлами, хранящимися в /etc и в домашнем каталоге? Можно, конечно, придумать какое-нибудь извращение и приспособить Dropbox для хранения этих файлов, однако здесь возникает ещё одна проблема: как заставить Dropbox закачивать на новую систему только определённые файлы, а не все сразу?
Ещё одним решением может быть использование rsync, Duplicity или Unison, однако они не позволяют сохранять версионность файлов, и хранят лишь одну-единственную копию файла с самыми последними изменениями. Короче, Git (или другая система контроля версий) в моём случае подходит лучше всего, а может быть отлично сгодится и для вас.
Другой причиной, по которой мой выбор пал на Git, стало то, что я уже имею некоторый положительный опыт работы с ним и мне хотелось бы ещё попрактиковаться, используя Git в своей повседневной жизни. Конечно, опытные пользователи Git располагают гораздо большим набором знаний и вероятно могут гораздо эффективнее меня решить поставленные задачи. Я же попытался изучив лишь основные моменты работы с Git, создать инструкцию, которой бы могли свободно воспользоваться люди, не знакомые с ним вообще. Если у вас есть идеи, как лучше организовать процесс работы с файлами — пишите в комментариях, я всегда рад новым идеям.
Вкратце опишем перечень шагов, которые нам предстоит сделать в процессе изучения данного материала:
- создать ключи SSH, чтобы не приходилось авторизоваться паролем;
- установить Git на всех системах где будем его использовать;
- создать «голый» (bare) репозиторий на удалённой системе;
- создать репозиторий в локальной системе, файлы с которой будем синхронизировать;
- добавить файлы в локальный репозиторий;
- сделать слепок (commit) добавленных файлов;
- отправить (push) изменения в удалённый репозиторий;
- сделать изменения в локальных файлах и сделать слепок изменений;
- клонировать репозиторий на другую систему.
Начнём
Первое, что нам понадобится — это система, которая будет хранить наш Git-репозиторий. У вас должна быть возможность подключаться к ней по SSH. Это может быть как компьютер в вашей локальной сети, так и система, расположенная в Интернет. Вы даже можете использовать онлайн-сервис GitHub, если у вас нет подходящего компьютера.
Первым делом вам необходимо создать пару SSH-ключей и настроить аутентификацию на удалённой системе. Чтобы каждый раз не вводить пароль, вы можете сгенерировать закрытый ключ без пароля, однако не забывайте о том, что если кто-то сможет заполучить ваш закрытый ключ, то он сможет авторизоваться по SSH на удалённой системе. Процесс генерации ключей на моей системе выглядел так:
$ ssh-keygen -t dsa Generating public/private dsa key pair. Enter file in which to save the key (/home/ashep/.ssh/id_dsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/ashep/.ssh/id_dsa. Your public key has been saved in /home/ashep/.ssh/id_dsa.pub. The key fingerprint is: f0:59:19:5d:69:c7:4c:62:d0:c1:38:fe:f1:2b:2d:2c ashep@adesktop The key's randomart image is: +--[ DSA 1024]----+ | ...*=*.| | o+.=.+| | . o. o . | | o o . . | | S . o | | . .| | . . .| | E + o | | . o | +-----------------+
После того, как пара ключей создана, закрытый ключ будет размещён в в ~/.ssh/id_dsa, а открытый — в ~/.ssh/id_dsa.pub. Теперь, чтобы удалённая система аутентифицировала вас на основе ключа, а не пароля, необходимо скопировать содержимое локального файла ~/.ssh/id_dsa.pub в файл ~/.ssh/authorized_keys на удалённой системе. В Debian/Ubuntu для этих целей есть специальный shell-скрипт ssh-copy-id, им и воспользуемся:
$ ssh-copy-id ashep@aserver ashep@aserver's password: Now try logging into the machine, with "ssh 'ashep@aserver'", and check in: .ssh/authorized_keys to make sure we haven't added extra keys that you weren't expecting.
Пользователи же других систем, в которых ssh-copy-id отсутствует, могут воспользоваться старой-доброй scp:
$ scp /home/ashep/.ssh/id_dsa.pub ashep@aserver:/home/ashep/.ssh/authorized_keys
Будьте внимательны и если в ~/.ssh/authorized_keys на удалённой системе у вас уже имеются какие-то ключи, то добавьте вручную открытый ключ к существующим, поскольку приведённая выше команда затрёт существующий файл.
Ну и, само-собой разумеется, в ваших системах, которые будут участвовать в работе, должен быть установлен Git. На сегодняшний день Git присутствует в репозиториях всех современных дистрибутивов, а также в коллекции портов FreeBSD, так что у вас не должно возникнуть сложностей с его установкой. Я использую Ubuntu и в ней Git установился «лёгким движением руки»:
$ sudo apt-get install git-core
Создание репозиториев
Пришло время создавать репозитории. Начнём с создания репозитория на удалённой системе, затем создадим локальный, в который и добавим файлы. Подключитесь к удалённой системе по SSH:
$ ssh ashep@aserver
создайте каталог для хранения репозитория:
$ mkdir project
и создайте в это каталоге «голый» Git-репозиторий:
$ cd project && git init --bare Initialized empty Git repository in /home/ashep/project/
Просто, не так ли? Теперь в вашей локальной системе необходимо создать репозиторий для хранения отслеживаемых файлов. Обычно, если вы работаете над каким-то проектом, каталог репозитория .git хранится в каталоге проекта. В нашем же случае необходимо будет хранить файлы из разных мест, поэтому лучшим вариантом будет создать репозиторий в корне домашнего каталога:
$ cd ~/ && git init Initialized empty Git repository in /home/ashep/.git/
Репозиторий успешно создан и прежде, чем мы продолжим работу, давайте минимально настроим Git, а точнее определим имя и email, которые будут упоминаться к истории коммитов (слепков):
$ git config --global user.name "Alexander Shepetko" $ git config --global user.email "ashep@ashep.org"
Теперь добавим что-нибудь в репозиторий, указывая Git отслеживать изменения:
$ git add .vim $ git add .vimrc
И сделаем слепок состояния добавленных файлов, указав при помощи опции -m комментарии к слепку:
$ git commit -m 'Первый слепок' [master (root-commit) f4c5dcf] Первый слепок 4 files changed, 90 insertions(+), 0 deletions(-) create mode 100644 .vim/.netrwhist create mode 100644 .vim/spell/ru.utf-8.spl create mode 100644 .vim/spell/ru.utf-8.sug create mode 100644 .vimrc
Отлично, файлы и каталог успешно добавлены, теперь можно «слить» локальный репозиторий в удалённый. Для начала необходимо в локальном репозитории определить один или несколько удалённых, с которыми Git сможет производить синхронизацию. Добавим ранее созданный удалённый репозиторий project на удалённой системе aserver, доступ к которой у нас настроен от имени пользователя ashep:
$ git remote add origin ashep@aserver:project
И отправим изменения из локального репозитория:
$ git push origin master Counting objects: 8, done. Delta compression using up to 2 threads. Compressing objects: 100% (8/8), done. Writing objects: 100% (8/8), 2.37 MiB | 462 KiB/s, done. Total 8 (delta 0), reused 0 (delta 0) To ashep@aserver:project * [new branch] master -> master
Отслеживание изменений
После того, как вы сделали свой первый слепок и отправили изменения в удалённый репозиторий, самое время разобраться с тем, как отслеживать изменения в файлах. Сделайте какое-нибудь незначительное изменение, например, в файле .vimrc и сделайте после этого слепок состояния всех отслеживаемых файлов:
$ git commit -a -m 'Изменён .vimrc' [master 0d6096f] Изменён .vimrc 1 files changed, 0 insertions(+), 1 deletions(-)
Теперь вы можете отправить изменения в удалённый репозиторий:
$ git push origin master Counting objects: 5, done. Delta compression using up to 2 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 317 bytes, done. Total 3 (delta 1), reused 0 (delta 0) To ashep@aserver:project f4c5dcf..0d6096f master -> master
Копирование файлов на другие системы
Пришло время «размножить» наши конфигурационные файлы на тех системах, где это нам нужно. Авторизуйтесь в нужной системе и создайте в своём домашнем каталоге новый Git-репозиторий, как это мы делали ранее:
$ cd ~/ && git init Initialized empty Git repository in /home/ashep/.git/
И теперь скопируйте файлы удалённого репозитория на диск:
$ git pull ashep@aserver:project remote: Counting objects: 11, done. remote: Compressing objects: 100% (11/11), done. remote: Total 11 (delta 1), reused 0 (delta 0) Unpacking objects: 100% (11/11), done. From aserver:project * branch HEAD -> FETCH_HEAD
На это всё! Если вы сделаете изменения в каком-то из отслеживаемых файлов на любой системе, просто воспользуйтесь командами git commit и git push, как это было показано выше и изменения будут доставлены в удалённый репозиторий, после чего вы сможете из загрузить во все локальные репозитории систем, в которых эти версии файлов вам необходимы, при помощи команды git pull.
Обратите внимание на то, что мы используем git pull, а не git clone, поскольку нам нужно получать именно изменения в файлах, а не весь репозиторий целиком.
Управление версиями
По ходу работы вы можете добавлять в репозиторий новые файлы для отслеживания при помощи команд git add и удалять ненужные при помощи git rm. Если вам необходмо узнать, какие файлы находятся в состоянии «отслеживаемых», воспользуйтесь командой git ls-files:
$ git ls-files .vim/.netrwhist .vim/spell/ru.utf-8.spl .vim/spell/ru.utf-8.sug .vimrc
Что делать, если вы сделали ненужные изменения в локальном файле и хотите восстановить версию, находящуюся в последнем слепке? Для этого существует команда git checkout. Например, следующая команда восстановит последнюю версию файла .vimrc:
$ git checkout .vimrc
Просмотреть историю слепков можно при помощи команды git log:
$ git log commit 0d6096f96c647e8b1bdfb6a217cbae967b16a5cd Author: Alexander Shepetko Date: Fri Apr 22 02:46:15 2011 +0300 Изменён .vimrc commit f4c5dcf1f5c55ab8b495c6e16afb1eee73b8380a Author: Alexander Shepetko Date: Fri Apr 22 01:54:14 2011 +0300 Первый слепок
Обратите внимание на 40-битное значение хэша слепка. Оно уникально идентифицирует каждый коммит, так что вы можете обращаться к нему. В частности иногда бывает полезно восстановить не отдельный файл а весь слепок целиком. Для этого достаточно команде git revert передать хэш-значение нужного слепка:
$ git revert 0d6096f96c647e8b1bdfb6a217cbae967b16a5cd Finished one revert. [master 933c16f] Revert "Изменён .vimrc" 1 files changed, 1 insertions(+), 0 deletions(-)
Резюме
Хотя Git далёк от определения дружественной пользователям утилиты, разобраться с основами его использования не так уж и сложно. Данная заметка никоим образом не претендует на описание принципов работы Git, а лишь рассказывает об идее применения этой очень мощной утилиты для нужд рядовых пользователей и системных администраторов. Git обладает огромными возможностями и если вам это интересно, и вам хотелось бы подробней узнать о них, советую вам начать с замечательной книги Pro Git, в большей части уже доступной на русском языке.
По мотивам linux.com
Давно пользуюсь подобной схемой. В ubuntu есть еще полезный пакет etckeeper (вырезка мана:
ETCKEEPER (8)
NAME
etckeeper — store /etc in git, mercurial, bazaar, or darcs ...
)
Приспособил его для синхронизации каталога /etc между рабочими компьютерами.
Главное — не запустить git-clean для такого репозитория... ;)
Зачем ты это сказал? теперь я знаю эту команду — не знал бы никогда бы не ввёл (хотя в баше автодополнение есть)