Конфликт при удалении коммита с помощью git rebase - PullRequest
0 голосов
/ 11 мая 2019

У меня есть локальный репозиторий git, содержащий некоторые коммиты, которые я хотел бы удалить. Точнее, я хотел бы переписать всю историю хранилища, как если бы данные коммиты никогда не имели место. Удаление старых коммитов обсуждалось, например, здесь и здесь , но по некоторым причинам это не работает для меня.

Чтобы получить конкретный работоспособный пример, рассмотрим git-репозиторий, сконструированный следующим образом

git init .
echo hello >foo.txt
git add foo.txt
git commit -a -m first
echo hello2 >>foo.txt
git commit -a -m second
sed -i 's/hello2/hello2 bis/' foo.txt
git commit -a -m second_bis
echo hello3 >>foo.txt
git commit -a -m third

Репозиторий git теперь содержит один файл foo.txt, который содержит

hello
hello2 bis
hello3

Полная история git, полученная с помощью `` `git log -p --all``, равна (Авторы / Дата удалена)

commit 7bd2f440ef5a0cbfd0fd252671d1651a6c282db5
Author: ---
Date: ---

    third

diff --git a/foo.txt b/foo.txt
index 83d1cb0..ce5a249 100644
--- a/foo.txt
+++ b/foo.txt
@@ -1,2 +1,3 @@
 hello
 hello2 bis
+hello3

commit c2c7f8c66ddb40fc6196350ea5e4f4c54293cf54
Author: ---
Date: ---

    second_bis

diff --git a/foo.txt b/foo.txt
index 97531f3..83d1cb0 100644
--- a/foo.txt
+++ b/foo.txt
@@ -1,2 +1,2 @@
 hello
-hello2
+hello2 bis

commit 853dca5b3c9152ab50cdf9de260f1a3b4bba4100
Author: ---
Date: ---

    second

diff --git a/foo.txt b/foo.txt
index ce01362..97531f3 100644
--- a/foo.txt
+++ b/foo.txt
@@ -1 +1,2 @@
 hello
+hello2

commit 921efb9472e14333804dff575a71050213a770be
Author: ---
Date: ---

    first

diff --git a/foo.txt b/foo.txt
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/foo.txt
@@ -0,0 +1 @@
+hello

Предположим, что я хотел бы удалить коммит с комментарием "second_bis", чтобы иметь историю, подобную следующей

commit 7bd2f440ef5a0cbfd0fd252671d1651a6c282db5
Author: ---
Date: ---

    third

diff --git a/foo.txt b/foo.txt
index 83d1cb0..ce5a249 100644
--- a/foo.txt
+++ b/foo.txt
@@ -1,2 +1,3 @@
 hello
 hello2
+hello3

commit 853dca5b3c9152ab50cdf9de260f1a3b4bba4100
Author: ---
Date: ---

    second

diff --git a/foo.txt b/foo.txt
index ce01362..97531f3 100644
--- a/foo.txt
+++ b/foo.txt
@@ -1 +1,2 @@
 hello
+hello2

commit 921efb9472e14333804dff575a71050213a770be
Author: ---
Date: ---

    first

diff --git a/foo.txt b/foo.txt
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/foo.txt
@@ -0,0 +1 @@
+hello

Подход, который я пробовал, заключается в использовании git rebase для простого устранения коммита "second_bis"

git rebase -i 853dca5b

Это открывает мой редактор с файлом, содержащим

pick c2c7f8c second_bis
pick 7bd2f44 third
# Rebase 853dca5..7bd2f44 onto 853dca5 (2 commands)
#
#...

На этом этапе я заменяю «pick» на «drop» в строке, относящейся к «second_bis». К моему удивлению, git не может управлять операцией и жалуется на конфликт

Auto-merging foo.txt
CONFLICT (content): Merge conflict in foo.txt

Конечно, я могу вручную разрешить конфликт в этом простом примере, но это противоречит идее автоматического удаления коммита. Хуже того, в хранилище с дальнейшими коммитами после «третьего», после разрешения конфликта git rebase снова жалуется на конфликт при коммитах после «третьего» и т. Д.

Почему git rebase не может автоматически разрешить конфликт?

Существует ли автоматизированный способ удалить коммит "second_bis"?

В качестве альтернативы можно было бы, скажем, применить патч "second_bis -> second" к каждому коммиту в истории, а затем со временем удалить коммиты, которые ничего не делают?

Ответы [ 2 ]

1 голос
/ 11 мая 2019

проблема в том, что когда изменение ревизией, которая добавляет hello3 к файлу, выполнено, предыдущая строка - «hello2 bis», а не просто «hello 2», и нет ничего после строки, на которую влияют, в исходной ревизии, так что git может на самом деле не сказать, что происходит. дайте git немного больше контекста, добавив hello3 перед sed, и он работает как шарм:

git init .
echo hello >foo.txt
git add foo.txt
git commit -m first foo.txt
echo hello2 >>foo.txt
git commit -m second foo.txt
echo hello3 >>foo.txt
git commit -m third foo.txt
sed -i 's/hello2/hello2 bis/' foo.txt
git commit -m second_bis foo.txt
echo hello4 >> foo.txt
git commit -m hello4 foo.txt

В качестве примечания, ваши инструкции также будут работать, если вместо файла с 1, 2, 3 строками вы попробуйте в середине файла, который содержит по крайней мере несколько строк до и еще пару строк после , внезапный EOF - вот что по-настоящему сбивает с толку git, чтобы делать свою работу (чего я избегал, добавляя hello3 перед sed, очевидно).

0 голосов
/ 11 мая 2019

Кажется, ваш second_bis - последний коммит. Вы можете сделать следующее:

Изменить последнее сообщение о коммите

git commit --amend
#change second_bis into third

Сброс последнего коммита

git reset HEAD~
git add *
git commit -a -m "third"
#now 3rd commit shows third

Вернуть последний коммит

Если вы уже передали изменения на сервер, вы можете вернуть

git revert HEAD
#revert done change for third commit
git add *
git commit -a -m "third"
#now 3rd commit shows third
...