Я чувствую, что должен начать этот пост, говоря, что я очень люблю Git . Если вы никогда не слышали об этом, это система контроля версий, такая как CVS или Subversion, но, в отличие от этих двух, это распределенная система контроля версий. Я не буду вдаваться в подробности об истории и возможностях git, но если вам интересно об этом, вы можете перейти на http://git-scm.com/book, который является удивительным ресурсом со всем от вступления до передовые концепции.
Я предполагаю, что к настоящему времени большинство профессиональных разработчиков программного обеспечения используют некоторую форму контроля версий в своей повседневной работе, но вы не должны останавливаться на достигнутом. Я использую git и для личных проектов. Хотя некоторые люди могут подумать, что это может быть излишним , я полностью не согласен. Нет ничего лучше комфорта, зная, что вся история
все ваши файлы в безопасности и готовы быть возвращенными, если они вам когда-нибудь понадобятся. Мы все иногда делаем ошибки. С git это так же просто, как написать 3 простые команды:
1
2
3
|
mkdir myNewProject cd myNewProject git init |
Это оно! Каждый файл, который вы создаете или изменяете в «myNewProject», теперь будет отслеживаться git. Очень полезная функция, которую вы получаете с каждым инструментом контроля версий — это возможность игнорировать определенные файлы из отслеживания инструмента. Вообще говоря, вы не хотите помещать в свой репозиторий кода ни один файл, который может быть вычислен в результате другого файла. В типичном проекте Java Maven это может быть, например, каталог «target» или, если вы используете Eclipse, файлы «.metadata», «.project» или «.settings». В git самый простой способ сделать это — иметь специальный файл с именем «.gitignore» в корне вашего проекта со всеми правилами исключения, которые вы хотите установить. Синтаксис этого файла довольно прост. Вы также можете иметь файл «.gitignore» для каждого подкаталога в вашем проекте, но это не так часто.
С правилами git и ignore хитрость заключается в том, что если файл, который вы хотите игнорировать, уже отслеживается git, то добавление его в «.gitignore» не заставит git автоматически забыть о файле. Чтобы проиллюстрировать этот момент, рассмотрим следующий пример. Сначала мы создаем репозиторий с двумя исходными файлами и фиксируем их:
1
2
3
4
5
6
|
mkdir gitExample cd gitExample touch file1 file2 git init git add . git commit -m 'Initial commit' |
Давайте теперь создадим файл .gitignore, чтобы попытаться игнорировать «file2? и совершить это:
1
2
3
|
echo file2 > .gitignore git add . git commit -m 'Added gitignore for file2' |
Теперь давайте изменим «file2? и посмотрим что получится
1
2
|
echo 'Hello World' >> file2 git status |
Мы получаем:
1
2
3
4
5
6
7
8
|
# On branch master # Changes not staged for commit: # (use 'git add ...' to update what will be committed) # (use 'git checkout -- ...' to discard changes in working directory) # # modified: file2 # no changes added to commit (use 'git add' and /or 'git commit -a' ) |
Git по-прежнему отслеживает file2, хотя уже находится на нашем .gitignore. Как я уже говорил, это происходит потому, что git уже отслеживал файл, когда мы добавляли его в наши игнорирующие файлы. Итак, давайте посмотрим, что произойдет, когда мы добавим «.gitignore» перед добавлением файла в git:
1
2
3
4
5
6
|
mkdir gitExample cd gitExample touch file1 file2 git init echo 'file2' > .gitignore git status |
И теперь мы получаем:
01
02
03
04
05
06
07
08
09
10
|
# On branch master # # Initial commit # # Untracked files: # (use 'git add ...' to include in what will be committed) # # .gitignore # file1 nothing added to commit but untracked files present (use 'git add' to track) |
Здорово! Нет упоминания о file2 в любом месте! Но если в качестве нашего первого примера мы забыли добавить файлы к нашему .gitignore изначально? Как мы можем помешать Git отслеживать их? Хорошая команда, которую мы можем использовать для этих случаев — git rm --cached file
. В нашем первом примере:
1
2
|
git rm --cached file2 git commit -m 'Removed file2' |
Если мы теперь изменим файл снова и сделаем git status
мы получим:
1
2
|
echo 'Hello World Again' >> file2 git status |
1
2
|
# On branch master nothing to commit (working directory clean) |
Именно то, что мы хотели!
Обратите внимание, что эта маленькая команда удалит файл из индекса git, но ничего не сделает с вашей рабочей копией. Это означает, что у вас все еще будет файл в вашем каталоге, но файл больше не будет частью репозитория git. Это также означает, что в следующий раз, когда вы отправите файл в удаленный репозиторий, файл не будет передан, и, если он уже существовал в удаленном репозитории, он будет удален.
Это хорошо для типичного случая использования, когда вы добавили файл, который вы никогда не собирались иметь в хранилище. Но рассмотрим этот другой вариант использования. Во многих проектах разработчики загружают в удаленный центральный репозиторий набор файлов конфигурации для своей IDE со значениями по умолчанию для таких вещей, как форматирование кода и проверка стиля. Но в то же время, когда разработчики клонируют репозиторий, они настраивают эти файлы конфигурации в соответствии со своими личными предпочтениями. Тем не менее, те изменения, которые применяются к каждому конкретному разработчику, не должны быть зафиксированы и перенесены обратно в хранилище. Проблема с использованием git rm --cached
заключается в том, что, хотя у каждого разработчика все еще будет своя собственная копия, в следующий раз, когда он отправит на сервер, он удалит оттуда конфигурацию по умолчанию. В подобных случаях есть еще одна довольно полезная команда, которая сделает git update-index --assume-unchanged <file>
: git update-index --assume-unchanged <file>
. Давайте посмотрим, что на примере:
1
2
3
4
5
6
|
mkdir gitExample cd gitExample touch file1 file2 git init git add . git commit -m 'Initial commit' |
Там у нас есть по умолчанию «file2?». Теперь давайте воспользуемся командой git update-index
и внесем некоторые изменения в файл:
1
2
3
|
git update-index --assume-unchanged file2 echo 'Hello World' >> file2 git status |
Результат:
1
2
|
# On branch master nothing to commit (working directory clean) |
Магия! Git больше не видит изменений в нашем файле, а исходный файл все еще находится в хранилище, чтобы его могли клонировать другие пользователи со значением по умолчанию.
Справка: Когда Git игнорирует ваш… .gitignore? от нашего партнера JCG Хосе Луиса по разработке, как это должно быть в блоге.