Выборочно возвращать или проверять изменения файла в Git?


88

Есть ли команда, позволяющая частично отменить изменения файла (или файлов) в рабочем каталоге?

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

Я представляю себе вариант, git checkoutкоторый работает очень похоже git add -p, то есть он просматривает фрагмент файла за фрагментом и спрашивает, хотите ли вы его сохранить или нет.

Ответы:


85

Вы могли бы использовать

git add -p <path>

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

git checkout -- <path>

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

Наконец, вы можете использовать

git reset -- <path>

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


Почему для этого простого варианта использования, который любая другая система управления версиями просто называет «возврат», команда Git такая непонятная?
Jan Hettich

5
@Jan Позволяет ли команда других систем управления версиями revertвыбрать, какие изменения в файле будут отменены? Искренне спрашиваю, так как у меня только опыт работы с CVS и Git. В Git git checkout -- path/to/fileэто одна команда, которая отменяет все изменения в этом файле, но это не то же самое, что и выше.
michiakig

3
Также есть git checkout --patchи git reset --patchкоторые работают как git add --patchв последнем git.
Мэтт Коннолли

2
@Rudie, как --правило, означает конец анализа параметров, и любые аргументы, которые идут после него, должны интерпретироваться буквально. Это означает, что вам не нужно будет добавлять ./перед любым именем файла, который начинается со знака минус, если имя файла идет после --.
zrajm

когда я использую git checkout --patchdiff, кажется, что это назад. Знаки минуса ДОБАВЛЯЮТ текст в мою рабочую копию, а символы плюс - УДАЛЯЮТ строки из моей рабочей копии.
Фелипе Альварес

115

С версией git> = 1.7.1 я могу

git checkout -p

Я не уверен, когда появилась эта функция.


11
Стоит упомянуть, что вы также git reset -pможете выборочно отключить изменения из области подготовки / индекса. Я также не знаю, в какой версии Git это было введено.

Это правильный ответ, почему его не приняли.
wukong

1
@wukong, потому что этот ответ был опубликован через 2 года после вопроса. На данный момент (2009 г.) ответ Чарльза был лучшим решением
pomeh

8

git checkout $fileвозвращает файл $fileв последнее зафиксированное состояние. Я думаю, вы можете использовать, git checkout SHA-1 -- $fileчтобы вернуть файл к фиксации, определенной SHA-1.


1
да, не совсем то, что я хочу, так как я хочу сохранить некоторые изменения, которые я сделал в файле, и отменить другие
1800 ИНФОРМАЦИЯ

1

Сколько коммитов вам нужно вернуться и выбрать? Если это только один, возможно, возьмите ветку непосредственно перед ним, проверьте файл, который вы зафиксировали, а затем используйте, git add -pчтобы добавить его так, как вы этого хотели. Затем вы можете вернуться туда, где вы были, и извлечь файл из своей временной ветки.

то есть:

git checkout -b temp troublesome-commit^
git checkout troublesome-commit -- path/to/file
git add -p path/to/file
git commit -c troublesome-commit
git checkout @{-1}
git checkout temp -- path/to/file
git commit path/to/file
git branch -D temp

Другие альтернативы включают возврат и редактирование фиксации с помощью git rebase -i(отметка фиксации как edit, затем выполнение git reset HEAD^и повторение фиксации при возврате в оболочку).

Если изменения, которые вам нужно выбрать, распределены по серии коммитов, может быть лучше извлечь их как патчи (или патч, покрывающий все из них) и вручную отредактировать патч, удалив изменения, которые вы хотите сохранить, и подача остатка в git apply --reverse.


На самом деле я не хочу отменять все, что было зафиксировано, я хочу отменить изменения, которые есть только в моей рабочей копии
1800 ИНФОРМАЦИЯ
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.