Основные опции для работы с деревом и индексом
Всего есть четыре опции для управления тем, что происходит с вашим рабочим деревом и индексом во время исполнения команды reset.
Напомним, «индекс» — это «сцена» git’а, условное место, где происходят изменения, когда вы, например, выполняете команду, подготавливая свой коммит.
–hard — заставляет весь контент соответствовать коммиту, к которому вы сбрасываете (ресетите). Наверное, это самый простой для понимания ключ (опция). Все ваши локальные изменения исчезают. Основной случай применения — удалить вашу последнюю работу без переключения коммитов: git reset —hard означает git reset —hard HEAD, то есть, не изменяя ветку, избавиться от всех локальных изменений. Другой случай применения — перенести ветку из одного места в другое и держать при этом индекс/рабочее дерево в синхронизированном состоянии.
Напоминаем, эта опция действительно может привести к потере вашей работы, поскольку она модифицирует ваше рабочее дерево. Будьте на 100% уверены, что действительно хотите отказаться от локальных изменений, перед тем как выполнять.
- –mixed — это опция по умолчанию, то есть git reset означает. Эта команда сбрасывает индекс, но не рабочее дерево. Это означает, что все ваши файлы остаются неизменными, но любые изменения между текущим коммитом и коммитом, к которому вы сбрасываете, будут показаны как локальные изменения (или неотслеживаемые/untracked файлы) во время выполнения команды. Используйте эту опцию, когда вы вдруг поняли, что сделали неправильные коммиты, но все же хотите оставить некоторые изменения, которые сделали, чтобы их исправить и закоммитить снова. Чтобы закоммитить, вам придется добавить файлы в индекс снова командой.
- не изменяет индекс или рабочее дерево. Все ваши файлы остаются нетронутыми, как если бы вы использовали , но все изменения показываются как готовые к коммиту во время выполнения (то есть, зачекиненные и готовые к коммиту).
Используйте эту опцию, если осознали, что сделали несколько плохих коммитов, но сейчас состояние проекта правильное, и все что вам нужно — перекоммитить его еще раз. Индекс не тронут, поэтому вы можете закоммитить немедленно — результирующий коммит будет иметь то же содержание, которое было до выполнения reset.
–merge — эта опция добавлена в git относительно недавно, ее предназначение — прервать неудачное (failed) слияние (merge). Это бывает необходимо, потому что git merge в принципе позволяет осуществить попытку слияния с «грязным» рабочим деревом (грязным — в смысле «с локальными изменениями»), если эти изменения содержатся в файлах, не затронутых слиянием.
сбрасывает индекс (подобно опции — все изменения показываются как локальные изменения) и сбрасывает все файлы, затронутые слиянием, но не трогает остальные файлы. Это может позволить восстановить все до состояния, которое было до «плохого» слияния. Скорее всего, вы будете использовать это как(что означает ), потому что хотите сбросить только изменения, вызванные попыткой слияния, а не переместить ветку (указатель HEAD не изменился, поскольку слияние было неудачным). Если говорить более конкретно, представим, что мы поменяли файлы A и B и пытаемся «смерджиться» в ветку с измененными файлами C и D. Слияние «фейлится» по какой-либо причине, и мы решаем прервать его. Используем. Это приводит C и D обратно к состоянию, которое у них было в HEAD, но не затрагивает изменения в A и B, поскольку они не участвовали в попытке слияния.
Аргументы
Если сократить документацию git reset до одного абзаца, наиболее частый путь использования команды — , что сбросит данные пути до их состояния из данного коммита. Если пути не указаны, все дерево будет сброшено («ресетнуто»), а если коммит не указан, подразумевается коммит (текущий коммит).
Это стандартный паттерн команд git (включая checkout, diff, log, хотя семантика может несколько отличаться), так что сюрпризов здесь не предвидится.
Например, сбрасывает все в пути <путь/к/директории> к его состоянию в ветке <другая-ветка>; git reset — сбрасывает текущую директорию к ее состоянию в HEAD, а простой git reset сбрасывает все дерево к его состоянию в HEAD.
Мердж коммиты
Чем чаще мерджить между собой ветки, тем больше появляется так называемых мердж-коммитов. Такой коммит появляется каждый раз, когда мы подтягиваем мастер в свою ветку или сливаем свою ветку в мастер.
Эти коммиты не хранят изменений, они хранят только факт мерджа одной ветки в другую.
Посмотрим список коммитов и найдем мердж-коммит с хэшем 051f754
Посмотрим его содержимое
То есть информация только о том, что в мастер была залита ветка news. Сами изменения в файлах, которые мы делали в ветке news, лежат в других коммитах.
Споры о том, есть польза от таких коммитов, ведутся годами и не закончатся, видимо, никогда.
Плюс в том, что у нас есть возможность выбора — git позволяет обходиться без таких коммитов вообще.
Тогда история коммитов будет содержать только изменения в коде, а не операции с ветками. Это достигается механизмом ребейза, но это тема, которая выходит за рамки первой курса.
Ребейз, его плюсы и минусы, мы подробно рассмотрим во второй части курса.
Также можете почитать мою старую статью — Отличия мерджа от ребейза.
В ней нет видеоурока, но наглядно объясняется на скриншотах.
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
Странная нотация (~ и ^)
При использовании команды «странная нотация» бывает особенно полезной, поскольку позволяет указывать коммиты, близкие к HEAD, без необходимости написания их хэшей:
- HEAD~ — это сокращенная запись HEAD~1 и означает первого родителя коммита. HEAD~2 означает первого родителя у первого родителя коммита. HEAD~n можно понимать как «n коммитов перед HEAD» или «n-ый предок HEAD».
- HEAD^ (или HEAD^1) тоже означает первого родителя коммита. Но вот HEAD^2 означает второго родителя коммита. Помните, коммит, представляющий собой нормальное слияние (merge), имеет двух родителей: первый родитель — это коммит, в который осуществляется слияние, а второй родитель — коммит, который был слит. Вообще говоря, слияния могут иметь произвольно много родителей (octopus merges).
- Операторы ^ и ~ могут выстраиваться в линию, например, HEAD~3^2 будет означать второго родителя предка HEAD третьего уровня; HEAD^^2 — второго родителя первого родителя HEAD; HEAD^^^ — это просто эквивалент HEAD~3.