2016-11-09 13 views
1

Кто-то совершил что-то несколько месяцев назад. После этого было сделано несколько других коммитов. Можно ли увидеть, изменил ли кто-то содержимое этой определенной фиксации, изменив или переконфигурировав? Если да, то как?Как узнать, было ли изменено git?

+0

Что вы хотите делать с информацией? – NiVeR

+0

У меня такое ощущение, что был саботаж, и я хотел бы знать, так ли это. –

+3

Если у вас все еще есть клон того же репозитория в старом состоянии, просто сравните хэш-коды двух коммитов. – choroba

ответ

3

A commit, in Git, is never изменен. Ни rebase, ни git commit --amend никогда не изменяют никаких фиксаций, поскольку это невозможно.

Трюк здесь заключается в определении «фиксации». Откуда вы знаете, какая фиксация есть? Если я скажу «фиксация в репозитории Git для Git», то там будет более 40 000 коммитов. Какой номер я имею в виду?

Недвусмысленный и определенный способ для меня до сообщить. Вы должны предоставить вам идентификатор хэша, например, 9b7cbb315923e61bb0c4297c701089f30e116750. Это истинное имя для одного конкретного коммита:

$ git cat-file -p 9b7cbb315923e61bb0c4297c701089f30e116750 | sed 's/@/ /' 
tree 4ba58c32960dcecc1fedede9c9362f5c10158f08 
parent 77933f4449b8d6aa7529d627f3c7b55336f491db 
author Junio C Hamano <gitster pobox.com> 1418845774 -0800 
committer Junio C Hamano <gitster pobox.com> 1418845774 -0800 

Git 2.2.1 

Signed-off-by: Junio C Hamano <gitster pobox.com> 

Это имя постоянно прикрепляется к данному конкретному фиксации. Правда, это громоздкое и уродливое имя. Было бы неплохо иметь более короткое, красивое, wieldy имя? И есть один: я могу указать вам на v2.2.1:

$ git rev-parse v2.2.1^{commit} 
9b7cbb315923e61bb0c4297c701089f30e116750 

Но на самом деле, v2.2.1 не коммит вообще, это тег. В частности, это имя тега (находится в refs/tags/v2.2.1 или в packed-refs файл под именем v2.2.1), указывающий на аннотированный тег объекта, , а не непосредственно к совершению:

$ git rev-parse v2.2.1 
7c56b20857837de401f79db236651a1bd886fbbb 

Тег объекта имеет совершить идентификатор внутри него, а также целую кучу дополнительных Goop, в том числе «PGP подпись»:

$ git cat-file -p v2.2.1 | sed 's/@/ /' 
object 9b7cbb315923e61bb0c4297c701089f30e116750 
type commit 
tag v2.2.1 
tagger Junio C Hamano <gitster pobox.com> 1418851265 -0800 

Git 2.2.1 
-----BEGIN PGP SIGNATURE----- 
Version: GnuPG v1 

iQIcBAABAgAGBQJUkfPBAAoJELC16IaWr+bLjfgP/iA78fk3NkTEROoyIVq6kPDH 
pZAlm4ObsKXAdl6sFqWe7xFxGExHYzJ5L3qGXs3VM+9Z3iDe2WZN3WbK3aFtYqfU 
AYRSTpnPzDf4L0vfyqiFS7//+LoeM2TogAV7SLdehMlodsL5HR6FiSz1zffSq8D0 
Ci4XpGWHkqXLhfvUPC7foCgGpf7l38gsbJPbdkyKLK9/wtLSfkk45vK+wY6o3CCv 
JKBFr468958fvw+j73nxiT+Vne7TeL1Bq1kCq9M65dAjOpFjZiD408NaF7jTcNcx 
TMjdKoVlDNFHcUPMv9B5C308sRVUylmeUzb8XrQNji0+1NA5ivVgDfZsudWUtlTj 
jo9xku0Np4IdXPwxJNlO5tC2rnof4gdD4jWPJj/DvellNKCDXuLuXDZSKZDI9GSr 
OzLsad8uFX3MySPe+evIVF6qGS2KzI8PGNrohqWaPkX8cug22EW7lKJFpjYJb5gP 
3nJUJvbsrMeyoH/GqxPzA5clqMGtsirnTiapMILNRmlC+3rzc0DkLw90BM6vKNOC 
eDTOI9Xj1JS9qbD6fEkxVNrXRDz0TFbtpFbFTtKk4zfAc/jTOqE9fqpV7afoQfON 
e1NwrjR5Kcts7ev23Y0G1WH3t2L0N2/q27kcjrulCEH1vtXlmaZFU6o+WKUVV7iH 
/YQnjNUOgRxQ1zBGof7h 
=yJ4Q 
-----END PGP SIGNATURE----- 

PGP подпись является то, что позволяет нам решить, верим ли мы Junio ​​C Hamano действительно сделал и подписал этот тег. Он использует более прочную форму цифровой подписи шифрования, чем SHA-1 (что хорошо, поскольку SHA-1, по крайней мере теоретически, прерывистый), который также поддерживает как распределенную проверку, так и способность отменить подписи (которые SHA-1 сам не делает).

В конце концов, тем не менее, это помогает нам , если кто-то, кому мы доверяем и/или можем проверить, сделал такой тег, подписанный PGP, или подписал PGP. Теоретически, подписание каждой фиксации может быть немного сильнее с тех пор, когда на коммите есть цифровая подпись; но на практике подписывать метки гораздо удобнее и так же хорошо, что мы не будем регулярно ломать SHA-1 (и, по крайней мере, с помощью современных методов грубой силы, это оставило бы очевидные оценки, если бы мы это сделали, хотя это путь, выходящий за рамки этого ответа, а также несколько вне меня, чтобы описать правильно - криптография - это не мое поле).


Ну, это теоретически возможно, если вы можете break the SHA-1 hash. То, как Git ведет себя, если вы придумали новый, другой объект, который тем не менее производит то же самое hash означает, что вы никогда не заберете этот новый объект, если у вас уже есть старый.Это правило применяется ко всем объектам Git (коммиты, деревья, аннотированные теги и капли), все из которых называются своими хэшами.

Что git rebase и git commit --amend сделать, чтобы сделать его показаться как они изменили фиксации, чтобы сделать новые копии существующих фиксаций, а затем перетасовать имена вокруг. Новые коммиты имеют новые, разные хэши, а так как позже (потомок) совершает буквально содержит хеш своего непосредственного предка (родительского) commit, «меняя» хэш хэша (например, копируя объект commit на новый, другой объект фиксации) заставляет изменение опускаться вниз через остальную часть коммитов. Затем мы перетаскиваем существующий (короткий, ветвь или тег) имя на кончик новой цепи.

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

Это делает то, что Git называет «аннотированный тег»: имя тега (который сам по себе был бы «легкий тег»), указывающий на объект аннотированный-тегов, которые хранятся в хранилище Git, с объект тега, указывающий на какой-то другой объект Git - обычно это фиксация, но, возможно, еще один тег или даже дерево или blob. Однако даже «другой тег» несколько редок - всего три из них в репозитории Git для Git, а два других практически неслыханны.

+0

Удивительные объяснения. Спасибо. –