Другой вариант — git rebase -i. Это сложнее, чем git revert, но у вас также больше возможностей.
Допустим, у вас есть репозиторий git, который содержит только файл README:
$ cat README
This is line alpha.
Line Beta.
Line Gamma.
Затем вы удаляете бета-версию строки и фиксируете свое изменение:
(make changes)
$ git commit -am 'removed beta'
Теперь вы добавляете еще несколько строк, коммитя по пути:
(make changes)
$git commit -am 'added delta'
(make changes)
$git commit -am 'added epsilon'
Теперь наш файл README и журнал git выглядят так:
$ cat README
This is line alpha.
Line Gamma.
Line Delta.
Line Epsilon.
$ git log --pretty=oneline
56ae2db58905607270434045b2a7218237d3716e added epsilon
058ec4b92fb279370f6e5b81c4aebb6250f93c6b added delta
19801b380956b60f36b4922796ea86935a75e569 removed beta
bc9057cebf05352eb5596eaf753708a14de589d2 initial commit
Теперь мы решаем, что нам не стоило удалять бета-строку. git rebase на помощь! Всякий раз, когда я делаю какое-либо перемещение, мне нравится использовать временную ветку, так как я меняю историю.
$ git checkout -b fixingthings
Теперь мы хотим перебазировать все, что произошло с момента нашей первоначальной фиксации. Судя по журналу, это коммит bc9057c....
$ git rebase -i bc9057c
Теперь вы увидите это в своем редакторе:
pick 19801b3 removed beta
pick 058ec4b added delta
pick 56ae2db added epsilon
# Rebase bc9057c..56ae2db onto bc9057c
#
# Commands:
# p, pick = use commit
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
Комментарии внизу полезны. Просто удалите строку с фиксацией, от которой хотите избавиться, сохраните и закройте, а git позаботится обо всем остальном. Теперь ваш README выглядит так:
$ cat README
This is line alpha.
Line Beta.
Line Gamma.
Line Delta.
Line Epsilon.
Это как волшебство!
Если хотите, вы можете сейчас слиться со своей главной веткой и удалить временную ветку.
$ git checkout master
Switched to branch "master"
$ git merge fixingthings
Auto-merging README
Merge made by recursive.
$ git branch -d fixed
Deleted branch fixingthings (was 1247141).
Что делает git rebase, так это рассматривает каждую фиксацию как патч и воспроизводит их по порядку (или нет, как вы скажете). Это означает, что у вас могут быть конфликты слияния. Если это произойдет с вами, rebase приостановится, и вы разрешите конфликты. Существует множество руководств о том, что делать в такой ситуации. Этот мне понравился.
person
Neall
schedule
22.11.2009