У меня есть локальный репозиторий 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" к каждому коммиту в истории, а затем со временем удалить коммиты, которые ничего не делают?