programing

Git에서 동일한 커밋의 파일에 현재 커밋 해시를 쓰는 방법은 무엇입니까?

bestprogram 2023. 8. 30. 21:54

Git에서 동일한 커밋의 파일에 현재 커밋 해시를 쓰는 방법은 무엇입니까?

저는 Git hooks로 여기서 멋진 일을 하려고 하지만, 어떻게 하는지 잘 모릅니다(또는 가능하다면요.

제가 해야 할 일은 모든 커밋에서 해시를 가져온 다음 이 해시를 사용하여 커밋의 파일을 업데이트하는 것입니다.

아이디어 있어요?

빌드/설치/배포 프로세스의 일부로 생성되는 추적되지 않은 파일에 SHA1을 배치하는 것과 유사한 작업을 수행하는 것이 좋습니다.그것은 분명히 쉽게 할 수 있습니다.git rev-parse HEAD > filename 아마도 니면아마도아도▁or.git describe [--tags] > filename 것과 .), 그고리그 것가은 파추는 끝로것 나는과 같은미 친하않 짓지습 을니다일른 과적다 것하▁),습 다않▁and니▁it▁crazy▁doing▁anything ▁avoids하▁like지),▁ending▁that짓을▁file.

그런 다음 버전 번호가 필요할 때 코드가 이 파일을 참조하거나 빌드 프로세스가 정보를 최종 제품에 통합할 수 있습니다.후자는 실제로 Git 자체가 버전 번호를 얻는 방법입니다. 빌드 프로세스는 버전 번호를 레포에서 가져온 다음 실행 파일에 빌드합니다.

현재 커밋 해시를 작성하는 것은 불가능합니다. 향후 커밋 해시를 미리 계산할 경우 파일을 수정하는 즉시 변경됩니다.

그러나 세 가지 옵션이 있습니다.

  1. 스크립트를 사용하여 'commit id'를 증분하고 포함합니다. 보기 흉합니다.
  2. .git 해시를 저장할 파일을 무시합니다.사용하기 편리하지 않음
  3. pre-commit이전 커밋 해시 저장 :) 99.99%의 경우 커밋을 수정/삽입하지 않으므로, 이것이 작동합니다.최악의 경우에도 원본 수정본을 식별할 수 있습니다.

저는 후크 스크립트를 작성하고 있으며, '완료되면' 여기에 게시할 예정이지만, 여전히 - 듀크 누켐 포에버가 출시되기 전입니다 :)

업데이트: 코드:.git/hooks/pre-commit:

#!/usr/bin/env bash
set -e

#=== 'prev-commit' solution by o_O Tync
#commit_hash=$(git rev-parse --verify HEAD)
commit=$(git log -1 --pretty="%H%n%ci") # hash \n date
commit_hash=$(echo "$commit" | head -1)
commit_date=$(echo "$commit" | head -2 | tail -1) # 2010-12-28 05:16:23 +0300

branch_name=$(git symbolic-ref -q HEAD) # http://stackoverflow.com/questions/1593051/#1593487
branch_name=${branch_name##refs/heads/}
branch_name=${branch_name:-HEAD} # 'HEAD' indicates detached HEAD situation

# Write it
echo -e "prev_commit='$commit_hash'\ndate='$commit_date'\nbranch='$branch'\n" > gitcommit.py

이제 우리에게 필요한 유일한 것은 변환하는 도구입니다.prev_commit,branch해시와 을 이룹니다. :)

이 접근 방식이 병합 커밋을 구분할 수 있을지 모르겠습니다.곧 확인할 것입니다.

은 이다음사달수있다습니성할여용하을는▁the▁using다있니▁by를 사용하여 달성할 수.filtergit 속성의 속성입니다.다음을 제공해야 합니다.smudge, " " " ID " 를 삽입하는 명령어입니다.clean커밋 ID 때문에 삽입된 파일이 변경되지 않도록 제거하는 명령입니다.

따라서 커밋 ID는 파일의 BLOB에 저장되지 않고 작업 복사본에서 확장됩니다.실제로 blob에 커밋 ID를 삽입하는 작업은 무한 반복 작업이 됩니다.☺) 이 트리를 복제하는 사용자는 자신을 위해 속성을 설정해야 합니다.

누군가 ID에 대한 "관리 속성" 섹션을 가리켰습니다. 여기에는 다음과 같은 내용이 있습니다.

동일한

속성 ID가 경로에 대해 설정된 경우 git는 BLOB 개체의 $Id$를 $Id:로 대체하고 체크아웃 시 40자의 16진수 BLOB 개체 이름 다음에 달러 기호 $로 대체합니다.워크트리 파일에서 $Id:로 시작하고 $로 끝나는 바이트 시퀀스는 체크인 시 $Id$로 바뀝니다.

생각해보면, 이것은 CVS, Subversion 등도 마찬가지입니다.리포지토리를 보면 리포지토리의 파일에 항상 $Id$가 포함되어 있는 것을 볼 수 있습니다.그것은 결코 그것의 확장을 포함하지 않습니다.텍스트가 확장되는 것은 체크아웃 시에만 가능합니다.

커밋 박스 밖에서 생각해 보세요!

이것을 파일 훅/포스트 훅에 넣어주세요.

#!/bin/sh
git describe --all --long > config/git-commit-version.txt

버전은 사용하는 모든 곳에서 사용할 수 있습니다.

커밋의 파일이 변경되면 커밋의 해시도 변경되기 때문에 실제로는 그렇게 하고 싶지 않다고 생각합니다.

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당신이 이 메시지를 검토할 때 두 가지가 즉시 문제로 떠오릅니다.하나는 tree sha1이고 두 번째는 commit time입니다.

이제 메시지를 변경하고 특정 시간에 커밋 또는 스케줄링을 수행하는 데 걸리는 시간을 추측하여 커밋 시간을 쉽게 처리할 수 있습니다.진정한 문제는 당신이 얻을 수 있는 나무 sha1입니다.git ls-tree $(git write-tree) | git mktree기본적으로 ls-tree의 메시지에 대해 sha1 체크섬을 수행합니다. 이 체크섬은 모든 파일과 해당 파일의 목록입니다.

따라서 커밋 sha1 체크섬은 트리 sha1 체크섬에 따라 달라지며, 이는 원을 완성하고 커밋 sha1에 따라 달라지는 파일 sha1 체크섬에 직접 의존합니다.그러므로 당신은 나 자신이 사용할 수 있는 기술에 대한 순환적인 문제를 가지고 있습니다.

덜 안전한 체크섬으로, 브루트 포스를 통해 파일 자체에 파일의 체크섬을 쓰는 것이 가능한 것으로 나타났지만, 저는 sha1로 그 작업을 수행한 어떤 작업도 알지 못합니다.이것이 불가능한 것은 아니지만, 우리의 현재 이해로는 거의 불가능합니다(그러나 몇 년 후에 그것이 사소한 일이 될 것이라는 것을 누가 알겠습니까).그러나 (블롭) 체크섬의 (트리) 체크섬의 (커밋) 체크섬을 파일에 기록해야 하기 때문에 강제력을 부여하기가 더욱 어렵습니다.

저는 단순히 정확한 날짜 시간과 상위 커밋의 해시를 쓰는 것을 선호하기 때문에hooks/pre-commit아래 코드를 작성합니다.

#!/bin/bash
ver_file=version.txt
> $ver_file
date +"%Y-%m-%d %T %:z" >> $ver_file
echo -n "Parent: " >> $ver_file
git rev-parse HEAD >> $ver_file
git add $ver_file
echo "Date-time and parent commit added to '$ver_file'"
exit 0

샘플 자동 생성version.txt파일:

2023-05-24 01:24:12 +03:30
Parent: 35acd10240a55d164b371aa28812e8e988ab0c8d

이 방법은 당신이 사용할 때에도 계속 작동합니다.checkout다른 약속으로, 예를 들어.version.txt파일은 다른 파일이 저장되는 방식과 정확히 동일하게 저장됩니다.remote저장소 및submodule동일한 이유로 s, 그러나 동일한 파일이 존재하는지 확인해야 합니다..git/hooks/pre-commit서브모듈 또는 원격 저장소에도 사용할 수 있습니다.

다운사이드

  1. GitHub 및 일부 다른 웹 사이트에서는 지원되지 않습니다.

  2. 항상 충돌이 있을 것입니다.version.txt수행 시merge그러나, 이외의 추가적인 조치는 없습니다.commit -am <message>병합을 수행하기 전에 사전 커밋도 실행되므로 필요합니다.commit.

언급URL : https://stackoverflow.com/questions/3442874/in-git-how-can-i-write-the-current-commit-hash-to-a-file-in-the-same-commit