Могу ли я сделать частичное возвращение в GIT

Можно ли вернуть только один файл или некоторые изменения в файле в нескольких файлах?

Полная история Я совершил кучу файлов. Несколько позже комментируют того, кто останется безымянным (JACK!!!) скопировал файл в свой репозиторий и совершил несколько файлов, перезаписав некоторые изменения, которые я сделал. Я хочу вернуть один файл, который был взломан или еще лучше, зайдите и верните два изменения в этом файле. Это должно быть отдельной ревертной фиксацией, так как она была вытащена и нажата.

Ответ 1

Вы можете отменить фиксацию, не создавая новую, добавив параметр "-no-commit". Это оставляет все восстановленные файлы в промежуточной области. Оттуда я бы выполнил мягкий reset и добавил изменения, которые я действительно хотел. Пример рабочего процесса:

git revert <sha-of-bad-commit> --no-commit
git reset   // This gets them out of the staging area
<edit bad file to look like it should, if necessary>
git add <bad-file>
git checkout . // This wipes all the undesired reverts still hanging around in the working copy
git commit

Ответ 2

Вы можете интерактивно применять старую версию файла с помощью команды checkout.

Например, если вы знаете COMMIT, где был удален код для добавления назад, вы можете запустить следующую команду:

git checkout -p COMMIT^ -- FILE_TO_REVERT

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

Ответ 3

Вы можете просто вручную проверить прежнее, хорошее содержимое файлов, которые вы хотите вернуть, используя git checkout. Например, если вы хотите вернуть my-important-file в версию, которая была в версии abc123, вы можете сделать

git checkout abc123 -- my-important-file

Теперь у вас есть старое содержимое my-important-file назад, и вы можете даже отредактировать их, если хотите, и совершите, как обычно, совершение фиксации, которая вернет изменения, которые он сделал. Если есть только некоторые части его фиксации, которые вы хотите вернуть, используйте git add -p, чтобы выбрать только несколько кусков из патча, который вы совершаете.

Ответ 4

Я нашел способ сделать это в списке рассылки Git:

git show <commit> -- <path> | git apply --reverse

Источник: http://git.661346.n2.nabble.com/Revert-a-single-commit-in-a-single-file-td6064050.html#a6064406

Варианты

Эта команда выходит из строя (не вызывая никаких изменений), если патч не применяется чисто, но с --3way вместо этого вы получаете конфликты, которые затем можно разрешить вручную (в этом случае Casey answer может быть более практичным):

git show <commit> -- <path> | git apply --reverse --3way

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

git log -S<string> --patch | git apply --reverse

чтобы отменить файлы с изменениями, соответствующими <string> в любой фиксации. Это именно то, что мне нужно в моем случае использования (несколько отдельных коммитов вносили аналогичные изменения в разные файлы, а также меняли другие файлы несвязанными способами, которые я не хотел возвращать).

Если у вас diff.noprefix=true установлен в ~/.gitconfig, тогда вам нужно добавить -p0 в команду git apply, например.

git show <commit> -- <path> | git apply -p0 --reverse