Почему в Git нет отмены / возврата? - PullRequest
9 голосов
/ 01 декабря 2011

Насколько я знаю, когда вы хотите отменить что-то в Git, вы должны явно найти команду, чтобы отменить все, что вы сделали, и выпустить ее. Например, один из многих способов отменить коммит и повторить его - следовать примеру из здесь ,

$ git commit ...
$ git reset --soft HEAD^
$ edit
$ git add ....
$ git commit -c ORIG_HEAD 

Или, чтобы отменить тягу, вы можете следовать инструкциям здесь ,

$ git reset --hard

Но эти команды не обязательно работают взаимозаменяемо. Есть ли причина, по которой Git не разрешает простые команды отмены и повтора? Что-то связанное с философией, стоящей за этим? Кроме того, у меня нет большого опыта работы с другими системами контроля версий, но предлагает ли какая-либо из них простую команду отмены и повтора?

Ответы [ 4 ]

7 голосов
/ 02 декабря 2011

Существует несколько проблем с таким понятием:

  • Не все операции обратимы.Иногда это происходит из-за того, что Git не записывает достаточно информации, чтобы вывести предыдущее состояние - это было бы слишком дорого в общем.Иногда такие вещи, как git reset --hard или git clean, уничтожают неотслеживаемые изменения.Чтобы отменить их, необходимо постоянно выполнять автоматическое резервное копирование.Иногда это происходит потому, что понятие отмены неоднозначно - как вы сами отметили, существует множество способов отменить фиксацию.

  • Если операция обратима и требует некоторогоистория, должны ли отмены / повторы также быть в истории, или они должны заставить это исчезнуть?Должен ли коммит быть отменен путем сброса назад или путем возврата (создания другого коммита для его отмены)?

  • Без регистрации всех последних действий, которые вы делаете, как вы узнаете, какая самая последняя операциябыло?Допустим, вы добавили файл в индекс и создали ветку.Нет записей о том, что было первым.

Даже если бы все было четко определено, это было бы нелепое количество работы для выполнения.Как вы решаете, что представляет собой одно действие?Одна команда Git может сделать много вещей.Должен ли он отменить один шаг, все это?Что, если вы выполнили миллион команд, каждая из которых делает маленький шаг, и вы хотите отменить все это?И это должно быть идеально , совершенно идеально, потому что это особенность, которая будет использоваться неопытными пользователями, которые не имеют ни малейшего представления, как исправить ошибки.

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

Кроме того, в отношении «повторить», каквы определили это в своем вопросе, он повторяет команду, не выполняя первоначальную операцию снова.Когда вы переделали коммит, он был другим.Повторное выполнение предыдущей команды - это то, что оболочки командной строки были предназначены для выполнения.Git не нужно изобретать это заново.

4 голосов
/ 01 декабря 2011

На самом деле ваш первый пример может быть выполнен с:

$ git commit ...
$ edit
$ git add ...
$ git commit --amend

Ваш второй пример должен быть больше похож на git reset --hard <hash>

Ответ на ваш вопрос в том, что это возможно, но даэто больше философия вождения мерзавца, что означает, что это не было сделано.Теоретически нет никакого способа определить, получил ли вы коммит, создав его или удалив другой, но, используя рефлог, это возможно ... не думал об этом раньше.

Я не знаюЯ не думаю, что «отменить» и «повторить» - это очень распространенная вещь в управлении исходным кодом, но поправьте меня, если я ошибаюсь.используя reflog - не уверен, достаточно ли там информации, но стоит попробовать.

1 голос
/ 02 декабря 2011

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

Это сказало, что у него есть различные журналы, такие как reflog, чтобы вы могли оглянуться назад на то, что было сделано.

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

0 голосов
/ 22 февраля 2013

Наряду с другими комментариями я бы проверил git stash. Много раз я прячу какую-то работу, исправляю что-то другое, затем распаковываю и продолжаю. Или для веб-приложения: спрячьте мою готовую и незафиксированную работу, обновите браузер, распакуйте, откройте новую вкладку, а затем сравните две страницы вперед и назад, чтобы убедиться, что исправление ошибки, связанной с пользовательским интерфейсом, не сломало ничего.

...