Позвольте мне исследовать, почему это сложная проблема с использованием внутренностей git. Вы можете получить sha1 текущего коммита
#!/bin/bash
commit=$(git cat-file commit HEAD) #
sha1=($((printf "commit %s\0" $(echo "$commit" | wc -c); echo "$commit") | sha1sum))
echo ${sha1[0]}
По сути, вы запускаете контрольную сумму sha1 для сообщения, возвращаемого пользователем git cat-file commit HEAD
. При рассмотрении этого сообщения сразу же возникают две проблемы. Одним из них является дерево sha1, а вторым - время фиксации.
Теперь время фиксации легко можно изменить, изменив сообщение и угадав, сколько времени потребуется для принятия или планирования фиксации в определенное время. Истинная проблема - это дерево sha1, которое вы можете получить git ls-tree $(git write-tree) | git mktree
. По сути, вы делаете контрольную сумму sha1 для сообщения от ls-tree, которое представляет собой список всех файлов и их контрольную сумму sha1.
Поэтому ваша контрольная сумма коммитов sha1 зависит от вашей контрольной суммы sha1 дерева, которая напрямую зависит от контрольной суммы файлов sha1, которая завершает круг и зависит от коммитов sha1. Таким образом, у вас есть круговая проблема с методами, доступными для меня.
С менее безопасными контрольными суммами было показано, что можно записать контрольную сумму файла в сам файл с помощью грубой силы; однако я не знаю ни одной работы, которая бы выполнила эту задачу с помощью sha1. Это не невозможно, но почти невозможно с нашим текущим пониманием (но кто знает, может быть, через пару лет это будет тривиально). Тем не менее, перебор еще труднее, так как вы должны записать в файл контрольную сумму (commit) контрольной суммы (tree) контрольной суммы (blob).