Отмените конкретную фиксацию в Git, которая была перенесена на удаленные репозитории

Каков самый простой способ отменить конкретную фиксацию, которая:

  • не в голове или голове
  • Был нажат на удаленный компьютер.

Потому что, если это не последняя фиксация,

git reset HEAD

не работает. И поскольку он был нажат на удаленный,

git rebase -i

и

git rebase --onto

вызовет некоторые проблемы в пультах.

Более того, я не хочу действительно изменять историю. Если был плохой код, он был там в истории и может быть замечен. Я просто хочу, чтобы это было в рабочей копии, и я не возражаю против фиксации слияния.

Другими словами, что означает Git эквивалент следующих команд svn:

svn merge -r 303:295 http://svn.example.com/repos/calc/trunk

который удаляет все изменения с 295 до 302 путем обратного слияния всех изменений в этих ревизиях в качестве нового коммита.

svn merge -c -302 ^/trunk

который отменяет фиксацию 302, конечно, путем добавления другого коммита, который обратный объединяет изменения с соответствующей фиксацией.

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

У нас есть постановка stashing и все, чтобы гарантировать, что коммиты совершенно атомарны, разве вы не сможете отменить один или несколько из этих атомных легко фиксируется?

Ответ 1

Определите хэш фиксации, используя git log, затем используйте git revert <commit>, чтобы создать новую фиксацию, которая удаляет эти изменения. В некотором смысле git revert является обратным символом git cherry-pick - последний применяет патч к ветки, которая его отсутствует, первая удаляет ее из ветки, которая ее имеет.

Ответ 2

Мне не нравится auto-commit, что git revert, так что это может быть полезно для некоторых.

Если вы хотите, чтобы измененные файлы не были автоматически зафиксированы, вы можете использовать --no-commit

% git revert --no-commit <commit hash>

который совпадает с -n

% git revert -n <commit hash>

Ответ 3

Поскольку он уже был нажат, вы не должны напрямую манипулировать историей. git revert вернет определенные изменения из фиксации с использованием нового коммита, чтобы не манипулировать историей фиксации.