Сброс или возврат определенного файла к определенной ревизии с помощью Git? - PullRequest
3989 голосов
/ 19 октября 2008

Я внес некоторые изменения в файл, который был зафиксирован несколько раз как часть группы файлов, но теперь хочу сбросить / отменить изменения в нем до предыдущей версии.

Я сделал git log вместе с git diff, чтобы найти нужную мне ревизию, но просто не знаю, как вернуть файл в прежнее состояние в прошлом.

Ответы [ 31 ]

5408 голосов
/ 19 октября 2008

Предполагая, что хеш коммита, который вы хотите, равен c5f567:

git checkout c5f567 -- file1/to/restore file2/to/restore

Справочная страница git дает дополнительную информацию.

Если вы хотите вернуться к фиксации до c5f567, добавьте ~1 (работает с любым числом):

git checkout c5f567~1 -- file1/to/restore file2/to/restore

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

559 голосов
/ 17 декабря 2008

Вы можете быстро просмотреть изменения, внесенные в файл, используя команду diff:

git diff <commit hash> <filename>

Затем, чтобы вернуть определенный файл в этот коммит, используйте команду сброса:

git reset <commit hash> <filename>

Возможно, вам придется использовать опцию --hard, если у вас есть локальные модификации.

Хорошим рабочим процессом для управления путевыми точками является использование тегов для точной маркировки точек на временной шкале. Я не совсем понимаю ваше последнее предложение, но вам может понадобиться отклонить ветку от предыдущего момента времени. Для этого используйте удобную команду проверки:

git checkout <commit hash>
git checkout -b <new branch name>

Затем вы можете перебазировать его по своей основной линии, когда будете готовы объединить эти изменения:

git checkout <my branch>
git rebase master
git checkout master
git merge <my branch>
333 голосов
/ 08 апреля 2009

Вы можете использовать любую ссылку на коммит git, включая SHA-1, если это наиболее удобно. Дело в том, что команда выглядит так:

git checkout [commit-ref] -- [filename]

262 голосов
/ 30 августа 2008
git checkout -- foo

Это сбросит foo в ГОЛОВУ. Вы также можете:

git checkout HEAD^ foo

за одну ревизию и т. Д.

117 голосов
/ 14 января 2012

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

git checkout HEAD file/to/restore
103 голосов
/ 27 мая 2009

У меня была такая же проблема только сейчас, и я нашел этот ответ проще всего понять (commit-ref - это значение SHA изменения в журнале, к которому вы хотите вернуться):

git checkout [commit-ref] [filename]

Это поместит старую версию в ваш рабочий каталог, и оттуда вы можете зафиксировать ее, если хотите.

89 голосов
/ 07 апреля 2009

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

git checkout master~5 image.png

Предполагается, что вы находитесь на ветке master, и вам нужна версия 5 коммитов назад.

80 голосов
/ 17 декабря 2008

Я думаю, что нашел это .... из http://www -cs-students.stanford.edu / ~ blynn / gitmagic / ch02.html

Иногда вы просто хотите вернуться назад и забыть о каждом изменении после определенного момента, потому что все они не правы.

Начните с:

$ git log

, который показывает вам список последних коммитов и их хэш SHA1.

Далее введите:

$ git reset --hard SHA1_HASH

для восстановления состояния данного коммита и полного удаления всех новых коммитов из записи.

61 голосов
/ 26 августа 2011

Это сработало для меня:

git checkout <commit hash> file

Затем передайте изменения:

git commit -a
54 голосов
/ 11 января 2009

Вы должны быть осторожны, когда говорите «откат». Если раньше у вас была одна версия файла в коммите $ A, а затем позже было сделано два изменения в двух отдельных коммитах $ B и $ C (так что вы видите третью итерацию файла), и если вы скажете " Я хочу откатиться к первому ", вы действительно это имеете в виду?

Если вы хотите избавиться от изменений как второй, так и третьей итерации, это очень просто:

$ git checkout $A file

и затем вы фиксируете результат. Команда спрашивает: «Я хочу извлечь файл из состояния, записанного коммитом $ A».

С другой стороны, вы имели в виду избавление от изменений, внесенных второй итерацией (т. Е. Фиксацией $ B), сохраняя то, что коммит $ C сделал с файлом, вы захотите вернуть $ B

$ git revert $B

Обратите внимание, что тот, кто создал коммит $ B, возможно, не был очень дисциплинированным и мог совершить совершенно несвязанное изменение в том же коммите, и этот откат может коснуться файлов, отличных от file , вы видите оскорбительные изменения, поэтому вы после этого может потребоваться тщательно проверить результат.

...