Git выборочный возврат локальных изменений из файла

В моем реестре git, который отслеживает репозиторий svn, я сделал несколько изменений для одного файла.

Теперь я хочу вернуть эти изменения (например, svn revert), но только части файла.

Я хочу иметь возможность просматривать diff в файле, отбрасывать (возвращать) те изменения, которые мне не нужны, и сохранять изменения, которые я хочу.

git add -i 
Кажется, что команда

имеет возможность сделать это, но я пока не хочу это делать.

Ответ 1

Вы можете сделать это непосредственно с помощью git checkout -p. См. Даниэль Штуцбах.


Старый ответ (до checkout -p был введен):

Вы можете сделать это следующим образом:

git add -i

(выберите фрагменты, которые вы хотите сохранить)

git commit -m "tmp"

Теперь у вас есть фиксация только с изменениями, которые вы хотите сохранить, а остальная часть не установлена.

git reset --hard HEAD

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

git reset --mixed HEAD^

Это удаляет последнюю фиксацию ('tmp'), но сохраняет изменения в вашем рабочем каталоге, не прошедшие проверку.

EDIT: замените --soft на --mixed, чтобы очистить область постановки.

Ответ 2

Я считаю, что вы можете сделать это наиболее просто:

git checkout -p <optional filename(s)>

Из man-страницы:

   −p, −−patch
       Interactively select hunks in the difference between the <tree−ish>
       (or the index, if unspecified) and the working tree. The chosen
       hunks are then applied in reverse to the working tree (and if a
       <tree−ish> was specified, the index).
       This means that you can use git checkout −p to selectively discard
       edits from your current working tree.

Ответ 3

Вы можете запустить git diff в файле, сохранить полученный diff, отредактировать его, чтобы удалить изменения, которые вы хотите сохранить, а затем запустить через patch -R, чтобы отменить оставшиеся различия.

git diff file.txt >patch.tmp
# edit patch.tmp to remove the hunks you want to keep
patch -R <patch.tmp

Ответ 4

Похоже, вы хотите

 git revert --no-commit $REVSISON 

Затем вы можете использовать

 git diff --cached

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

Если вы использовали чистый репозиторий Git, вы могли бы, в зависимости от ваших целей, использовать интерактивную rebase (git rebase -i), чтобы вернуться к комманде, который вам не понравился, и отредактировать фиксацию ретроактивно, чтобы изменений, которые вам не нравятся, никогда не было, но, как правило, только если вы ЗНАЕТЕ, что никогда не захотите снова увидеть это.

Ответ 5

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

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

git add -i <file>

Затем отбросьте изменения, которые вы не хотите сохранять, проверяя версию индекса:

git checkout -- <file>

Затем отключите изменения, если вы еще не хотите, чтобы они были укомплектованы:

git reset -- <file>

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

Если вы хотите выборочно применять только некоторые изменения, внесенные в предыдущие коммиты, вы можете сначала reset сохранить файл в предыдущее состояние:

git reset <commit_before_first_unwanted_change> -- <file>

Затем вы можете следовать предыдущему рецепту git add -i <file>, чтобы выполнить те изменения, которые вы хотите сохранить, git checkout -- <file>, чтобы выбросить нежелательные изменения, и git reset -- <file>, чтобы "отключить" изменения.

Ответ 6

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

Откройте файл в редакторе netbeans (который поставляется с поддержкой git). Netbeans помещает красные/зеленые/синие метки в номера строк, чтобы указать, где материал был удален/добавлен/изменен (соответственно).

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