Возврат части коммита с помощью git - PullRequest
123 голосов
/ 25 января 2011

Я хочу отменить определенный коммит в git.К сожалению, наша организация все еще использует CVS в качестве стандарта, поэтому, когда я возвращаюсь к CVS, несколько git коммитов объединяются в один.В этом случае я хотел бы выделить оригинальный коммит git, но это невозможно.

Существует ли подход, подобный git add --patch, который позволил бы мне выборочно редактировать diff, чтобы решить, какие части коммитавернуться?

Ответы [ 6 ]

196 голосов
/ 25 января 2011

Используйте параметр --no-commit (-n) для git revert, затем отмените внесение изменений, затем используйте git add --patch:

$ git revert -n $bad_commit    # Revert the commit, but don't commit the changes
$ git reset HEAD .             # Unstage the changes
$ git add --patch .            # Add whatever changes you want
$ git commit                   # Commit those changes

Примечание. Файлы, которые вы добавляете с помощью git add --patch, - это файлы, которые вы хотите вернуть, а не файлы, которые вы хотите сохранить.

35 голосов
/ 19 декабря 2012

Я успешно использовал следующее.

Сначала верните полный коммит (поместите его в индекс), но не коммитите.

git revert -n <sha1>  # -n is short for --no-commit

Затем в интерактивном режиме удалите отмененные ХОРОШИЕ изменения из индекса

git reset -p          # -p is short for --patch  

Затем выполните обратный дифференциал плохих изменений

git commit -m "Partially revert <sha1>..."

Наконец, отозванные ХОРОШИЕ изменения (которые не были установлены командой сброса) все еще находятся в рабочем дереве. Они должны быть очищены. Если в рабочем дереве не осталось других незафиксированных изменений, это можно сделать с помощью

git reset --hard
4 голосов
/ 08 октября 2014

Лично я предпочитаю эту версию, которая использует автоматически сгенерированное сообщение о коммите и дает пользователю возможность отредактировать и вставить слово «Частично» перед окончательной фиксацией.

# generate a revert commit
# note the hash printed to console on success
git revert --no-edit <hash to revert>

# undo that commit, but not its changes to the working tree
# (reset index to commit-before-last; that is, one graph entry up from HEAD)
git reset HEAD~1

# interactively add reversions
git add -p

# commit with pre-filled message
git commit -c <hash from revert commit, printed to console after first command>

# reset the rest of the current directory's working tree to match git
# this will reapply the excluded parts of the reversion to the working tree
# you may need to change the paths to be checked out
# be careful not to accidentally overwrite unsaved work
git checkout -- .
4 голосов
/ 11 августа 2014

Решение:

git revert --no-commit <commit hash>
git reset -p        # every time choose 'y' if you want keep the change, otherwise choose 'n'
git commit -m "Revert ..."
git checkout -- .   # Don't forget to use it.
1 голос
/ 13 марта 2018

Другая альтернатива (если ваша текущая версия файла не слишком далека от версии, которую вы пытаетесь вернуть) - это получить хеш коммита непосредственно перед той, которую вы хотите частичновернуться (от git log).Тогда ваша команда становится:

$ git checkout -p <hash_preceding_commit_to_revert> -- file/you/want/to/fix.ext

Это изменяет файлы в вашем рабочем дереве, но не создает коммитов, поэтому, если вы действительно разберетесь, вы можете просто начать снова с git reset --hard -- file/you/want/to/fix.ext.

1 голос
/ 25 января 2011

Вы можете использовать git-revert -n, а затем использовать add --patch для выбора блоков.

...