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

88

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

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

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

1800 ИНФОРМАЦИЯ
источник

Ответы:

85

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

git add -p <path>

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

git checkout -- <path>

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

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

git reset -- <path>

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

CB Bailey
источник
Почему для этого простого варианта использования, который любая другая система управления версиями просто называет «возврат», команда 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

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

thisgeek
источник
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 ИНФОРМАЦИЯ