Git의 가장 빠른 날짜는 몇 시입니까?

10147 단어 GitGitHub

tl;dr


실용적으로는 1970-01-01 00:00:00 +0000.
실제 저장소: https://github.com/okuoku/the-epoc-repo
추적: HOME에서 THIS를 시도하지 마십시오.이 GitHub의 프로필은 왠지 1969년 프로젝트를 할 수 있었다.(후술)

(돌아가신 오프닝)


올해 2019년은 유닉스 탄생 50주년으로 1969년 여름 PDP-7에서 유닉스(원형)가 성립된 때부터 계산됐다.51년 동안 UNIX 날짜 push의 가장 오래된 Git 약속을 사용한다면...

아닌가요 (끝)

가장 오래된 약속의 제작 방법

git commit 옵션을 통해 authordate를 직접 지정할 수 있습니다.
git commit --date="1970-01-01 00:00:00 +0000" -m temp
이 방법을 사용한다면committerdate는 --date 순간의committerdate를 사용하기 때문에committerdate를 표시하는 곳에서도, 이전의 날짜를 표시하려면 git commit 환경 변수를 설정한 토대에서committerdate를 실행합니다.

플러그인 명령 직접 사용


(see comments. 처음 나왔을 때 여기를 먼저 썼어요.)
git의 상세한 조작은 모두 명령으로 나뉘어 명령줄에서 상당히 낮은 수준의 조작을 할 수 있다.중요한 것은 GIT_COMMITTER_DATE 명령과 write-tree 명령이다. 특히 commit-tree 명령에 대해 원시 날짜를 직접 부여하는 것은 미소다.
단계는 다음과 같습니다.
  • commit-tree 저장소 준비
  • git init 파일git add에 적절히 추가
  • index에서 git write-treetree 객체로 변환
  • indextree 대상을 가리키는commit 대상(날짜는 환경 변수git commit-tree 등에서 제시)
  • GIT_AUTHOR_DATE 어떤 방식으로든 HEAD 업데이트
  • 이렇게구체적으로 말하면
    git init
    git add README.txt
    git write-tree > tree.txt
    GIT_AUTHOR_DATE="1970-01-01 00:00:00 +0000" GIT_COMMITTER_DATE="1970-01-01 00:00:00 +0000" git commit-tree -F msg1.txt `cat tree.txt`
    
    느낌
    여기에 제시된 git reset 날짜는 가장 오래된 날짜로 Git로 일반적으로 표시할 수 있다.이것은 유닉스 Epoch라고 불리는 시간으로 Git를 포함한 유닉스의 프로그램이 대부분 사용하는 시간계의 시작에 해당한다.
    커밋이 표시되면 시간1970-01-01 00:00:00 +0000 또는 Thu Jan 1 00:00:00 1970 +0000로 표시됩니다.후자는 실제 Git 객체에서 사용되며 UNIX는 0입니다.
    인간에 대한 우호적인 표시
    $ git show 
    commit e111c81454967d83488272a47c9422c446d6fa65
    Author: okuoku <[email protected]>
    Date:   Thu Jan 1 00:00:00 1970 +0000
    
    사람에 대한 엄격한 표시
    $ git cat-file commit HEAD
    tree 0f148df97147b603999860a1fed76de1f5ee3b02
    author okuoku <[email protected]> 0 +0000
    committer okuoku <[email protected]> 0 +0000
    
    This is +0000 timezone offset commit
    
    참고로 0 +0000 매뉴얼 https://git-scm.com/docs/git-commit-tree 과 같이 git commit-tree 등 몇 가지 날짜 형식을 받아들일 수도 있고 유닉스 시간을 직접 쓸 수도 있다.단, 위에 나타난 GIT_AUTHOR_DATE 은 직접 지정할 수 없습니다.UNIX 시간 표시는 8자리 이상으로 인식할 수 없습니다.이것은 일반적인 YYYMMDD 형식과 혼동되기 쉽다.

  • https://stackoverflow.com/questions/5093533/git-ignores-git-author-date-is-this-a-bug/5093714#5093714
  • SO의 응답

  • https://github.com/git/git/blob/6e0cc6776106079ed4efa0cc9abace4107657abf/date.c#L637
  • 실제 코드
  • 
        /*
         * Seconds since 1970? We trigger on that for any numbers with
         * more than 8 digits. This is because we don't want to rule out
         * numbers like 20070606 as a YYYYMMDD date.
         */
        if (num >= 100000000 && nodate(tm)) {
            time_t time = num;
            if (gmtime_r(&time, tm)) {
                *tm_gmt = 1;
                return end - date;
            }
        }
    

    게다가 더 오래된 시간은 어떻게 될까


    당연한 의문은 더 오래된 시간까지 더하면 어떨까.실제로 JST의 1970/1/1 심야에 0 +0000 명령으로 받아들여지고 실제 제작으로 제출할 수도 있다.
    제출 시 표시
    $ git cat-file commit 321603c4a49a98b4bb0502640844d56ca145da71
    tree c6babee1ec49d936cf7df8f20b309d5d8627ce20
    author okuoku <[email protected]> 18446744073709519216 +0900
    committer okuoku <[email protected]> 1561830314 +0900
    
    여기에는 1970-01-01 00:00:00 +0900에 해당하는 수치가 표시되어 있으며, 16진법을 18446744073709519216 로 표시하면 이른바 인덱스 오버플로우를 일으킬 수 있다.UNIX는 일반적으로 32bits2038년 문제에서 기호를 사용하여 사용됩니다.
    언뜻 보기에는 제출이 정상적인 것 같지만 이런 제출은 통과되지 않는다0xffffffffffff8170. GitHub에push를 할 수 없다.
    Counting objects: 4, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (4/4), 979 bytes | 979.00 KiB/s, done.
    Total 4 (delta 0), reused 0 (delta 0)
    remote: error: object 32b0128451f66ca872431bc6c23fb2854b20e85d: badDateOverflow: invalid author/committer line - date causes integer overflow
    remote: fatal: fsck error in packed object
    error: remote unpack failed: index-pack abnormal exit
    To github.com:okuoku/the-oldest-repo.git
     ! [remote rejected] master -> master (failed)
    error: failed to push some refs to '[email protected]:okuoku/the-oldest-repo.git'
    
    이 검사는 git fsck 함수를 통해 진행되었으며, 64bit 코드가 없는 상황에서 date_overflows 과 시스템TIME_MAX 을 수렴해야 한다.UNIX Epoch에서 볼 수 있는 마이너스 값, 즉 1970/1/1 심야 UTC 이전의 날짜가 후자의 조건을 충족시키지 못했기 때문에 (시스템의 time_t로 해석하면 이 기호) Git에서는 부당하다.
  • https://github.com/git/git/blob/8dca754b1e874719a732bc9ab7b0e14b21b1bc10/date.c#L1320
  • int date_overflows(timestamp_t t)
    {
        time_t sys;
    
        /* If we overflowed our timestamp data type, that's bad... */
        if ((uintmax_t)t >= TIME_MAX)
            return 1;
    
        /*
         * ...but we also are going to feed the result to system
         * functions that expect time_t, which is often "signed long".
         * Make sure that we fit into time_t, as well.
         */
        sys = t;
        return t != sys || (t < 1) != (sys < 1);
    }
    

    실제 저장소


    이번에 GitHub에 저장소https://github.com/okuoku/the-epoc-repo를 준비했는데 이것은 당연히 fake입니다. 실제 50년 코드로는 유닉스 히스토리 레포https://github.com/dspinellis/unix-history-repo가 있습니다.
    올해 유닉스-history-repohttps://t.co/19ZJ79xpAw가 50years ago에 돌입했나...Git 날짜는 UNIX 시간이기 때문에 UNIX 이전 기록을 기록할 수 없습니다.UNIX의 역사는 1970년 6월 30일, UNIX 시간 1558800 (-0500)입니다.pic.twitter.com/q1eQqboYQY — okuoku (@okuoku) April 3, 2019
    Git에서 1970년 이전의 인류는 소프트웨어를 쓰지 않았다는 것이다.이에 비해 Windows의 시스템 시간은 1601년 1/1부터 시작됩니다.부터 UNIX보다 Windows가 더 오래되었습니다!(실제로 Windows의 Epoch는 Windows 개발 시작 부근이 아니라 단지 개발이 시작되었을 때의 그리고리가 겪은 400년 주기가 시작된 한 해

    추기: 1969년의 수수께끼


    ... ↑ 1970년이 가장 오래된 날짜라고 적혀 있는데, 왠지 모르게 GitHub의 프로필에 이 날짜는 1969년으로 보인다.
  • https://github.com/okuoku?tab=overview&from=1969-12-01&to=1969-12-31

  • Svn 미러링과 다른 방법을 사용하면 더 빠른 날짜에 도전할 수 있습니다.
    (add: 아마 이 편차도 시간대 때문인 것 같아요. 현지 시간만 바꿔도 1970년은 안 될 것 같아요. GitHub의 설치 장소에 따라?)

    좋은 웹페이지 즐겨찾기