Как удалить выбранные записи журнала фиксации из репозитория Git при сохранении их изменений?
Я хотел бы удалить выбранные записи журнала фиксации из линейного дерева фиксации, чтобы записи не отображались в журнале фиксации.
Мое дерево компиляции выглядит примерно так:
R--A--B--C--D--E--HEAD
Я хотел бы удалить записи B и C, чтобы они не отображались в журнале фиксации, но изменения от A до D должны быть сохранены. Возможно, введя одно коммит, чтобы B и C стали BC, и дерево выглядит.
R--A--BC--D--E--HEAD
Или, в идеале, после того, как A приходит напрямую. D ', представляющий изменения от A до B, B до C и C к D.
R--A--D'--E--HEAD
Возможно ли это? если да, то как?
Это довольно новый проект, так что на данный момент у него нет ветвей, следовательно, нет слияний.
Ответы
Ответ 1
git -rebase (1) делает именно это.
$ git rebase -i HEAD~5
git awsome-ness [git rebase --interactive] содержит пример.
- Не использовать
git-rebase
для публичных (удаленных) коммитов.
- Убедитесь, что ваш рабочий каталог чист (
commit
или stash
ваши текущие изменения).
- Выполните приведенную выше команду. Он запускает ваш
$EDITOR
.
- Замените
pick
до C
и D
на squash
. Он объединит C и D в B. Если вы хотите удалить фиксацию, просто удалите ее строку.
Если вы потеряли, введите:
$ git rebase --abort
Ответ 2
# detach head and move to D commit
git checkout <SHA1-for-D>
# move HEAD to A, but leave the index and working tree as for D
git reset --soft <SHA1-for-A>
# Redo the D commit re-using the commit message, but now on top of A
git commit -C <SHA1-for-D>
# Re-apply everything from the old D onwards onto this new place
git rebase --onto HEAD <SHA1-for-D> master
Ответ 3
Вот способ удаления определенного кода фиксации, который знает только идентификатор фиксации, который вы хотите удалить.
git rebase --onto commit-id^ commit-id
Обратите внимание, что это фактически удаляет изменения, которые были внесены фиксацией.
Ответ 4
Чтобы расширить ответ Дж. Ф. Себастьяна:
Вы можете использовать git -rebase, чтобы легко вносить все изменения в историю фиксации.
После запуска git rebase --interactive вы получите следующее в своем $EDITOR:
pick 366eca1 This has a huge file
pick d975b30 delete foo
pick 121802a delete bar
# Rebase 57d0b28..121802a onto 57d0b28
#
# 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
Вы можете перемещать строки, чтобы изменить порядок фиксации и удалить строки, чтобы удалить эту фиксацию. Или вы можете добавить команду для объединения (squash) двух коммитов в одну фиксацию (предыдущая фиксация - это фиксация выше), редактирование коммитов (что было изменено) или перепечатать сообщения фиксации.
Я думаю, что выбрать просто означает, что вы хотите оставить это сообщение в одиночку.
(Пример из здесь)
Ответ 5
Вы можете не интерактивно удалить B и C в своем примере с помощью
git rebase --onto HEAD~5 HEAD~3 HEAD
или символически,
git rebase --onto A C HEAD
Обратите внимание, что изменения в B и C не будут в D; они исчезнут.
Ответ 6
Еще один способ,
git rebase -i ad0389efc1a79b1f9c4dd6061dca6edc1d5bb78a (C hash)
and
git push origin master -f
выберите хеш, который вы хотите использовать в качестве базы, и приведенная выше команда должна сделать его интерактивным, чтобы вы могли скворовать все сообщения top (вам нужно оставить самый старый)
Ответ 7
Я считаю этот процесс более безопасным и понятным, создавая еще одну ветку из SHA1 of A и вишневую подбор желаемых изменений, чтобы я мог убедиться, что я доволен тем, как выглядит эта новая ветка. После этого легко удалить старую ветку и переименовать новую.
git checkout <SHA1 of A>
git log #verify looks good
git checkout -b rework
git cherry-pick <SHA1 of D>
....
git log #verify looks good
git branch -D <oldbranch>
git branch -m rework <oldbranch>
Ответ 8
Просто собрал ответы всех людей: (m new to git plz использовать его только для справки)
git rebase для удаления любых коммитов
git log
-first check from which commit you want to rebase
git rebase -i HEAD ~ 1
-Here i want to rebase on the second last commit- commit count starts from '1')
-this will open the command line editor (called vim editor i guess)
Затем экран будет выглядеть примерно так:
pick 0c2236d Добавлена новая строка.
Rebase 2a1cd65..0c2236d на 2a1cd65 (команда 1)
#
Команды
p, pick = use commit
r, reword = использовать commit, но отредактировать сообщение фиксации
e, edit = использовать commit, но останавливать для изменения
s, squash = использовать commit, но meld в предыдущий commit
f, fixup = like "squash", но отмените это сообщение журнала фиксации
x, команда exec = run (остальная часть строки) с использованием оболочки
d, drop = удалить commit
#
Эти строки могут быть переупорядочены; они выполняются сверху вниз.
#
Если вы удалите строку здесь, то КОМИТЕТ БУДЕТ ПОТЕРЯТЬ.
#
Однако, если вы удалите все, rebase будет прерван.
#
Обратите внимание, что пустые коммиты закомментированы ~ ~
~
~
~
~
~
~
~
~
~
Здесь измените первую строку в соответствии с вашими потребностями (используя команды, перечисленные выше i.e. "drop", чтобы удалить фиксацию и т.д.).
Сделав редактирование, нажмите ": x", чтобы сохранить и выйти из редактора (это только для редактора vim)
И затем
git нажмите
Если его проблема с отображением, вам необходимо принудительно надавить изменения на удаленный (ITS VERY CRITICAL: не нажимайте push, если вы работаете в команде)
git push -f origin
Ответ 9
Вы можете использовать git cherry-pick для этого. "cherry-pick" теперь применит фиксацию на ветку.
то do
git rebase --hard <SHA1 of A>
затем примените D и E совершает.
git cherry-pick <SHA1 of D>
git cherry-pick <SHA1 of E>
Это пропустит фиксацию B и C. Сказав, что было бы невозможно применить D-фиксацию к ветке без B, поэтому YMMV.