Git убрать файл из под контроля
Итак, у вас имеется настоящий Git-репозиторий и рабочая копия файлов для некоторого проекта. Вам нужно делать некоторые изменения и фиксировать «снимки» состояния (snapshots) этих изменений в вашем репозитории каждый раз, когда проект достигает состояния, которое вам хотелось бы сохранить.
Запомните, каждый файл в вашем рабочем каталоге может находиться в одном из двух состояний: под версионным контролем (отслеживаемые) и нет (неотслеживаемые). Отслеживаемые файлы — это те файлы, которые были в последнем снимке состояния проекта; они могут быть неизменёнными, изменёнными или подготовленными к коммиту. Если кратко, то отслеживаемые файлы — это те файлы, о которых знает Git.
Неотслеживаемые файлы — это всё остальное, любые файлы в вашем рабочем каталоге, которые не входили в ваш последний снимок состояния и не подготовлены к коммиту. Когда вы впервые клонируете репозиторий, все файлы будут отслеживаемыми и неизменёнными, потому что Git только что их извлек и вы ничего пока не редактировали.
Как только вы отредактируете файлы, Git будет рассматривать их как изменённые, так как вы изменили их с момента последнего коммита. Вы индексируете эти изменения, затем фиксируете все проиндексированные изменения, а затем цикл повторяется.
19. Слияние двух веток
Объединить две ветки можно параметром merge с указанием имени ветки. Команда объединит указанную ветку с основной.
Если надо выполнить коммит слияния, выполните команду git merge с флагом --no-ff .
Указанная команда объединит заданную ветку с основной и произведёт коммит слияния. Это необходимо для фиксации всех слияний в вашем репозитории.
2. Кэширование учётных данных
Кэшировать учётные данные можно с помощью параметра config с флагом --global . Так вы избавитесь от необходимости вручную вводить имя пользователя и пароль при создании нового коммита.
Коммит изменений
Теперь, когда ваш индекс находится в таком состоянии, как вам и хотелось, вы можете зафиксировать свои изменения. Запомните, всё, что до сих пор не проиндексировано — любые файлы, созданные или изменённые вами, и для которых вы не выполнили git add после редактирования — не войдут в этот коммит. Они останутся изменёнными файлами на вашем диске. В нашем случае, когда вы в последний раз выполняли git status , вы видели что всё проиндексировано, и вот, вы готовы к коммиту. Простейший способ зафиксировать изменения — это набрать git commit :
Эта команда откроет выбранный вами текстовый редактор.
Редактор устанавливается переменной окружения EDITOR — обычно это vim или emacs, хотя вы можете установить любой другой с помощью команды git config --global core.editor , как было показано в главе Введение).
В редакторе будет отображён следующий текст (это пример окна Vim):
Для ещё более подробного напоминания, что же именно вы поменяли, можете передать аргумент -v в команду git commit . Это приведёт к тому, что в комментарий будет также помещена дельта/diff изменений, таким образом вы сможете точно увидеть все изменения которые вы совершили.
Есть и другой способ — вы можете набрать свой комментарий к коммиту в командной строке вместе с командой commit указав его после параметра -m , как в следующем примере:
Итак, вы создали свой первый коммит! Вы можете видеть, что коммит вывел вам немного информации о себе: на какую ветку вы выполнили коммит ( master ), какая контрольная сумма SHA-1 у этого коммита ( 463dc4f ), сколько файлов было изменено, а также статистику по добавленным/удалённым строкам в этом коммите.
Запомните, что коммит сохраняет снимок состояния вашего индекса. Всё, что вы не проиндексировали, так и висит в рабочем каталоге как изменённое; вы можете сделать ещё один коммит, чтобы добавить эти изменения в репозиторий. Каждый раз, когда вы делаете коммит, вы сохраняете снимок состояния вашего проекта, который позже вы можете восстановить или с которым можно сравнить текущее состояние.
14. Откат последнего коммита
Откатить последний коммит можно с помощью параметра revert . Создастся новый коммит, содержащий обратные преобразования относительно предыдущего, и добавится к истории текущей ветки.
13. Изменение последнего коммита
Внимание! Не изменяйте публичные коммиты.
С помощью amend прекрасно исправляются локальные коммиты, а исправления можно передать в общий репозиторий. Однако изменять коммиты, уже доступные другим пользователям, не следует. Помните, что изменённые коммиты являются совершенно новыми, а предыдущий коммит уже не будет доступен в текущей ветке. Последствия будут такими же, как при отмене изменений публичного снимка.
5. Проверка статуса репозитория
Просмотреть статус нужного репозитория можно по ключевому слову status : его действие распространяется на подготовленные, неподготовленные и неотслеживаемые файлы.
20. Отображение журнала фиксации в виде графика для текущей или всех веток
Просмотреть историю коммитов в виде графика для текущей ветки можно с помощью параметра log и флагов --graph --oneline --decorate . Опция --graph выведет график в формате ASCII, отражающий структуру ветвления истории коммитов. В связке с флагами --oneline и --decorate , этот флаг упрощает понимание того, к какой ветке относится каждый коммит.
Для просмотра истории коммитов по всем веткам используется флаг --all .
Индексация изменённых файлов
Давайте модифицируем файл, уже находящийся под версионным контролем. Если вы измените отслеживаемый файл CONTRIBUTING.md и после этого снова выполните команду git status , то результат будет примерно следующим:
Файл CONTRIBUTING.md находится в секции «Changes not staged for commit» — это означает, что отслеживаемый файл был изменён в рабочем каталоге, но пока не проиндексирован. Чтобы проиндексировать его, необходимо выполнить команду git add . Это многофункциональная команда, она используется для добавления под версионный контроль новых файлов, для индексации изменений, а также для других целей, например для указания файлов с исправленным конфликтом слияния. Вам может быть понятнее, если вы будете думать об этом как «добавить этот контент в следующий коммит», а не как «добавить этот файл в проект». Выполним git add , чтобы проиндексировать CONTRIBUTING.md , а затем снова выполним git status :
Теперь оба файла проиндексированы и войдут в следующий коммит. В этот момент вы, предположим, вспомнили одно небольшое изменение, которое вы хотите сделать в CONTRIBUTING.md до коммита. Вы открываете файл, вносите и сохраняете необходимые изменения и вроде бы готовы к коммиту. Но давайте-ка ещё раз выполним git status :
Что за чёрт? Теперь CONTRIBUTING.md отображается как проиндексированный и непроиндексированный одновременно. Как такое возможно? Такая ситуация наглядно демонстрирует, что Git индексирует файл в точности в том состоянии, в котором он находился, когда вы выполнили команду git add . Если вы выполните коммит сейчас, то файл CONTRIBUTING.md попадёт в коммит в том состоянии, в котором он находился, когда вы последний раз выполняли команду git add , а не в том, в котором он находится в вашем рабочем каталоге в момент выполнения git commit . Если вы изменили файл после выполнения git add , вам придётся снова выполнить git add , чтобы проиндексировать последнюю версию файла:
Игнорирование индексации
Несмотря на то, что индекс может быть удивительно полезным для создания коммитов именно такими, как вам и хотелось, он временами несколько сложнее, чем вам нужно в процессе работы. Если у вас есть желание пропустить этап индексирования, Git предоставляет простой способ. Добавление параметра -a в команду git commit заставляет Git автоматически индексировать каждый уже отслеживаемый на момент коммита файл, позволяя вам обойтись без git add :
Обратите внимание, что в данном случае перед коммитом вам не нужно выполнять git add для файла CONTRIBUTING.md , потому что флаг -a включает все файлы. Это удобно, но будьте осторожны: флаг -a может включить в коммит нежелательные изменения.
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.
Я не знаю ни одного проекта, в рабочей директории которого не появлялось бы таких файлов, которые не нужно игнорировать. Зачастую, у вас имеется группа файлов, которые вы не только не хотите автоматически добавлять в репозиторий, но и видеть в списках неотслеживаемых (а чем взрослее проект, тем больше таких файлов может быть). К таким файлам обычно относятся автоматически генерируемые файлы (различные логи, результаты сборки программ и т.п.).
Как я говорил в вводной лекции, в таком случае, вы можете создать файл .gitignore с перечислением шаблонов соответствующих таким файлам. Хорошая практика заключается в настройке файла .gitignore до того, как начать серьёзно работать, это защитит вас от случайного добавления в репозиторий файлов, которых вы там видеть не хотите.
Вот пример файла .gitignore для типового Rails приложения (пример взят с github и является стандартом де-факто для большинства репозиториев с проектами на Ruby on Rails):
Давайте повнимательнее рассмотрим этот файл: В первой строке написано, что необходимо игнорировать все файлы, которые заканчиваются на .rbc, в четвертой, что необходимо игнорировать директорию log, в шестой - все файлы конфигураций баз данных sqlite3. Сразу видно, что для большинства правил используются некоторые шаблоны. Но можно указывать и полный путь до конкретного файла, как сделано в 15 и 16 строках. Git всегда мягко применяет эти правила. Если вы указали, что необходимо игнорировать просто строку test - то он будет игнорировать и директории (вместе со вложенными файлами) и файлы, которые называются test, вне зависимости, где они располагаются. Если вы хотите ограничиться только корневым уровнем в репозитории - необходимо явно это указать поставив “/” перед шаблоном.
К шаблонам в файле .gitignore применяются следующие правила:
Шаблон **/ доступен в Git, начиная с версии 1.8.2.
Временно игнорировать изменения в файле можно командой:
Если файл попал в индекс и нужно убрать его из индекса:
Однако, стоит быть осторожнее с командой git rm.
Однако, стоит обратить внимание на то, что файл .gitignore не решение от всех проблем. То есть он проблему то решает, но не стоит его всегда использовать. Иногда встречаю в файле .gitignore то, чего там быть никак не должно. Давайте представим такую ситуацию: Я и вы работаем в одной команде над одним проектом. Я в своей работе использую vim, а вы, например, IDE от JetBrains. У меня временные файлы создаются в специальном каталоге в профиле пользователя, тем самым в директории проекта я никак не создаю временных файлов при редактировании проекта. У вас же в проекте создается директория .idea, в которой лежат конфиги вашей IDE для этого проекта. Это часть вашего рабочего окружения и она никаким боком не относится к проекту и репозиторию. По идее, вы можете добавить строчку /.idea в файл .gitignore в проекте, однако, если над проектом работает несколько человек и каждый из них добавит конфиги своего окружения в .gitignore, то он превратится в нечитаемую помойку.
Что делать и как быть? Есть несколько разных способов игнорирования файлов в git.
Этот как раз тот самый .gitignore, в корне репозитория. В него стоит помещать в основном только то, что имеет непосредсвенное оношение к проекту и его архитектуре. Например, у всех участников проекта есть директория с локами, или у всех в одном и том же месте создаются временные файлы. Если эти правила имеют отношение ко всем участникам проекта - то стоит правила игнорирования разместить в .gitignore, который будет распространяться вместе с репозиторием.
Когда у вас несколько проектов и везде создается что-либо, что вы не хотите коммитить(например, *.swp файлы Vim) используйте ~/.gitconfig. Вышеприведённый пример папки .idea, которая создается для каждого проекта как раз подходит сюда. Создайте файл .gitexcludes и выполните:
или вручную добавьте в ~/.gitconfig:
Иногда возможны случаи, когда у вас есть файлы, которые специфичны для данного проекта и для вашего рабочего окружения (например, логи third-party утилиты, которую вы любите использовать и используете только в этом проекте). К проекту отнести шаблон игнорирования - не верно. Вы не используете ее во всех проектах и значит игнорировать глобально на всем компьютере - тоже не стоит. В данном случае используйте .git/info/exclude. Этот файл не коммитится и остается только в локальном репозитории.
Сразу после сохранения ~/.gitconfig вы не должны видеть указанные файлы/папки в списке Untracked files.
Я люблю Git, но и он порой непоследователен в мелочах. Обращаю ваше внимание на то, что в первом случае мы редактируем файл.git/info/exclude (без s на конце), а во втором используем опцию excludeSfile (c s в середине). Не потеряйте время из-за возможной опечатки.
Работа с Git в большинстве случаев означает работу в команде, поэтому не усложняйте жизнь тем, кто будет работать с вами деталями вашего рабочего окружения. Хороших коммитов! :)
17. Просмотр списка веток
Можно просматривать полный список веток, используя параметр branch . Команда отобразит все ветки, отметит текущую звёздочкой (*) и выделит её цветом.
Также можно вывести список удалённых веток с помощью флага -a .
16. Создание новой ветки и переход в неё
Создать новую ветку можно с помощью параметра branch , указав имя ветки.
Но Git не переключится на неё автоматически. Для автоматического перехода нужно добавить флаг -b и параметр checkout .
4. Добавление отдельных файлов или всех файлов в область подготовленных файлов
Добавить отдельный файл в область подготовленных файлов можно параметром add с указанием имени файла. Просто замените somefile.js на актуальное имя.
Кроме того, можно добавить все файлы и папки в эту область, предоставив wildcard . вместо имени файла:
30. Использование перебазирования
Для доступа к этой функции используйте параметр rebase с указанием имени ветки. Перебазирование — это процесс объединения или перемещения последовательности коммитов на новый родительский снимок.
Эта команда изменит основу ветки с одного коммита на другой, как если бы вы начали ветку с другого коммита. В Git это достигается за счёт создания новых коммитов и применения их к указанному базовому коммиту. Необходимо понимать, что, хотя ветка и выглядит такой же, она состоит из совершенно новых коммитов.
Просмотр индексированных и неиндексированных изменений
Допустим, вы снова изменили и проиндексировали файл README , а затем изменили файл CONTRIBUTING.md без индексирования. Если вы выполните команду git status , вы опять увидите что-то вроде:
Чтобы увидеть, что же вы изменили, но пока не проиндексировали, наберите git diff без аргументов:
Эта команда сравнивает содержимое вашего рабочего каталога с содержимым индекса. Результат показывает ещё не проиндексированные изменения.
Если вы хотите посмотреть, что вы проиндексировали и что войдёт в следующий коммит, вы можете выполнить git diff --staged . Эта команда сравнивает ваши проиндексированные изменения с последним коммитом:
Важно отметить, что git diff сама по себе не показывает все изменения сделанные с последнего коммита — только те, что ещё не проиндексированы. Такое поведение может сбивать с толку, так как если вы проиндексируете все свои изменения, то git diff ничего не вернёт.
Другой пример: вы проиндексировали файл CONTRIBUTING.md и затем изменили его, вы можете использовать git diff для просмотра как проиндексированных изменений в этом файле, так и тех, что пока не проиндексированы. Если наше окружение выглядит вот так:
Используйте git diff для просмотра непроиндексированных изменений
а так же git diff --cached для просмотра проиндексированных изменений ( --staged и --cached синонимы):
Мы будем продолжать использовать команду git diff различными способами на протяжении всей книги. Существует еще один способ просматривать эти изменения, если вы предпочитаете графический просмотр или внешнюю программу просмотра различий, вместо консоли. Выполнив команду git difftool вместо git diff , вы сможете просмотреть изменения в файле с помощью таких программ как emerge, vimdiff и других (включая коммерческие продукты). Выполните git difftool --tool-help чтобы увидеть какие из них уже установлены в вашей системе.
28. Отправка новой ветки в удалённый репозиторий
Передать новую ветку в удалённый репозиторий можно параметром push с флагом -u , указав имя репозитория и имя ветки.
Изменённые файлы в рабочей директории
Для отмены изменений в таких файлах используется команда git restore . Причём git сам напоминает об этом при проверке статуса:
24. Получение дополнительных сведений об удалённом репозитории
Получить подробные сведения об удалённом репозитории можно с помощью параметра remote show с указанием имени репозитория — например, origin .
Эта команда отображает список веток, связанных с удалённым репозиторием, а также рабочих станций, подключённых для получения и отправки файлов.
Удаление файлов
Для того чтобы удалить файл из Git, вам необходимо удалить его из отслеживаемых файлов (точнее, удалить его из вашего индекса) а затем выполнить коммит. Это позволяет сделать команда git rm , которая также удаляет файл из вашего рабочего каталога, так что в следующий раз вы не увидите его как «неотслеживаемый».
Если вы просто удалите файл из своего рабочего каталога, он будет показан в секции «Changes not staged for commit» (измененные, но не проиндексированные) вывода команды git status :
Затем, если вы выполните команду git rm , удаление файла попадёт в индекс:
После следующего коммита файл исчезнет и больше не будет отслеживаться. Если вы изменили файл и уже проиндексировали его, вы должны использовать принудительное удаление с помощью параметра -f . Это сделано для повышения безопасности, чтобы предотвратить ошибочное удаление данных, которые ещё не были записаны в снимок состояния и которые нельзя восстановить из Git.
Другая полезная штука, которую вы можете захотеть сделать — это удалить файл из индекса, оставив его при этом в рабочем каталоге. Другими словами, вы можете захотеть оставить файл на жёстком диске, но перестать отслеживать изменения в нём. Это особенно полезно, если вы забыли добавить что-то в файл .gitignore и по ошибке проиндексировали, например, большой файл с логами, или кучу промежуточных файлов компиляции. Чтобы сделать это, используйте опцию --cached :
В команду git rm можно передавать файлы, каталоги или шаблоны. Это означает, что вы можете сделать что-то вроде:
Обратите внимание на обратный слеш ( \ ) перед * . Он необходим из-за того, что Git использует свой собственный обработчик имён файлов вдобавок к обработчику вашего командного интерпретатора. Эта команда удаляет все файлы, имеющие расширение .log и находящиеся в каталоге log/ . Или же вы можете сделать вот так:
Эта команда удаляет все файлы, имена которых заканчиваются на ~ .
22. Добавление удалённого репозитория
Добавить удалённый репозиторий можно параметром remote add , указав shortname и url требуемого репозитория.
▍ Спасибо за внимание!
Вы узнали 30 основных команд интерфейса командной строки Git. Теперь, при условии регулярной практики, у вас есть всё необходимое, чтобы достичь мастерства в управлении репозиториями GitHub.
Сегодня мы поговорим о удалении и перемещении файлов, находящихся в git репозитории. Я расскажу о том, как обычно выполняют эти операции, что при этом происходит и как лучше их выполнять.
18. Удаление ветки
Для принудительного удаления ветки используется флаг -D с заглавной буквой. В этом случае ветка будет удалена независимо от текущего статуса, без предупреждений.
Вышеуказанные команды удаляют только локальную копию ветки. В удалённом репозитории она может сохраниться. Если хотите стереть удалённую ветку, выполните следующую команду:
Изменения, подготовленные к коммиту
С файлами, подготовленными к коммиту, можно поступить по-разному. Первый вариант — отменить изменения совсем, второй — отменить только индексацию, не изменяя файлы в рабочей директории. Второе полезно в том случае, если изменения нам нужны, но мы не хотим их коммитить сейчас.
И здесь снова помогает Git. При выводе статуса он показывает нужную нам команду для перевода изменений в рабочую директорию:
Теперь, если нужно, можно выполнить git restore и окончательно отменить изменения в выбранных файлах.
Самостоятельная работа
Выполните все шаги из урока
Вам ответят команда поддержки Хекслета или другие студенты.
Нашли опечатку или неточность?
Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.
Что-то не получается или материал кажется сложным?
- задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
- расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
- изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Урок «Как эффективно учиться на Хекслете»
- Вебинар «Как самостоятельно учиться»
▍ Разница между revert и reset
Команда git revert отменяет изменения, записанные только одним коммитом. Она не откатывает проект к более раннему состоянию, удаляя все последующие коммиты, как это делает команда git reset .
У команды revert есть два крупных преимущества по сравнению с reset. Во-первых, она не меняет историю проекта и производит операцию, безопасную для коммитов. Во-вторых, её объектом выступает конкретный коммит, созданный в любой момент истории, а git reset всегда берёт за точку отсчёта текущий коммит. К примеру, если нужно отменить старый коммит с помощью git reset, придётся удалить все коммиты, поданные после целевого, а затем выполнить их повторно. Следовательно, команда git revert — гораздо более удобный и безопасный способ отмены изменений.
7. Просмотр истории коммитов с изменениями
Просматривать изменения, внесённые в репозиторий, можно с помощью параметра log . Он отображает список последних коммитов в порядке выполнения. Кроме того, добавив флаг -p , вы можете подробно изучить изменения, внесённые в каждый файл.
29. Удаление удалённой ветки
Чтобы избавиться от удалённой ветки, используйте параметр push с флагом --delete , указав имя удалённого репозитория и имя ветки.
26. Получение изменений из удалённого репозитория
Для загрузки изменений из удалённого репозитория используется параметр pull . Он скачивает копию текущей ветки с указанного удалённого репозитория и объединяет её с локальной копией.
Также можно просмотреть подробные сведения о загруженных файлах с помощью флага --verbose .
23. Просмотр удалённых URL-адресов
Просматривать удалённые URL-адреса можно параметром remote с флагом -v . Этот параметр отображает удалённые подключения к другим репозиториям.
Такая команда открывает доступ к интерфейсу управления удалёнными записями, которые хранятся в файле .git/config репозитория.
30 основных команд, которые сделают из вас мастера Git
Сокращенный вывод статуса
Вывод команды git status довольно всеобъемлющий и многословный. Git также имеет флаг вывода сокращенного статуса, так что вы можете увидеть изменения в более компактном виде. Если вы выполните git status -s или git status --short вы получите гораздо более упрощенный вывод:
Новые неотслеживаемые файлы помечены ?? слева от них, файлы добавленные в отслеживаемые помечены A , отредактированные файлы помечены M и так далее. В выводе содержится два столбца — в левом указывается статус файла, а в правом модифицирован ли он после этого. К примеру в нашем выводе, файл README модифицирован в рабочем каталоге, но не проиндексирован, а файл lib/simplegit.rb модифицирован и проиндексирован. Файл Rakefile модифицирован, проиндексирован и ещё раз модифицирован, таким образом на данный момент у него есть те изменения, которые попадут в коммит, и те, которые не попадут.
8. Просмотр заданного коммита
Просмотреть полный список изменений, внесённых конкретным коммитом, можно с помощью параметра show , указав идентификатор или хеш коммита. Значение хеша уникально для каждого коммита, созданного в вашем репозитории.
Также можно использовать сокращённый хеш.
1. Как задать имя пользователя и адрес электронной почты
Имя пользователя нужно, чтобы привязывать коммиты к вашему имени. Это не то же самое, что имя пользователя учётной записи GitHub, с помощью которого выполняется вход в профиль на GitHub. Задать или изменить имя пользователя можно с помощью команды git config . Новое имя будет автоматически отображаться в последующих коммитах, отправленных на GitHub через командную строку. Если хотите скрыть своё реальное имя, можно использовать в качестве имени пользователя Git произвольный набор символов.
Кроме того, командой git config можно изменять адрес электронной почты, привязанный к вашим коммитам Git. Новый адрес электронной почты будет автоматически отображаться во всех дальнейших коммитах, поданных на GitHub через командную строку.
Перемещение файлов
Что касается перемещения файлов - то возможны 3 самых частых случая:
- Файл был перемещен в другую директорию
- Файл был переименован
- Любое из предыдущих действий + при этом файл был отредактирован.
А теперь, давайте абстрагируемся от того, как бы git мог это обработать и опишем эти действия при помощи команд:
Перемещаем файл в новую директорию mv file.txt new_dir/ Теперь git видит, что у него один файл удален ( file.txt ) и один не отслеживается ( new_dir/file.txt ) Зафиксируем удаление файла file.txt git add file.txt Зафиксируем добавление файла new_dir/file.txt под версионный контроль git add new_dir/file.txt
То есть, мы выполнили 3 действия, для того, чтобы зафиксировать перемещение файла в другую директорию (в случае с переименованием файла будет то же самое). git предоставляет 1 команду взамен этим 3-м git mv file.txt new_dir/txt
Как в первом случае, так и во втором, git заметит то, что файл был перемещен (переименован) и будет опираться на эту информацию в будущем. Например, если кто-то отредактирует в будущем файл, который располагался по старому пути, при мерже или ребейзе git определит, что файл был перемещен и, если сможет - то автоматически применит изменения к новому файлу по новому пути. Если не сможет применить изменения автоматически - то в информации о конфликте он скажет, куда был перемещен файл и вы сможете проще разрешить конфликт.
Однако, git не фиксирует факт перемещения файла, если при перемещении он был существенно отредактирован. В таком случаен он зафиксирует удаление первого файла и добавление второго. В случае, описанном выше, это не хорошо, поэтому лучше взять за правило сначала делать коммит, в котором файл перемещается без изменений, а потом делать коммит, который вносит изменения в файл, который располагается по новому пути. Это убережет вас в будущем от проблем с разрешением конфликтов. Или, может быть более неприятная ситуация - если вы будете выполнять ребейз относительно ветки, в которой файл был отредактирован ДО того, как вы его переместили - вы можете и не узнать о том, что файл был отредактирован и, тем самым, просто потеряете изменения, выполненные в нем (или у вас окажется два файла в репозитории - один старый, второй новый).
На этом я закончу знакомство с этими операциями. Не забудьте прочесть справку по командам перед выполнением тестового задания.
Одна из ключевых возможностей Git — "откат" любых сделанных изменений буквально одной командой. Такое практически невозможно сделать без использования системы контроля версий. Только если помнить все изменения наизусть. В этом уроке мы поговорим про откат изменений, которые сделаны в рабочей директории, но ещё не попали в коммит.
Важно! Откат незакоммиченных изменений безвозвратен. Не существует никакой физической возможности получить эти изменения обратно, поэтому будьте крайне осторожны.
Неотслеживаемые файлы
Самая простая ситуация. Вы добавили новые файлы в репозиторий (или сгенерировали их как-то) и поняли, что они вам не нужны. В этом случае можно выполнить очистку:
Забавный факт: про эту команду знает не так много программистов. Вы можете удивить даже опытных ребят.
Перемещение файлов
В отличие от многих других систем контроля версий, Git не отслеживает перемещение файлов явно. Когда вы переименовываете файл в Git, в нём не сохраняется никаких метаданных, говорящих о том, что файл был переименован. Однако, Git довольно умён в плане обнаружения перемещений постфактум — мы рассмотрим обнаружение перемещения файлов чуть позже.
Таким образом, наличие в Git команды mv выглядит несколько странным. Если вам хочется переименовать файл в Git, вы можете сделать что-то вроде:
и это отлично сработает. На самом деле, если вы выполните что-то вроде этого и посмотрите на статус, вы увидите, что Git считает, что произошло переименование файла:
Однако, это эквивалентно выполнению следующих команд:
Git неявно определяет, что произошло переименование, поэтому неважно, переименуете вы файл так или используя команду mv . Единственное отличие состоит лишь в том, что mv — одна команда вместо трёх — это функция для удобства. Важнее другое — вы можете использовать любой удобный способ для переименования файла, а затем воспользоваться командами add/rm перед коммитом.
Git — самая популярная в мире распределённая система контроля версий. Линус Торвальдс, разработчик ядра ОС Linux, создал этот инструмент ещё в 2005 году, а сегодня Git активно поддерживается как проект с открытым исходным кодом. Огромное количество открытых и коммерческих проектов используют Git для контроля версий.
В данной статье перечисляются самые основные команды, которые следует знать разработчику, чтобы освоить управление репозиториями GitHub на высоком уровне. Ознакомиться с ними будет полезно как новичкам, так и опытным разработчикам.
3. Инициализация репозитория
Создать пустой репозиторий Git или вновь инициализировать существующий можно параметром init . При инициализации он создаст скрытую папку. В ней содержатся все объекты и ссылки, которые Git использует и создаёт в истории работы над проектом.
27. Слияние удалённого репозитория с локальным
Слияние удалённого репозитория с локальным выполняется параметром merge с указанием имени удалённого репозитория.
11. Переименование файлов
Переименовать файл или папку можно параметром mv . Для него указывается источник source и назначение destination . Источник — реально существующий файл или папка, а назначение — существующая папка.
При выполнении команды файл или папка, указанные как источник, будут перемещены в папку назначения. Индекс будет обновлён соответственно, но изменения нужно записать.
9. Просмотр изменений до коммита
Можно просматривать список изменений, внесённых в репозиторий, используя параметр diff . По умолчанию отображаются только изменения, не подготовленные для фиксации.
Для просмотра подготовленных изменений необходимо добавить флаг --staged .
Также можно указать имя файла как параметр и просмотреть изменения, внесённые только в этот файл.
Определение состояния файлов
Основной инструмент, используемый для определения, какие файлы в каком состоянии находятся — это команда git status . Если вы выполните эту команду сразу после клонирования, вы увидите что-то вроде этого:
Это означает, что у вас чистый рабочий каталог, другими словами — в нем нет отслеживаемых измененных файлов. Git также не обнаружил неотслеживаемых файлов, в противном случае они бы были перечислены здесь. Наконец, команда сообщает вам на какой ветке вы находитесь и сообщает вам, что она не расходится с веткой на сервере. Пока что это всегда ветка master , ветка по умолчанию; в этой главе это не важно. В главе Ветвление в Git будут рассмотрены ветки и ссылки более детально.
Предположим, вы добавили в свой проект новый файл, простой файл README . Если этого файла раньше не было, и вы выполните git status , вы увидите свой неотслеживаемый файл вот так:
Понять, что новый файл README неотслеживаемый можно по тому, что он находится в секции «Untracked files» в выводе команды status . Статус Untracked означает, что Git видит файл, которого не было в предыдущем снимке состояния (коммите); Git не станет добавлять его в ваши коммиты, пока вы его явно об этом не попросите. Это предохранит вас от случайного добавления в репозиторий сгенерированных бинарных файлов или каких-либо других, которые вы и не думали добавлять. Мы хотели добавить README, так давайте сделаем это.
25. Отправка изменений в удалённый репозиторий
Отправлять изменения в удалённый репозиторий можно параметром push с указанием имени репозитория и ветки.
Эта команда передаёт локальные изменения в центральный репозиторий, где с ними могут ознакомиться другие участники проекта.
10. Удаление отслеживаемых файлов из текущего рабочего дерева
Удалять файлы из текущего рабочего дерева можно с помощью параметра rm . При этом файлы удаляются и из индекса.
Можно также использовать маски файлов (например *.js) для удаления всех файлов, соответствующих критерию.
Удаление файлов
Для начала рассмотрим удаление файлов. Я упоминал про эту операцию, когда рассказывал про добавление изменений в репозиторий. В рамках того урока я говорил, что в git репозиторий данные только добавляются. В случае с обычным удалением файла это утверждение верно. Давайте рассмотрим такой пример:
У вас в проекте был файл, который при рефакторинге стал не нужен и вам нужно его удалить. Чаше всего получается так, что вы его сначала удаляете из рабочей директории, а потом уже добавляете в индекс информацию о том, что файл должен быть удален из репозитория. То есть это может быть описано следующими командами:
Результатом выполнения данных команд будет удаление файла из репозитория для коммита, который вы выполните на этом этапе и всех последующих коммитов. Это замечание важно тем, что для предыдущих коммитов этот файл будет находиться в репозитории. Аналогом этих двух команд является команда git rm file.txt . При этом в индекс сразу будет добавлена информация о том, что файл удален и не нужно будет выполнять команду git add .
Также вы можете не выполнять команду git add , а зафиксировать удаление файла непосредственно при выполнении коммита (git commit -a). Но я не советую вам использовать такой вариант (если вы действительно не хотите сделать именно это).
Если команде git rm в pathspec было указано название директории, то вам понадобится указать флаг -r для того, чтобы git рекурсивно удалил файлы, находящиеся в указанной директории.
Другая полезная штука, которую вы можете захотеть сделать — это удалить файл из индекса, оставив его при этом в рабочем каталоге. Другими словами, вы можете захотеть оставить файл на жестком диске, и убрать его из-под бдительного ока Git'а. Это особенно полезно, если вы забыли добавить что-то в файл .gitignore и по ошибке проиндексировали, например, большой файл с логами, или большое количество промежуточных файлов компиляции. Чтобы сделать это, используйте опцию --cached :
В случае, если вам необходимо полностью удалить файл из истории git - вам потребуется выполнить совсем не простую команду, которая будет приведена в расшифровке видео:
Она выполнит следующее - для каждого коммита в истории ветки удалит этот файл, если он присутствует. В итоге, у вас перезапишется история всего репозитория с момента появления этого файла. Поэтому, выполнять эту команду нужно только в том случае, если вам это действительно нужно и вы понимаете, что произойдет.
Для выполнения этого действия можно использовать и другие команды. Но мы не будем сейчас их всех рассматривать.
21. Прекращение слияния при конфликте
Прервать слияние в случае конфликта можно параметром merge с флагом --abort . Он позволяет остановить процесс слияния и вернуть состояние, с которого этот процесс был начат.
Также при конфликте слияния можно использовать параметр reset , чтобы восстановить конфликтующие файлы до стабильного состояния.
15. Откат заданного коммита
Откатить проект до заданного коммита можно с помощью параметра revert и идентификатора коммита. Создастся новый коммит — копия коммита с предоставленным идентификатором — и добавится к истории текущей ветки.
Определение состояния файлов
Основной инструмент, используемый для определения, какие файлы в каком состоянии находятся — это команда git status . Если вы выполните эту команду сразу после клонирования, вы увидите что-то вроде этого:
Это означает, что у вас чистый рабочий каталог, другими словами — в нем нет отслеживаемых измененных файлов. Git также не обнаружил неотслеживаемых файлов, в противном случае они бы были перечислены здесь. Наконец, команда сообщает вам на какой ветке вы находитесь и сообщает вам, что она не расходится с веткой на сервере. Пока что это всегда ветка master , ветка по умолчанию; в этой главе это не важно. В главе Ветвление в Git будут рассмотрены ветки и ссылки более детально.
Предположим, вы добавили в свой проект новый файл, простой файл README . Если этого файла раньше не было, и вы выполните git status , вы увидите свой неотслеживаемый файл вот так:
Понять, что новый файл README неотслеживаемый можно по тому, что он находится в секции «Untracked files» в выводе команды status . Статус Untracked означает, что Git видит файл, которого не было в предыдущем снимке состояния (коммите); Git не станет добавлять его в ваши коммиты, пока вы его явно об этом не попросите. Это предохранит вас от случайного добавления в репозиторий сгенерированных бинарных файлов или каких-либо других, которые вы и не думали добавлять. Мы хотели добавить README, так давайте сделаем это.
Игнорирование файлов
Зачастую, у вас имеется группа файлов, которые вы не только не хотите автоматически добавлять в репозиторий, но и видеть в списках неотслеживаемых. К таким файлам обычно относятся автоматически генерируемые файлы (различные логи, результаты сборки программ и т. п.). В таком случае, вы можете создать файл .gitignore . с перечислением шаблонов соответствующих таким файлам. Вот пример файла .gitignore :
Первая строка предписывает Git игнорировать любые файлы заканчивающиеся на «.o» или «.a» — объектные и архивные файлы, которые могут появиться во время сборки кода. Вторая строка предписывает игнорировать все файлы заканчивающиеся на тильду ( ~ ), которая используется во многих текстовых редакторах, например Emacs, для обозначения временных файлов. Вы можете также включить каталоги log, tmp или pid; автоматически создаваемую документацию; и т. д. и т. п. Хорошая практика заключается в настройке файла .gitignore до того, как начать серьёзно работать, это защитит вас от случайного добавления в репозиторий файлов, которых вы там видеть не хотите.
К шаблонам в файле .gitignore применяются следующие правила:
Стандартные шаблоны являются глобальными и применяются рекурсивно для всего дерева каталогов.
Чтобы избежать рекурсии используйте символ слеш (/) в начале шаблона.
Чтобы исключить каталог добавьте слеш (/) в конец шаблона.
Можно инвертировать шаблон, использовав восклицательный знак (!) в качестве первого символа.
Glob-шаблоны представляют собой упрощённые регулярные выражения, используемые командными интерпретаторами. Символ ( * ) соответствует 0 или более символам; последовательность [abc] — любому символу из указанных в скобках (в данном примере a, b или c); знак вопроса ( ? ) соответствует одному символу; и квадратные скобки, в которые заключены символы, разделённые дефисом ( 1 ), соответствуют любому символу из интервала (в данном случае от 0 до 9). Вы также можете использовать две звёздочки, чтобы указать на вложенные каталоги: a/**/z соответствует a/z , a/b/z , a/b/c/z , и так далее.
Вот ещё один пример файла .gitignore :
В простейшем случае репозиторий будет иметь один файл .gitignore в корневом каталоге, правила из которого будут рекурсивно применяться ко всем подкаталогам. Так же возможно использовать .gitignore файлы в подкаталогах. Правила из этих файлов будут применяться только к каталогам, в которых они находятся. Например, репозиторий исходного кода ядра Linux содержит 206 файлов .gitignore .
Детальное рассмотрение использования нескольких .gitignore файлов выходит за пределы этой книги; детали доступны в справке man gitignore .
Отслеживание новых файлов
Для того чтобы начать отслеживать (добавить под версионный контроль) новый файл, используется команда git add . Чтобы начать отслеживание файла README , вы можете выполнить следующее:
Если вы снова выполните команду status , то увидите, что файл README теперь отслеживаемый и добавлен в индекс:
Вы можете видеть, что файл проиндексирован, так как он находится в секции «Changes to be committed». Если вы выполните коммит в этот момент, то версия файла, существовавшая на момент выполнения вами команды git add , будет добавлена в историю снимков состояния. Как вы помните, когда вы ранее выполнили git init , затем вы выполнили git add (файлы) — это было сделано для того, чтобы добавить файлы в вашем каталоге под версионный контроль. Команда git add принимает параметром путь к файлу или каталогу, если это каталог, команда рекурсивно добавляет все файлы из указанного каталога в индекс.
12. Отмена подготовленных и неподготовленных изменений
Восстановить файлы рабочего дерева, не подготовленные к коммиту, можно параметром checkout . Для проведения операции требуется указать путь к файлу. Если путь не указан, параметр git checkout изменит указатель HEAD, чтобы задать указанную ветку как текущую.
Восстановить подготовленный файл рабочего дерева можно параметром reset . Потребуется указать путь к файлу, чтобы убрать его из области подготовленных файлов. При этом не будет производиться откат никаких изменений или модификаций — однако файл перейдёт в категорию не подготовленных к коммиту.
Если нужно выполнить это действие для всех подготовленных файлов, путь к ним указывать не надо.
Читайте также: