Архитектура Git с тремя деревьями
В Git вы можете отменить изменения, используя команду за которой следует идентификатор фиксации.
принимает дополнительные аргументы, которые позволяют вам управлять поведением команды. Чтобы лучше понять, как работает давайте поговорим о трех разных деревьях Git. Архитектура с тремя деревьями — ключевая концепция системы управления Git. Они называются деревьями, потому что представляют собой наборы файлов.
Git управляет следующими тремя деревьями:
- Рабочий каталог — каталог, включающий все подкаталоги и файлы в локальной файловой системе, связанной с репозиторием. Его часто называют «рабочим деревом». Рабочий каталог — это что-то вроде песочницы, где вы можете протестировать изменения перед их фиксацией в промежуточном индексе.
- Индекс — это дерево отслеживает новые или измененные файлы, которые были добавлены в индекс с помощью , для включения в следующую фиксацию. Его часто называют «промежуточной областью» или «промежуточным индексом».
- — указатель на вашу последнюю фиксацию в текущей ветке.
Команда имеет три аргумента, которые соответствуют трем деревьям:
- — обновляет указатель для данной фиксации. Рабочий каталог и Индекс не меняются.
- — обновляет указатель и сбрасывает индекс до указанной фиксации. Рабочий каталог остается нетронутым. Это режим работы по умолчанию для команды .
- — обновляет указатель и сбрасывает индекс и рабочий каталог до указанной фиксации. Будьте особенно осторожны при использовании этой опции, так как все локальные изменения, которые вы не зафиксировали, будут перезаписаны и потеряны.
Отмена последней фиксации
Чтобы отменить последнюю фиксацию без потери изменений, внесенных вами в локальные файлы и индекс, вызовите с параметром за которым следует :
— это переменная, указывающая на предыдущую фиксацию. Приведенная выше команда перемещает текущую ветвь назад на одну фиксацию, эффективно отменяя последнюю фиксацию. Если вы запустите команду , вы увидите, что измененные файлы перечислены как незафиксированные изменения.
Чтобы обновить указатель для сброса индекса, запустите с или без параметра:
Измененные файлы сохраняются, но, в отличие от предыдущего примера, теперь изменения не ставятся для фиксации.
Если вы не хотите сохранять изменения, внесенные в файлы, вызовите команду с параметром :
Перед выполнением аппаратного сброса убедитесь, что вам больше не нужны изменения.
Общее
Git — система контроля версий (файлов). Что-то вроде возможности сохраняться в компьютерных играх (в Git эквивалент игрового сохранения — коммит)
Важно: добавление файлов к «сохранению» двухступенчатое: сначала добавляем файл в индекс (), потом «сохраняем» ()
Любой файл в директории существующего репозитория может находиться или не находиться под версионным контролем (отслеживаемые и неотслеживаемые).
Отслеживаемые файлы могут быть в 3-х состояниях: неизменённые, изменённые, проиндексированные (готовые к коммиту).
Ключ к пониманию
Ключ к пониманию концепции git — знание о «трех деревьях»:
- Рабочая директория — файловая система проекта (те файлы, с которыми вы работаете).
- Индекс — список отслеживаемых git-ом файлов и директорий, промежуточное хранилище изменений (редактирование, удаление отслеживаемых файлов).
- Директория — все данные контроля версий этого проекта (вся история разработки: коммиты, ветки, теги и пр.).
Коммит — «сохранение» (хранит набор изменений, сделанный в рабочей директории с момента предыдущего коммита). Коммит неизменен, его нельзя отредактировать.
У всех коммитов (кроме самого первого) есть один или более родительских коммитов, поскольку коммиты хранят изменения от предыдущих состояний.
Простейший цикл работ
- Редактирование, добавление, удаление файлов (собственно, работа).
- Индексация/добавление файлов в индекс (указание для git какие изменения нужно будет закоммитить).
- Коммит (фиксация изменений).
- Возврат к шагу 1 или отход ко сну.
Указатели
- — указатель на текущий коммит или на текущую ветку (то есть, в любом случае, на коммит). Указывает на родителя коммита, который будет создан следующим.
- — указатель на коммит, с которого вы только что переместили (командой , например).
- Ветка (, etc.) — указатель на коммит. При добавлении коммита, указатель ветки перемещается с родительского коммита на новый.
- Теги — простые указатели на коммиты. Не перемещаются.
Перед началом работы нужно выполнить некоторые настройки:
Если вы в Windows:
Длинный вывод в консоли: Vim
Если нужно что-то написать, нажмите i — это переход в режим вставки текста. Если нужно сохранить изменения, перейдите в командный режим и наберите :w.
# Нажатия кнопок ESC — переход в командный режим i — переход в режим редактирования текста ZQ (зажат Shift, поочередное нажатие) — выход без сохранения ZZ (зажат Shift, поочередное нажатие) — сохранить и выйти ```bash # Нажатия кнопок ESC — переход в командный режим i — переход в режим редактирования текста ZQ (зажат Shift, поочередное нажатие) — выход без сохранения ZZ (зажат Shift, поочередное нажатие) — сохранить и выйти # Ввод в командном режиме :q! — выйти без сохранения :wq — сохранить файл и выйти :w filename.txt — сохранить файл как filename.txt
Принудительная публикация
Git предотвращает перезапись истории центрального репозитория, отклоняя push-запросы, если нельзя выполнить их ускоренное слияние. Так, если история удаленного репозитория отличается от вашей истории, необходимо загрузить удаленную ветку командой pull и выполнить ее слияние с локальной веткой командой merge, а затем попробовать выполнить команду push еще раз. Это похоже на то, как в SVN необходимо синхронизироваться с центральным репозиторием с помощью команды перед тем, как сделать коммит набора изменений.
Флаг отменяет это поведение и подгоняет ветку удаленного репозитория под вашу локальную ветку, удаляя любые вышестоящие изменения, которые могли быть внесены с момента последнего выполнения вами команды pull. Принудительное использование команды push оправдано лишь в том случае, когда вы понимаете, что только что опубликованные вами коммиты были не совсем правильными и вы исправили их с помощью команды или интерактивного перебазирования. При этом прежде, чем использовать опцию , вы должны быть абсолютно уверены в том, что никто из участников вашей команды не забирал эти коммиты с помощью команды pull.
Как сбросить файл к состоянию в коммите, если изменения уже подготовлены командой git add?
В случае, если в файл были внесены изменения и эти изменения уже подготовлены для фиксации в коммит с помощью команды git add, то в этом случае для сброса файла в исходное состояние нужно:
- Убрать файл из подготовленного состояния к фиксации в коммите, т.е. перевести файл из состояния staged.
- Сбросить файл к исходному состоянию.
Для примера рассмотрим ситуацию, когда в нашем локальном репозитории есть файл second.php , в который были внесены изменения и более того эти изменения были подготовлены к фиксации в коммит при помощи команды $ git add *.php .
В репозитории есть модифицированный файл со статусом staged, подготовленный для фиксации изменений в следующий коммит.
Для того, чтобы такой модифицированный файл сбросить к первоначальному состоянию, вначале следует перевести его в состояние not staged. Делается это при помощи команды:
$ git reset HEAD second.php
На иллюстрации выше к файлу применена команда $ git reset HEAD , а после этого команда $ git satus в результате вывода информации которой видно, что файл second.php теперь просто является модифицированным
Кстати, обратите внимание, что система контроля версий git сама в выводе команды status подсказывает, что файл можно сбросить к исходному состоянию командой $ git checkout — или подготовить изменения к фиксации в коммит при помощи $ git add
Для сброса файла в исходное состояние мы воспользуемся командой:
$ git checkout — second.php
Файл сброшен к исходному состоянию при помощи команды git checkout
Вывод: Для сброса команды к состоянию сохраненному в последнем коммите применяется команда $ git checkout — . Если изменения в файле уже подготовлены для фиксации в следующем коммите, то перед сбросом следует воспользоваться также командой git reset HEAD .
Подмодули
Клонирование репозитория с подмодулями
При клонировании репозитория вам необходимо инициализировать и обновить подмодули:
Запуск данной команды эквивалентен запуску команды:
после обычного клонирования репозитория
Обновление подмодулей
Подмодуль ссылается на конкретную коммит в другом репозитории. Чтобы получить
точное состояние всех подмодулей необходимо запустить:
Для получения состояния последнего коммита всех подмодулей необходимо выполнить
следующую команду:
или использовать аргументы по умолчанию команды git pull:
Эта команда просто обновляет локальную рабочую копию. При запуске команды git status
каталоги подмодулей будут показаны изменёнными. Чтобы обновить репозиторий необходимо
зафиксировать изменения:
Для получения состояние последнего коммита конкретного подмодуля необходимо использовать команду:
Добавление подмодулей
В текущий проект можно включить другой репозиторий Git в качестве папки, отслеживаемый Git:
После этого необходимо добавить и зафиксировать новый файл .gitmodules. В нём описано
какие подмодули следует клонировать при запуске команды git submodule update
12 ответов
Лучший ответ
Запуск выполняет следующие задачи по порядку:
Шаг слияния объединяет ветки, которые были настроены для слияния в вашей конфигурации. Вы хотите отменить этап слияния , но, вероятно, не выборку (не имеет большого смысла и в этом нет необходимости).
Чтобы отменить слияние , используйте для сброса локального репозитория в предыдущее состояние; используйте git-reflog, чтобы найти SHA- 1 из предыдущего состояния, а затем сбросить на него.
Предупреждение
Команды, перечисленные в этом разделе, удаляют все незафиксированные изменения, что может привести к потере работы:
В качестве альтернативы можно выполнить сброс на определенный момент времени, например:
1679
Dave Jarvis
20 Сен 2019 в 19:51
То же, что и ответ jkp, но вот полная команда:
Где a0d3fe6 находится путем выполнения
И глядя на точку, в которой вы хотите отменить.
402
Jeffrey Sun
22 Июл 2014 в 00:39
Более современный способ отменить слияние:
И немного более старый способ:
Старый способ, описанный в предыдущих ответах (предупреждение: все ваши локальные изменения будут отменены):
Но на самом деле стоит отметить, что эквивалентен только при наличии . Это можно прочитать в справке git для команды слияния.
После неудачного слияния, когда нет , неудачное слияние можно отменить с помощью , но не обязательно с помощью , поэтому они не только старый и новый синтаксис для то же самое . Вот почему я считаю гораздо более полезным в повседневной работе.
148
Martin G
20 Май 2015 в 09:17
Оно работает первое использование:
Найдите свой SHA предыдущего состояния и создайте (пример HEAD @ {1})
72
Ezequiel García
8 Мар 2016 в 17:00
Если у вас есть gitk (попробуйте запустить «gitk —all из командной строки git»), это просто. Просто запустите его, выберите фиксацию, к которой вы хотите выполнить откат (щелкните правой кнопкой мыши), и выберите «Сбросить главную ветку сюда». Если у вас нет незавершенных изменений, выберите «жесткий» вариант.
42
Samuel Carrijo
3 Авг 2009 в 16:49
Предположим, что был последним идентификатором фиксации перед выполнением . Что вам нужно, чтобы отменить последнее нажатие, так это
Бонус :
Говоря о вытягивании, я хотел бы поделиться интересным трюком,
Эта команда выше — самая полезная команда в моей жизни с git, которая сэкономила много времени.
Прежде чем отправлять новую фиксацию на сервер, попробуйте эту команду, и она автоматически синхронизирует последние изменения сервера (с помощью fetch + merge) и поместит вашу фиксацию наверху в журнале git. Не нужно беспокоиться о ручном извлечении / слиянии.
Подробности можно найти на странице: http://gitolite.com/git-pull—rebase
42
Community
20 Июн 2020 в 09:12
Это самый простой способ отменить изменения.
Сделайте резервную копию измененных файлов, поскольку при этом будут удалены вновь созданные файлы и папки .
Где — ваш {идентификатор фиксации}
20
Manish Goswami
5 Дек 2019 в 07:25
Ты можешь сделать
Так как «pull» или «merge» устанавливают ORIG_HEAD как текущее состояние перед выполнением этих действий.
18
Orlando
19 Авг 2015 в 17:02
Если происходит сбой слияния, что является наиболее частой причиной желания отменить , запуск делает именно то, что и ожидалось: сохраняют выбранные файлы, но отменяют слияние, которое предпринята попытка слияния. Затем можно решить, что делать без беспорядка, который иногда создает . И не нужно искать точный идентификатор фиксации, который требуется , упомянутым во всех остальных ответах.
7
Davide
24 Сен 2018 в 17:35
git pull выполните операцию ниже.
Чтобы отменить вытягивание, выполните любую операцию:
Улучшение:
В следующий раз используйте вместо .. его сервер синхронизации измените, выполнив (выборка и слияние).
5
GolamMazid Sajib
5 Апр 2020 в 13:38
Попробуй бежать
3
henrique_ms
27 Авг 2020 в 18:06
Самый быстрый способ решить эту проблему —
3
Azeez Bello
13 Мар 2021 в 16:33
11 ответов
Лучший ответ
Что вам нужно сделать, так это создать новую фиксацию с теми же деталями, что и текущая фиксация , но с родительским элементом, как в предыдущей версии . переместит указатель ветки так, чтобы следующая фиксация произошла поверх другой фиксации, где сейчас находится заголовок текущей ветки.
2696
banan3’14
1 Июн 2019 в 02:24
Используйте журнал ссылок:
После этого вы должны иметь все свои ранее внесенные изменения только в вашу рабочую копию и можете снова зафиксировать
Чтобы увидеть полный список предыдущих типов индексов
157
knittl
22 Сен 2009 в 10:14
Если вы отправили фиксацию на удаленный доступ, а затем ошибочно внесли изменения в эту фиксацию, это решит вашу проблему. Выполните , чтобы найти SHA перед фиксацией. (предполагается, что удаленный объект имеет имя origin). Теперь выполните эту команду, используя этот SHA.
25
David Sopko
19 Авг 2019 в 22:39
Вы всегда можете разделить коммит, Из руководства
- Запустите интерактивную перебазировку с помощью git rebase -i commit ^, где фиксация — это фиксация, которую вы хотите разделить. Фактически, подойдет любой диапазон фиксации, если он содержит эту фиксацию.
- Отметьте коммит, который вы хотите разделить, действием «редактировать».
- Когда дело доходит до редактирования этого коммита, выполните git reset HEAD ^. Эффект состоит в том, что ГОЛОВКА перематывается на единицу, и индекс следует ее примеру. Однако рабочее дерево остается прежним.
- Теперь добавьте изменения в индекс, которые вы хотите иметь при первой фиксации. Для этого вы можете использовать git add (возможно, интерактивно) или git-gui (или оба).
- Зафиксируйте текущий индекс с любым подходящим сообщением фиксации.
- Повторяйте последние два шага, пока ваше рабочее дерево не станет чистым.
- Продолжите перебазирование с помощью git rebase —continue.
24
Arkaitz Jimenez
22 Сен 2009 в 10:01
Возможно, стоит отметить, что если вы все еще находитесь в редакторе с сообщением о фиксации, вы можете удалить сообщение о фиксации, и оно прервет выполнение команды .
23
Justin Schulz
3 Мар 2017 в 18:45
Ни один из этих ответов с использованием у меня не сработал, поэтому вот мое решение:
Теперь ваша промежуточная среда будет содержать все изменения, которые вы случайно слили с фиксацией c296452.
21
Oisín Foley
30 Янв 2021 в 19:49
Может быть, можно использовать , чтобы получить два коммита до и после поправки.
Затем используйте , чтобы получить разницу между изменениями до и после поправок.
Затем используйте , чтобы вернуться к перед фиксацией
И последнее, используйте , чтобы применить реальные изменения, которые вы сделали.
Это решает мою проблему.
17
utzcoz
19 Янв 2017 в 07:34
Вы можете сделать следующее, чтобы отменить
====================================
Теперь ваши изменения такие же, как и раньше. Итак, вы закончили отменить для
Теперь вы можете сделать , чтобы нажать на ветку.
10
kenorb
20 Фев 2019 в 17:47
Почти на 9 лет позже этого, но я не заметил, что этот вариант, упомянутый для выполнения того же самого (это своего рода комбинация нескольких из них, как и в верхнем ответе (https://stackoverflow.com/a/1459264/4642530 ).
Поиск всех оторвавшихся голов на ветке
Затем найдите хеш SHA1
Восстановить старый SHA1
Затем снова поднимите его.
Готово .
Это полностью вернет вас к старой фиксации.
(Включая дату предыдущей перезаписанной отдельной главы фиксации)
7
garrettmac
17 Июн 2018 в 21:55
-
Оформить заказ на временную ветку с последней фиксацией
-
Сбросить последнюю фиксацию
-
Теперь у вас будут все файлы вашего коммита, а также файлы предыдущего коммита. Проверить статус всех файлов.
-
Сбросьте файлы фиксации на этапе git.
(и т. Д.)
-
Повторно прикрепить эту фиксацию
-
Добавьте и зафиксируйте свои файлы в новом коммите.
3
Priyanshu Chauhan
4 Мар 2016 в 07:28
Простое решение Решение работает: если ваша фиксация HEAD синхронизирована с удаленной фиксацией.
- Создайте еще одну ветку в своей локальной рабочей области и синхронизируйте ее с удаленной веткой.
- Cherry выбирает фиксацию HEAD из ветки (где git commit —amend) была выполнена во вновь созданной ветке.
Выбранная вишня фиксация будет содержать только ваши последние изменения, а не старые изменения. Теперь вы можете просто переименовать этот коммит.
2
Vasudeva H
10 Сен 2020 в 13:47