Фактически удалите коммит git таким образом, чтобы он исчез из журнала - PullRequest
1 голос
/ 30 мая 2020

Я не могу найти способ удалить целевую фиксацию из журнала. Документация по удалению коммитов либо просто сбрасывает указатель с помощью reset (который ничего не удаляет, а просто сбрасывает указатели), либо rebase, который создает новую структуру некоторого вида в удаленном коммите. По-прежнему отображается ha sh целевой фиксации. Там может быть старая документация, относящаяся к

git rebase -i fork1~1 fork1~3

, потому что в старых сообщениях говорится об удалении строки в редакторе, то есть строки, соответствующей целевой фиксации. Когда я попадаю в интерактивный редактор, один из вариантов - «drop», что означает удаление фиксации. Однако мне не удалось удалить какие-либо коммиты в том смысле, что они исчезают из журнала. Я вставляю слово drop, и в выводе журнала создается что-то вроде вилки. Но я все еще вижу ха sh коммита, который пытаюсь удалить. Проще говоря, я хочу определить ha sh, который нужно удалить, и чтобы он больше не отображался в журнале.

Итак, идея тут сбросить 1bc7112:

*   4518859 (refs/stash) WIP on fork3: 8c438a9 Added first.bsh back in
|\
| * 1bc7112 index on fork3: 8c438a9 Added first.bsh back in
|/
* 8c438a9 Added first.bsh back in
* eef828f (HEAD -> fork4) Removed using git rm
* c21cda0 Third change.

Ответы [ 4 ]

2 голосов
/ 30 мая 2020

Теперь, когда вы разместили журнал (в виде графика), причина ясна: коммит, который вы хотите удалить, вообще не является частью истории. Это хранится на станции sh. Способ его удаления - сбросить сам sta sh.

График показывает, что за странная утка на самом деле sta sh. Фактически это фиксация слияния; его первый родительский элемент - это HEAD, когда вы создали sta sh (поскольку рабочее дерево существовало в отношении этого HEAD), а его вторым родительским элементом является весь индекс на тот момент, а родительским элементом этого второго родителя является HEAD. В документации dr aws это выглядит так:

       .----W
      /    /
-----H----I

Точка - это sta sh, H - это ГОЛОВКА, I - записанный индекс, а W - записанное рабочее дерево.

Итак, пока существует sta sh, этот коммит H (тот, который был head в то время, когда вы прятали) не может go исчезнуть.

Между тем, коммит, на который вы жалуетесь даже не настоящая фиксация! Это замороженный снимок индекса на тот момент, когда вы сделали sta sh. Является неотъемлемой частью STA sh.

0 голосов
/ 30 мая 2020

При создании git rebase -i HEAD~X, где X - количество коммитов для перебазирования, вы можете перебазировать в интерактивном режиме. Вы увидите (например) следующие параметры:

pick 0a3e7b9 other commit
pick 7cfa14c commit to remove

# Rebase 04ec4b7..7cfa14c onto 04ec4b7 (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

Введите i для редактирования, затем вы можете добавить d или drop перед фиксацией, которую хотите удалить, например:

d 7cfa14c commit to remove 

Пусть pick перед всеми другими коммитами, затем введите esc, чтобы выйти из режима редактирования, и :wq, чтобы сохранить и выйти.

Сейчас фиксация будет удалена локально, следующее обновление pu sh в удаленной ветке с использованием git push --force origin <remote_branch>, обратите внимание на параметр --force, необходимый из-за перебазирования.

0 голосов
/ 30 мая 2020

Это ожидаемое поведение.

Git - это, по сути, простой ориентированный граф, где ветви - это автоматически расширяемые имена (также известные как ссылки) для коммитов и, следовательно, головной узел в некотором поддереве графа. Сброс - это один из методов изменения, который фиксирует имена веток.

Аналогичным образом, когда выполняется rebase, изменения, которые приводят к другому результату вычисления ha sh в отдельных фиксациях. Родительские хэши также являются частью вычисления , поэтому сброс фиксации влияет на всех потомков. Затем ветвь обновляется, чтобы указать на начало нового дерева коммитов, в то время как сами исходные коммиты фактически не удаляются из набора всех коммитов и их все еще можно найти через reflog .

После сброса или перебазирования эти устаревшие (в том числе отброшенные) коммиты являются «сиротами» тогда и только тогда, когда на них не могут ссылаться никакие ссылки + . На коммиты по-прежнему можно ссылаться с помощью commit ha sh, поскольку они все еще существуют на диске; однако, если нет прямых ссылок на эти коммиты, и они не являются предком каких-либо ссылок, они не должны отображаться в команде журнала.

+ Git ссылки (также известные как ссылки) включают ~ ветки ~, ~ теги ~ и ~ sta sh записи ~.

Если коммиты не «осиротевший» и, следовательно, видимый в обычном журнале, существует ветвь или тег, который необходимо обновить. Сюда также входят ветви удаленного отслеживания и записи sh. Обновите и / или удалите эти ссылки по мере необходимости. Если ветка, удерживающая эти коммиты от «осиротевания», уже отправлена ​​и находится на основной линии ... что ж, будем надеяться, что это не так.


Удаление фиксации с диска, после он стал сиротой, это можно сделать с помощью команды prune , которая может удалить всех сирот. Git обычно выполняет периодi c G C хозяйственное обслуживание, поэтому обычно это не требуется.

Если фиксация уже была отправлена, этот процесс должен быть распространен на каждый репозиторий, который теперь есть изменение. Если это включает принудительное продвижение ветвей основной ветки, это может быть «очень раздражающим» для других разработчиков и / или неосуществимым, в зависимости от того, сколько других коммитов являются потомками. Это следует делать только в крайнем случае, так как фиксация (и любые данные в ней) уже просочились и возможна зависимость других удаленных коммитов.

0 голосов
/ 30 мая 2020

сброс на более старую фиксацию: git reset --hard <old commit>

...