В чем разница между "git checkout" и "git restore" для отмены незафиксированных изменений файла? - PullRequest
1 голос
/ 10 апреля 2020

Скажем, у меня есть репозиторий git с измененным файлом с именем readme.txt , и я хочу отменить внесенные мной изменения и вернуть его в состояние самого последнего коммита. Кажется, есть две команды для этого:

git checkout -- readme.txt

и

git restore readme.txt

Есть ли разница между этими двумя командами? Я заметил, что git status предлагает совет "(use "git restore <file>..." to discard changes in working directory)". Это канонический способ отменить незафиксированные модификации? Являются ли оба способа одинаково действительными и популярными?

Ответы [ 3 ]

4 голосов
/ 10 апреля 2020

Как указано в документации :

или вы можете восстановить как индекс, так и рабочее дерево (это то же самое, что и git -checkout 1 )

Это удобный способ сделать то же самое. (первая версия в Git 2.23)

Запись блога от GitHub об основных моментах Git 2.23:

Git 2.23 приносит новую пару экспериментальных команд в набор существующих: git switch и git restore. Эти два предназначены для того, чтобы в конечном итоге обеспечить лучший интерфейс для хорошо известного git checkout. Новые команды предназначены для того, чтобы каждая из них имела четкое разделение, аккуратно разделяя многие обязанности git checkout, так как мы покажу ниже.

3 голосов
/ 10 апреля 2020

git restore - это новая команда, которая была введена (прошлым летом) в Git 2.23 вместе с git switch. Их целью является упрощение и разделение вариантов использования git checkout, который делает слишком много вещей.

git checkout можно использовать для переключения ветвей (а также для создания новой ветви до того, как переключаюсь на это). Эта функциональность была извлечена в git switch.

git checkout, также может использоваться для восстановления файлов до состояния, в котором они находились в указанном коммите. Эта функциональность была извлечена в git restore.

Они все еще могут выполняться git checkout, но новые команды проще в использовании и менее запутаны.

Подводя итог,

git restore readme.txt

- это новый способ сделать то, что вы делали с:

git checkout -- readme.txt
0 голосов
/ 10 апреля 2020

Мне нравятся два ответа на этот вопрос в то время, когда я пишу свой - оба ответа axia c и kapsiR * , но я бы сказал так:

  • git checkout объединяет слишком много команд в одном интерфейсе. Некоторые из этих команд являются «безопасными», в том случае, если у вас есть незафиксированная работа, они не будут уничтожать ее, а некоторые из них «небезопасны», в том случае, если у вас есть незафиксированная работа и вы сообщаете им уничтожить мою незафиксированную работу , они это сделают.

  • git switch реализует «безопасное» подмножество.

  • git restore реализует «небезопасное» подмножество.

Пока что нет особой причины отдавать предпочтение ни старой одиночной команде, ни новой паре команд. Но мы добавим еще один элемент:

  • git checkout <em>name</em> может выполнить или небезопасный один или безопасный один, в зависимости от что-то, о чем вы, возможно, даже не задумывались!

Теперь, этот последний пункт отмечен в последних Git версиях. Предположим, у вас есть имя для удаленного отслеживания origin/dev и вы хотите создать ветку dev соответственно. Обычно вы можете просто выполнить:

git checkout dev

Предположим, однако, что ваша текущая (вероятно, master) проверка имеет каталог с именем dev, и в этом каталоге вы проделал кучу работы и еще не совершил ее. Вы только что вспомнили: Я должен зафиксировать всю эту работу, которую я только что выполнил в ветке dev, а не в ветке master.

Теперь нет ветки dev в все, но там есть dev/ файлы . Вот что делает старый Git:

sh-3.2$ git --version
git version 2.20.1
sh-3.2$ git branch -r
  origin/dev

(то есть origin/dev существует; ветка dev не существует, и я здесь master)

sh-3.2$ git status --short
 M dev/file
sh-3.2$ git diff
diff --git a/dev/file b/dev/file
index e69de29..c238a0b 100644
--- a/dev/file
+++ b/dev/file
@@ -0,0 +1 @@
+look at all this work I did

Добавление этой строки заняло недель кропотливой работы! : -)

sh-3.2$ git checkout dev

Э-э-э. Почему это не говорит мне о создании ветви с именем dev, настроенной на отслеживание origin/dev?

sh-3.2$ git status
On branch master
nothing to commit, working tree clean

Гах! Моя тяжелая работа ушла!

Проблема в том, что git checkout выполнил команду unsafe . Я мог ожидать, что он будет использовать безопасный ... но это не так.

Более современный Git (2.24.0) скажет мне, что git checkout dev неоднозначно, что хорошо : это не просто забивает мой файл. (Я не проверял сам Git 2.23, где впервые появились команды разбивки на две части.)

В любом случае, используя команды new , вы по крайней мере знаете, верно когда вы вводите команду, получите ли вы безопасный или небезопасный режим. Если ваши привычки установлены, и вы продолжаете использовать git checkout, или вас беспокоит примечание, в котором говорится, что эти новые команды все еще являются экспериментальными, вы все равно можете использовать старую - и она больше не просто уничтожает работу, в неоднозначный случай.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...