Отменить изменения файла в фиксации

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

Могу ли я использовать команду git revert для этого?

Любой другой простой способ сделать это?

+74
источник поделиться
7 ответов

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

git show some_commit_sha1 -- some_file.c | git apply -R

Как и ответ VonC, но используя git show и git apply.

+130
источник

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

Например, вы хотите отменить изменения в 1 файле (badfile.txt) в aaa222:

aaa333 Good commit
aaa222 Problem commit containing badfile.txt
aaa111 Base commit

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

1) Запустите интерактивный ребаз:

git rebase -i aaa111

2) Отметьте фиксацию проблемы для редактирования в редакторе, изменив pick на e (для редактирования):

e aaa222
pick aaa333

3) Вернуть изменения в плохой файл:

git show -- badfile.txt | git apply -R

4) Добавьте изменения и исправьте коммит:

git add badfile.txt
git commit --amend

5) Завершите ребаз:

git rebase --continue
+23
источник

git revert для всех файлов в пределах коммитов.

Для одного файла вы можете script it:

#!/bin/bash

function output_help {
    echo "usage: git-revert-single-file <sha1> <file>"
}

sha1=$1
file=$2

if [[ $sha1 ]]; then
git diff $sha1..$sha1^ -- $file | patch -p1
else
output_help
fi

(Из git-shell-scripts утилиты из smtlaissezfaire)


Примечание:

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

git checkout -- filename

git checkout имеет некоторые параметры для файла, изменяя файл из HEAD, перезаписывая ваши изменения.


Dropped.on.Caprica упоминает в комментариях:

Вы можете добавить псевдоним к git, чтобы вы могли сделать git revert-file <hash> <file-loc> и вернуть этот конкретный файл.
См. этот смысл.

[alias]
  revert-file = !sh /home/some-user/git-file-revert.sh
+19
источник

Я бы просто использовал параметр --no-commit для git-revert, а затем удалил файлы, которые вы не хотите возвращать из индекса, прежде чем, наконец, его совершить. Вот пример, показывающий, как легко вернуть только изменения в foo.c во второй последней фиксации:

$ git revert --no-commit HEAD~1
$ git reset HEAD
$ git add foo.c
$ git commit -m "Reverting recent change to foo.c"
$ git reset --hard HEAD

Первый git-reset "отключает" все файлы, поэтому мы можем добавить обратно только тот файл, который мы хотим вернуть. Окончательный git-reset --hard избавляется от оставшихся файлов, которые мы не хотим сохранять.

+12
источник
git reset HEAD^ path/to/file/to/revert/in/commit

Приведенная выше команда выведет файл из коммита, но это отразится в git status.

git checkout path/to/file/to/revert/in/commit

Приведенная выше команда вернет изменения (в результате вы получите файл, такой же, как HEAD).

git commit

(Передайте --amend чтобы изменить коммит.)

git push

При этом файл, который уже находится в коммите, удаляется и возвращается.

Вышеперечисленные шаги следует выполнить из ветки, в которой производится фиксация.

+4
источник

Гораздо проще:

git reset HEAD^ path/to/file/to/revert

затем

git commit --amend   

а затем

git push -f

файл пропал, а хэш, сообщение и т.д. - то же самое.

+3
источник

Вы можете следовать этой процедуре:

  1. git revert -n <*commit*> (-n все изменения, но не -n их)
  2. git add <*filename*> (имя файла/ов, которые вы хотите восстановить и зафиксировать)
  3. git commit -m 'reverted message' (добавить сообщение для возврата)
  4. после фиксации отменить изменения других файлов, чтобы файлы оставались обновленными с изменениями, внесенными вами до восстановления
0
источник

Посмотрите другие вопросы по меткам или Задайте вопрос