Вопрос по git, version-control – Как я могу вернуть несколько коммитов Git (уже переданных) в опубликованный репозиторий?

57

Новый для мерзавца, и уже испорченный.

Я зафиксировал некоторые изменения на удаленной машине разработчика. Мне нужно восстановить более старую версию, но сохранить «плохой прогресс» делать так, чтобы продолжать работать над отдельной веткой;

Я думал сделать это так:

Create a local branch named: "tested-thing" Revert local repository to the state where it worked (hopefully meaningful commits will help);

Push to remote

finish tests on tested-thing

Merge "tested-thing" into dev Push to remote

Между этапами 3 и 5 другие разработчики могут фиксировать и выдвигать, и я боюсь, что это может привести к «трагедии слияния». - Во всяком случае, это может быть правильный путь?

UPDATE:

The main problem here resides on 2)

Здесь по теме: «разбить работу на ветку темы» http://learn.github.com/p/undoing.html

Они предлагают:

$ git branch test $ git reset --hard a6b4c974

Таким образом, другие разработчики могут:

$ git commit (на ветке разработчика)

и я могуcheckout to test и работать доmerge время.

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

Пожалуйста, обратите внимание на следующее:Since I made those changes and I mess up the all thing, no one else have worked on the repository so far. So, if I revert the working directory, no one will notice.

Ваш Ответ

3   ответа
25

Если вы уже отправили информацию на удаленный сервер (и у вас есть другие разработчики, работающие с той же удаленной веткой), важно помнить, что вы не хотите переписывать историю

Don't use git reset --hard

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

если тыhave not внес изменения в пульт, вы можете использовать

git reset --hard <hash>

если тыhave подтолкнул изменения, но уверен, что никто не потянул их, вы можете использовать

git reset --hard
git push -f

если тыhave подтолкнул изменения, и кто-то втянул их в их оформление, вы все еще можете сделать это, но другой член команды / оформить заказ должен будет сотрудничать:

(you) git reset --hard <hash>
(you) git push -f

(them) git fetch
(them) git reset --hard origin/branch

Но, вообще говоря, это превращается в беспорядок. Итак, возвращаясь:

The commits to remove are the lastest

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

Сначала вам нужно определить коммит, к которому вы хотите вернуться, вы можете сделать это с помощью:

git log

просто найдите коммит до ваших изменений и запишите хеш коммита. вы можете ограничить журнал самыми последними коммитами, используя-n флаг:git log -n 5

Затем верните ветку в состояние, которое вы хотите, чтобы другие разработчики видели:

git revert  <hash of first borked commit>..HEAD

Последний шаг - создать собственную локальную ветвь, применив ваши отмененные изменения:

git branch my-new-branch
git checkout my-new-branch
git revert <hash of each revert commit> .

Продолжайте работать вmy-new-branch пока вы не закончили, затем объедините его с вашей основной веткой разработки.

The commits to remove are intermingled with other commits

Если коммиты, которые вы хотите отменить, не все вместе, вероятно, проще всего отменить их по отдельности. Снова используяgit log найдите коммиты, которые вы хотите удалить, а затем:

git revert <hash>
git revert <another hash>
..

Затем снова создайте свою ветку для продолжения работы:

git branch my-new-branch
git checkout my-new-branch
git revert <hash of each revert commit> .

Затем снова взломайте и объедините, когда вы закончите.

Вы должны получить историю коммитов, которая выглядит следующим образом:my-new-branch

2012-05-28 10:11 AD7six             o [my-new-branch] Revert "Revert "another mistake""
2012-05-28 10:11 AD7six             o Revert "Revert "committing a mistake""
2012-05-28 10:09 AD7six             o [master] Revert "committing a mistake"
2012-05-28 10:09 AD7six             o Revert "another mistake"
2012-05-28 10:08 AD7six             o another mistake
2012-05-28 10:08 AD7six             o committing a mistake
2012-05-28 10:05 Bob                I XYZ nearly works

Better way®

Тем более, что теперь, когда вы знаете об опасностях нескольких разработчиков, работающих в одной ветке, рассмотрите возможность использования ветвей функцийalways для вашей работы. Все это означает, что работа в ветке продолжается до тех пор, пока что-то не будет завершено, и только затем объединить ее с вашей основной веткой. Также рассмотрите возможность использования таких инструментов, какГИТ-поток автоматизировать создание филиалов в согласованном порядке.

+1 заgit reset без флага --hard, но я не думаю, что большинство людей поймут, что вы сбрасываете и рабочий каталог, и HEAD, что приведет к! [rejected] master -> master (non-fast-forward) на толчок. Кроме того, если много файлов было изменено, это делает действительно широкий патч, даже если вы принудительно делаете коммит.
@ AD7Six: Спасибо за это зарегистрированное дополнение торговой марки Better Way. На самом деле, ветки настолько дешевы, что я решил сделать это сразу после этого глупого шага. Зная, что никто, кроме меня, не трогал хранилище, так как я все это испортил, может помочь в использовании подхода к обновлению моего вопроса? MEM
@ Код, ты прав, это так давно, когда я оказался в этом положении:]
@MEM: не имеет значения, обновил ли репозиторий никто другой, - важно, обновил ли кто-то свою кассу после "ошибок". были совершены. Потому что, если у них есть, когда они извлекают, их проверка будет по-прежнему содержать коммиты, которые вы принудительно удалили, объединенные с любыми новыми изменениями. Если вы используетеgit reset --hard в вашей функциональной ветке, когда вы объединяете ее, вы, скорее всего, будете получать конфликты, так как удаленные коммиты будут применены повторно - в основном, нет, вероятно, это не очень хорошая идея делать это.
107

The Problem

Есть несколько рабочих процессов, которые вы можете использовать. Суть в том, чтобы не разрушать историю в опубликованной ветви, если вы не общаетесь со всеми, кто может использовать ветку и готовы сделать операцию на всех клонах. Лучше не делать этого, если вы можете избежать этого.

Solutions for Published Branches

Ваши намеченные шаги имеют свои достоинства. Если вам нужно, чтобы ветка dev была стабильной сразу, сделайте это так. У вас есть ряд инструментов дляОтладка с помощью Git это поможет вам найти правильную точку ветвления, а затем вы сможете отменить все коммиты между вашим последним стабильным коммитом и HEAD.

Либо отменить фиксацию по одному, в обратном порядке, либо использовать<first_bad_commit>..<last_bad_commit> спектр. Хэши - это самый простой способ указать диапазон фиксации, но есть и другие обозначения. Например, если вы нажали 5 неудачных коммитов, вы можете отменить их с помощью:

# Revert a series using ancestor notation.
git revert --no-edit dev~5..dev

# Revert a series using commit hashes.
git revert --no-edit ffffffff..12345678

Это будет последовательно применять обратные патчи к вашему рабочему каталогу, возвращаясь к вашей заведомо исправной фиксации. С--no-edit Отметьте, что изменения в вашем рабочем каталоге будут автоматически зафиксированы после применения каждого исправленного патча.

Увидетьman 1 git-revert для большего количества вариантов, иman 7 gitrevisions для разных способов указать коммиты, которые будут возвращены.

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

The Danger Zone

Конечно, если выabsolutely sure что никто не вытащил из хранилища, так как ваши плохие толчки, и если пульт являетсяbare repository, тогда вы можете сделать коммит без ускоренной перемотки вперед.

git reset --hard <last_good_commit>
git push --force

Это оставит reflog нетронутым в вашей системе и на вышестоящем хосте, но ваши плохие коммиты исчезнут из истории прямого доступа и не будут распространяться при вытягивании Ваши старые изменения будут зависать до тех пор, пока хранилища не будут сокращены, но только Git-ниндзя смогут увидеть или восстановить сделанные вами коммиты по ошибке.

Если люди уже клонировали плохие сообщения и были уведомлены - что они должны сделать, чтобы иметь ту же ветку, что и в удаленном? Должны ли они сделать то же самоеgit reset --hard <last_good_commit>?
git revert --no-edit head~2..head работает отлично.
Если вы используете теги коммитов, это не<first_bad_commit>..<last_bad_commit>, скорее<last_good_commit>..<last_bad_commit>
0
git revert HEAD -m 1

В приведенной выше строке кода. & quot; Последний аргумент представляет & quot;

  • 1 - reverts one commits. 2 - reverts last commits. n - reverts last n commits

или же

git reset --hard siriwjdd

выдает ошибку: зафиксируйте a17dc423957324b2b537c1caa9d9476c9b443f48 не имеет родителя n, где n - последний аргумент

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