Проще говоря, что означает & ldquo; git reset & rdquo; делать?

Просто удаленная версия jre-32 bit и она отлично работает для меня.

641
задан MusTheDataGuy 7 November 2018 в 15:19
поделиться

2 ответа

В общем, функция git reset заключается в том, чтобы взять текущую ветку и сбросить её в другое место, и, возможно, принести с собой индекс и рабочее дерево. Более конкретно, если ваша ветка master (в настоящее время вычеркнутая) выглядит так:

- A - B - C (HEAD, master)

и вы понимаете, что хотите, чтобы master указывала на B, а не на C, вы используете git reset B, чтобы переместить её туда:

- A - B (HEAD, master)      # - C is still here, but there's no branch pointing to it anymore

Отступление: Это отличается от выгрузки. Если бы вы выполнили git checkout B, то получили бы следующее:

- A - B (HEAD) - C (master)

Вы оказались в отделенном состоянии HEAD. HEAD, рабочее дерево, индекс все соответствуют B, но мастер-ветвь была оставлена на C. Если вы сделаете новый коммит D в этот момент, вы получите следующее, что, вероятно, не то, чего вы хотите:

- A - B - C (master)
       \
        D (HEAD)

Помните, что сброс не делает коммитов, он просто обновляет ветвь (которая является указателем на коммит), чтобы она указывала на другой коммит. Остальное - это просто детали того, что происходит с вашим индексом и рабочим деревом.

Случаи использования

Я рассматриваю многие из основных случаев использования git reset в описании различных опций в следующем разделе. Он действительно может быть использован для множества вещей; общим является то, что все они включают сброс ветви, индекса и/или рабочего дерева для указания на/соответствия данному коммиту.

То, чего следует остерегаться

  • -hard может привести к тому, что вы действительно потеряете работу. Она изменяет ваше рабочее дерево.

  • git reset [options] commit может привести к тому, что вы (вроде как) потеряете коммиты. В игрушечном примере выше мы потеряли коммит C. Он всё ещё находится в репозитории, и вы можете найти его, посмотрев git reflog show HEAD или git reflog show master, но на самом деле он больше не доступен ни из одной ветки.

  • Git безвозвратно удаляет такие коммиты через 30 дней, но до тех пор вы можете восстановить C, снова указав на него ветку (git checkout C; git branch <имя новой ветки>).

Аргументы

Перефразируя man-страницу, наиболее часто используется в виде git reset [] [paths...], который вернет заданные пути к их состоянию после данного коммита. Если пути не указаны, то сбрасывается всё дерево, а если коммит не указан, то за него принимается HEAD (текущий коммит). Это общий паттерн для всех команд git (например, checkout, diff, log, хотя точная семантика варьируется), так что это не должно быть слишком удивительным.

Например, git reset other-branch path/to/foo возвращает всё в path/to/foo к состоянию в other-branch, git reset -- . возвращает текущий каталог к состоянию в HEAD, а простой git reset возвращает всё к состоянию в HEAD.

Основные опции рабочего дерева и индекса

Есть четыре основные опции для управления тем, что происходит с вашим рабочим деревом и индексом во время сброса.

Помните, что индекс является "перевалочным пунктом" git'а - это то место, куда всё попадает, когда вы говорите git add, готовясь к коммиту.

  • --hard заставляет всё соответствовать коммиту, на который вы сбросили. Это, пожалуй, самое простое для понимания. Все ваши локальные изменения будут уничтожены. Одно из основных применений - уничтожение вашей работы, но без переключения коммитов: git reset --hard означает git reset --hard HEAD, т.е. не меняйте ветку, но избавьтесь от всех локальных изменений. Другой вариант - просто переместить ветку из одного места в другое, синхронизируя индекс/рабочее дерево. Это тот вариант, который действительно может заставить вас потерять работу, потому что он изменяет ваше рабочее дерево. Будьте очень уверены, что хотите избавиться от локальной работы, прежде чем выполнять reset --hard.

  • --mixed используется по умолчанию, т.е. git reset означает git reset --mixed. Это сбрасывает индекс, но не рабочее дерево. Это означает, что все ваши файлы останутся нетронутыми, но любые различия между исходным коммитом и тем, на который вы сбросили, будут отображаться как локальные изменения (или неотслеживаемые файлы) в статусе git. Используйте этот способ, когда вы понимаете, что сделали несколько неудачных коммитов, но хотите сохранить всю проделанную работу, чтобы можно было исправить её и снова зафиксировать. Для фиксации вам придётся снова добавить файлы в индекс (git add ... ).

  • --soft не трогает индекс или рабочее дерево . Все ваши файлы остаются нетронутыми, как и при --mixed, но все изменения отображаются как changes to be committed со статусом git (т.е. проверенные в процессе подготовки к фиксации). Используйте это, когда вы понимаете, что сделали несколько неудачных коммитов, но работа в порядке - всё, что вам нужно сделать, это перекоммитить её по-другому. Индекс не тронут, поэтому вы можете сразу же зафиксировать работу, если хотите. результирующий коммит будет иметь то же содержимое, что и до сброса.

  • --merge был добавлен недавно и предназначен для того, чтобы помочь вам прервать неудачное слияние. Это необходимо, потому что git merge фактически позволит вам попытаться выполнить слияние с грязным рабочим деревом (с локальными изменениями), если эти изменения находятся в файлах, не затронутых слиянием. git reset --merge сбрасывает индекс (как --mixed - все изменения отображаются как локальные модификации), и сбрасывает файлы, затронутые слиянием, но оставляет остальные в покое. Это, надеюсь, вернет все к тому состоянию, в котором оно было до неудачного слияния. Обычно вы будете использовать его как git reset --merge (имеется в виду git reset --merge HEAD), потому что вы хотите только отменить слияние, а не переместить ветку. (HEAD ещё не обновлён, так как слияние не удалось)

    Чтобы быть более конкретным, предположим, что вы изменили файлы A и B, и пытаетесь объединить их в ветку, которая изменила файлы C и D. Слияние не удалось по какой-то причине, и вы решили прервать его. Вы используете git reset --merge. Это вернёт C и D к тому состоянию, в котором они были в HEAD, но оставит ваши изменения в A и B в покое, поскольку они не были частью попытки слияния.

Хотите узнать больше?

Я думаю, что man git reset действительно очень хорошо подходит для этого - возможно, вам нужно немного понять принцип работы git, чтобы он действительно усвоился. В частности, если уделить время внимательному чтению, то таблицы с подробным описанием состояний файлов в index и рабочем дереве для всех различных вариантов и случаев будут очень полезны. (Но да, они очень плотные - они передают огромное количество вышеуказанной информации в очень сжатой форме.)

Странная нотация

Упомянутая вами "странная нотация" (HEAD^ и HEAD~1) - это просто сокращение для указания коммитов, без необходимости использовать хэш-имя вроде 3ebe3f6. Он полностью документирован в разделе "specifying revisions" man-страницы для git-rev-parse, с большим количеством примеров и связанным синтаксисом. Каретка и тильда на самом деле означают разные вещи:

  • HEAD~ - это сокращение от HEAD~1 и означает первого родителя коммита. HEAD~2 означает первого родителя коммита. Считайте, что HEAD~n означает "n коммитов до HEAD" или "предок HEAD в n-ом поколении".
  • HEAD^ (или HEAD^1) также означает первого родителя коммита. HEAD^2 означает второго родителя фиксации. Помните, что обычный коммит слияния имеет двух родителей: первый родитель - это коммит, в который происходит слияние, а второй родитель - это коммит, который был слит. Вообще, у слияний может быть произвольно много родителей (осьминожьи слияния).
  • Операторы ^ и ~ могут быть объединены вместе, как в HEAD~3^2, втором родителе предка третьего поколения HEAD, HEAD^^2, второй родитель первого родителя HEAD, или даже HEAD^^^, что эквивалентно HEAD~3.

caret and tilde

961
ответ дан 22 November 2019 в 21:47
поделиться

Помните, что в git у вас есть:

  • указатель HEAD , который сообщает вам над каким коммитом вы работаете
  • рабочее дерево , которое представляет состояние файлов в вашей системе
  • промежуточная область (также называемая индексом ), которые "этапы" изменяются так, чтобы впоследствии их можно было зафиксировать вместе

Пожалуйста, включите подробные объяснения о:

- жестком , - мягком и --merge ;

В порядке возрастания опасности:

  • - soft перемещает HEAD , но не касается промежуточной области или рабочего дерева.
  • - смешанный перемещает HEAD и обновляет промежуточную область, но не рабочее дерево.
  • - merge перемещает HEAD , сбрасывает область подготовки и пытается переместить все изменения в вашем рабочем дереве в новое рабочее дерево.
  • - жестко перемещает HEAD и настраивает вашу промежуточную область и рабочее дерево на новую HEAD , отбрасывая все.

конкретные варианты использования и рабочие процессы;

  • Используйте - soft , когда вы хотите перейти к другой фиксации и исправить ситуацию, не «теряя свое место». Это бывает довольно редко.

-

# git reset --soft example
touch foo                            // Add a file, make some changes.
git add foo                          // 
git commit -m "bad commit message"   // Commit... D'oh, that was a mistake!
git reset --soft HEAD^               // Go back one commit and fix things.
git commit -m "good commit"          // There, now it's right.

-

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

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

  • Используйте - hard , чтобы стереть все и начать с нового коммита.

78
ответ дан 22 November 2019 в 21:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: