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 помещает красные/зеленые/синие метки в номера строк, чтобы указать, где материал был удален/добавлен/изменен (соответственно).
Щелчок правой кнопкой мыши по любой из этих меток дает вам возможность отменить это изменение.
Кроме того, вы можете щелкнуть правой кнопкой мыши по красным и синим меткам, чтобы найти старую версию во всплывающем окне.