Получение исходного хэша фиксации из обратной фиксации

Предположим, у меня есть эта история:

...
* c1   
...
* cr: git revert c1
...

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


person Cactus    schedule 09.10.2015    source источник
comment
Обычно git revert пишет вам сообщение фиксации, в котором говорится This reverts commit <hash>. Это отсутствует или неверно по какой-то причине? (Если это так, вам в основном не повезло: вы можете попробовать отменить возврат, а затем посмотреть, сможете ли вы найти более раннюю фиксацию с теми же изменениями, например, с помощью git cherry. В цепкой руке часто вы можете просто отменить возврат .)   -  person torek    schedule 09.10.2015
comment
Мне нужен исходный коммит, чтобы я мог получить из него некоторые метаданные. Я должен добавить к моему вопросу, что я ищу программный способ.   -  person Cactus    schedule 09.10.2015
comment
Вы делаете много возвратов? Это может указывать на проблему с вашей моделью разработки.   -  person Schwern    schedule 09.10.2015
comment
@Schwern: я обычно вообще не возвращаюсь. То, что я пытаюсь здесь решить, больше связано с обнаружением беспорядка, вызванного другими разработчиками.   -  person Cactus    schedule 09.10.2015


Ответы (2)


Как отмечено в комментарии, это основано на обычном сообщении журнала возврата, но в остальном это просто:

git log -1 --format=%B $revspec | \
    perl -n -e '/^This reverts commit ([0-9a-f]+)/ && print $1 '

(где $revspec — это то, как вы намереваетесь назвать фиксацию возврата, будь то необработанный SHA-1, или что-то вроде master~5, или что-то еще).

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

person torek    schedule 09.10.2015
comment
Коммиты @Cactus Git не хранят много метаданных, они полагаются на сообщения фиксации, и это позор. - person Schwern; 09.10.2015

Да. Сообщение журнала возврата по умолчанию содержит идентификатор оригинала. Вы можете разобрать git log, чтобы найти его. @torek уже рассказывал об этом.

Что делать, если вы не использовали сообщение о возврате по умолчанию? Ты СОЛ. Почему? Git больше нигде не хранит информацию об отмене. И вы не можете получить исходный идентификатор коммита.

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

Не могли бы вы использовать diff с предыдущим коммитом, чтобы восстановить исходное сообщение коммита? Опять же, нет. Во-первых, не гарантируется, что diff будет таким же, например, мог быть конфликт или части diff могли перемещаться. Что еще более важно, идентификатор фиксации представляет собой контрольную сумму не только содержимого, включая такие вещи, как содержимое файлов, журнал сообщение, дату и т. д. Вам также нужно знать все это, чтобы сгенерировать исходный идентификатор коммита.

Ваше последнее убежище для уничтожения вещей — git reflog, но и это вам не поможет. Он зафиксирует факт возврата, но сообщение будет первой строкой вашего сообщения фиксации. Он не будет содержать исходный идентификатор коммита.


Надежда есть, но она не программная. Получите разницу в возврате, найдите существенную строку изменения, удалите + или -. Теперь запустите git log -S'...yourline', чтобы найти коммиты, которые изменили эту строку.

Например, допустим, у меня...

commit 2c257ccae4c124e7cff6cfa7ca069250fb33907f (HEAD -> master)
Author: Michael G. Schwern <[email protected]>
Date:   Thu Oct 8 20:19:26 2015 -0700

    dlfjalkdjflkadj

diff --git a/Build.PL b/Build.PL
index 8c87db4..bed5170 100644
--- a/Build.PL
+++ b/Build.PL
@@ -73,10 +73,6 @@ my $builder = MyBuild->new(
         # so some CPAN shells won't see it.
         "Module::Build"      => '0.36',
     },
-    recommends => {
-        # Significant performance improvements
-        autodie         => '2.26',
-    },

     meta_merge => {
         resources => {

Затем я мог запустить git log -S'Significant performance improvements' и получить:

commit 2c257ccae4c124e7cff6cfa7ca069250fb33907f (HEAD -> master)
Author: Michael G. Schwern <[email protected]>
Date:   Thu Oct 8 20:19:26 2015 -0700

    dlfjalkdjflkadj

commit ac43bedc8c70fb851c7a594cace18d5fbad135ac
Author: Michael G. Schwern <[email protected]>
Date:   Wed Dec 31 14:46:05 2014 -0800

    Recommend the latest autodie which has significant performance improvements.

    It's loads much faster and uses much less memory and has significant bug fixes.
    None of this is required by perl5i, so I left the required version at what
    Debian stable is using.

    In the future this can be bumped to a requirement.

    For #284
person Schwern    schedule 09.10.2015