Как я могу "отменить" отмененную фиксацию Git?


учитывая изменение, которое было совершено с использованием commit, а затем вернулся через revert, что является лучшим способом, чтобы отменить то, что отменить?

В идеале это должно быть сделано с новой фиксацией, чтобы не переписывать историю.

8 289

8 ответов:

Если вы еще не подтолкнули это изменение,git reset --hard HEAD^

В противном случае, возврат revert отлично подходит.

другой способ -git checkout HEAD^^ -- . а то git add -A && git commit.

git cherry-pick <original commit sha>
Сделаем копию исходного коммита, по сути повторно применив коммит

возврат revert сделает то же самое, с сообщением messier commit:
git revert <commit sha of the revert>

любой из этих способов позволит вам git push без перезаписи истории, потому что он создает новый коммит после возвращения.
При вводе commit sha вам обычно нужны только первые 5 или 6 символов:
git cherry-pick 6bfabc

Это выглядит глупо для меня. Но я был в той же ситуации, и я вернулся к отмененным коммитам. Я сделал количество ревертов, поэтому мне пришлось вернуться для каждого "revert commit".

теперь моя история коммитов выглядит немного странно.

weird history

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

вы можете git checkout -b <new-branch> и git cherry-pick <commit> до и git rebase падение revert commit. отправить запрос на вытягивание, как и раньше.

возврат фиксации так же, как и любой другой фиксации в git. То есть, вы можете вернуть его, как в:

git revert 648d7d808bc1bca6dbf72d93bf3da7c65a9bd746

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

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

      7963f4b2a9d   Revert "Revert "OD-9033 parallel reporting configuration"
      "This reverts commit a0e5e86d3b66cf206ae98a9c989f649eeba7965f.
                    ...
     a0e5e86d3b6    Revert "OD-9055 paralel reporting configuration"
     This reverts commit 648d7d808bc1bca6dbf72d93bf3da7c65a9bd746.
                ...
     Merge pull request parallel_reporting_dbs to master* commit 
    '648d7d808bc1bca6dbf72d93bf3da7c65a9bd746'

таким образом, вы можете проследить историю и выяснить всю историю, и даже те, кто без знания наследия может решить это для себя. Тогда как, если вы cherry-pick или rebase материал, эта ценная информация теряется (если вы не включите ее в комментарий.)

очевидно, что если фиксация возвращена и повторно возвращена более одного раза, это становится довольно грязным.

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

учитывая следующую стартовую ситуацию

 P---o---o---M---x---x---W---x
  \         /
   A---B---C----------------D---E   <-- fixed-up topic branch

(W-ваш первоначальный возврат слияния M; D и E-исправления для вашей изначально сломанной ветви/фиксации функции)

теперь вы можете просто воспроизвести коммиты A В E, так что ни один из они "принадлежат" к возвращенному слиянию:

$ git checkout E
$ git rebase --no-ff P

новая копия вашей ветви теперь может быть объединена в master еще раз:

   A'---B'---C'------------D'---E'  <-- recreated topic branch
  /
 P---o---o---M---x---x---W---x
  \         /
   A---B---C----------------D---E

вот как я это сделал:
Если ветка my_branchname был включен в слияние, которое было отменено. И я хотел unrevert my_branchname:

я сначала делаю git checkout -b my_new_branchname С my_branchname.
Тогда я делаю git reset --soft $COMMIT_HASH здесь $COMMIT_HASH является хэшем фиксации права фиксации до первый коммит my_branchname (см. git log)
Затем я делаю новый коммит git commit -m "Add back reverted changes"
Затем я толкаю вверх новую ветку git push origin new_branchname
Затем я сделал запрос для новой отделение.

возврат revert сделает трюк

например,

If abcdef is your commit and ghijkl is the commit you have when you reverted the commit abcdef,

потом типа

git revert ghijkl

это вернет revert