Какая разница между git reset --hard и git reset --merge

В моих экспериментах мне не удалось найти функциональную разницу между

git reset --hard

и

git reset --merge

В инструкциях по использованию не указывается ни

--hard                reset HEAD, index and working tree
--merge               reset HEAD, index and working tree

Я регулярно использую параметр --hard, чтобы понять, как это работает. Какая разница между параметрами --merge и --hard?

Cheers, Olly

Возможно, пример поможет здесь, используйте следующую последовательность:

cd git_repo
touch file_one
git add file_one
git commit -m "commit one" # sha1 of 123abc
echo "one" >> ./file_one
git commit -a -m "commit two" # sha1 of 234bcd
echo "two" >> ./file_one
git add . # populate index with a change
echo "three" >> ./file_one # populate working area with a change

Теперь, если я попробую

git reset --merge 123abc

Я получаю

error: Entry 'file_one' not uptodate. Cannot merge.
fatal: Could not reset index file to revision '123abc'

причина, заключающаяся в том, что file_one имеет изменения как в рабочей области, так и в индексе

Чтобы исправить это, я делаю

git add .
git reset --merge 123abc

На этот раз он работает, однако, я получаю тот же результат, что и git reset --hard. Индекс пуст, рабочая область пуста, file_one пуст, как и после первой фиксации.

Может кто-нибудь придумать шаги, которые иллюстрируют разницу?

Ответ 1

От git reset manpage:

--hard    Matches the working tree and index to that of the tree being
               switched  to. Any changes to tracked files in the working tree since
               <commit> are lost.

--merge
              Resets the index to match the tree recorded by the named commit, and
              updates the files that are different between the named commit and
              the current commit in the working tree.

git reset --merge означает более безопасную версию git reset --hard, когда ваши изменения и изменения кого-либо другого смешиваются вместе, пытаясь нести наши изменения.

Ответ 2

В статье " Git undo, reset или revert?" суммируются различные способы использования при использовании с ORIG_HEAD:

# Reset the latest successful pull or merge
$ git reset --hard ORIG_HEAD

# Reset the latest pull or merge, into a dirty working tree
$ git reset --merge ORIG_HEAD

Как упоминалось manojlds , и проиллюстрировано сообщение в блоге, последнее особенно полезно, когда вы видите сообщение об ошибке вроде:

fatal: You have not concluded your merge. (`MERGE_HEAD` exists)

Нить " [PATCH] отказывается сливаться во время слияния "также детализирует эту точку:

git reset --merge HEAD

Он заполняет довольно другой случай, когда вы сделали чистое слияние с некоторыми незафиксированными изменения в worktree, но затем хотите сбросить слияние снова, не теряя незавершенных изменений.
В отсутствие изменений вы просто используете --hard, но здесь вы хотите переместить кончик ветки, сливая их, подобно тому, что делает git checkout -m 'для перемещение HEAD.

Ответ 3

Это полезно, когда вы делаете попытку с изменениями в рабочем дереве и обнаруживаете, что слияние не так, как ожидалось (вы, возможно, ожидали, что коммиты не повлияют на файлы, над которыми вы работали). На данный момент, если вы делаете git reset --hard ORIG_HEAD, вы удаляете все, включая локальные изменения. Если вы выполните git reset --merge ORIG_HEAD, вы сохраните локальные изменения.

Ответ 4

По-видимому, согласно:

http://www.kernel.org/pub/software/scm/git/docs/git-reset.html

- hard - сопоставляет рабочее дерево и индекс с деревом, на которое переключается. Любые изменения в отслеживаемых файлах в рабочем дереве поскольку <commit> теряются.

- merge. Сбрасывает индекс в соответствии с деревом, записанным именованным фиксатором, и обновляет файлы, которые отличаются от имени commit и текущий фиксатор в рабочем дереве.