Переписывание истории

Архитектура 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

  1. Оформить заказ на временную ветку с последней фиксацией

  2. Сбросить последнюю фиксацию

  3. Теперь у вас будут все файлы вашего коммита, а также файлы предыдущего коммита. Проверить статус всех файлов.

  4. Сбросьте файлы фиксации на этапе git.

    (и т. Д.)

  5. Повторно прикрепить эту фиксацию

  6. Добавьте и зафиксируйте свои файлы в новом коммите.

3

Priyanshu Chauhan
4 Мар 2016 в 07:28

Простое решение Решение работает: если ваша фиксация HEAD синхронизирована с удаленной фиксацией.

  • Создайте еще одну ветку в своей локальной рабочей области и синхронизируйте ее с удаленной веткой.
  • Cherry выбирает фиксацию HEAD из ветки (где git commit —amend) была выполнена во вновь созданной ветке.

Выбранная вишня фиксация будет содержать только ваши последние изменения, а не старые изменения. Теперь вы можете просто переименовать этот коммит.

2

Vasudeva H
10 Сен 2020 в 13:47

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: