programing

과거의 Git 커밋을 어떻게 만들 수 있습니까?

oldcodes 2023. 5. 9. 23:00
반응형

과거의 Git 커밋을 어떻게 만들 수 있습니까?

개인적으로 사용하기 위해 모든 것을 Git로 변환하는 중인데 저장소에 이미 있는 오래된 버전의 파일을 찾았습니다.파일의 "수정된 날짜"에 따라 올바른 순서로 기록에 커밋하여 파일의 정확한 기록을 얻으려면 어떻게 해야 합니까?

저는 다음과 같은 것이 효과가 있을 것이라고 들었습니다.

git filter-branch --env-filter="GIT_AUTHOR_DATE=... --index-filter "git commit path/to/file --date " --tag-name-filter cat -- --all  

이것이 저에게 도움이 되었습니다.

git commit --date="10 day ago" -m "Your commit message" 

당신이 받은 충고는 결점이 있습니다.를 에서에 --env-filter모든 약속의 날짜를 다시 쓸 것입니다.또한 내부에서 git commit을 사용하는 것은 드문 일입니다.--index-filter.

당신은 여기서 여러 가지 독립적인 문제를 다루고 있습니다.

"지금"이 아닌 날짜

각 커밋에는 작성자 날짜와 커밋 날짜의 두 가지 날짜가 있습니다.새 커밋을 쓰는 모든 명령에 대해 환경 변수 GIT_AUTHOR_DATE 및 GIT_COMMITTER_DATE를 통해 값을 제공하여 각 명령을 재정의할 수 있습니다.git-commit(1)의 "날짜 형식" 또는 다음을 참조하십시오.

Git internal format = <unix timestamp> <time zone offset>, e.g.  1112926393 +0200
RFC 2822            = e.g. Thu, 07 Apr 2005 22:13:13 +0200
ISO 8601            = e.g. 2005-04-07T22:13:13

일반적인 사용 중에 새 커밋을 쓰는 유일한 명령은 git commit입니다.또한 다음과 같은 기능이 있습니다.--date작성자 날짜를 직접 지정할 수 있는 옵션입니다.에는 상예사량다같습다니과음은이 포함됩니다.git filter-branch --env-filter또한 위에서 언급한 환경 변수를 사용합니다(이 변수는 옵션 이름이 붙은 "env"의 일부입니다. git-filter-branch(1)의 "옵션" 및 기본 "plumbing" 명령 git-commit-tree(1)를 참조하십시오).

단일 참조 기록에 파일 삽입

저장소가 매우 단순한 경우(즉, 분기가 하나만 있고 태그가 없는 경우) Gitrebase를 사용하여 작업을 수행할 수 있습니다.

다음 명령에서는 "A" 대신 커밋의 개체 이름(SHA-1 해시)을 사용합니다.git commit을 실행할 때 "날짜 재정의" 방법 중 하나를 사용하는 것을 잊지 마십시오.

---A---B---C---o---o---o   master

git checkout master
git checkout A~0
git add path/to/file
git commit --date='whenever'
git tag ,new-commit -m'delete me later'
git checkout -
git rebase --onto ,new-commit A
git tag -d ,new-commit

---A---N                      (was ",new-commit", but we delete the tag)
        \
         B'---C'---o---o---o   master

새하려면 추된위새커만를을을드대는밋신다새포파록도함하을니일다사합면려업용하데음가을트이치에을▁if다▁(▁then를▁a니▁to▁use추사다합가▁include를 사용합니다.git commit --amendgit commit결과는 다음과 같습니다.

---A'---B'---C'---o---o---o   master

위의 내용은 새 커밋의 부모가 되어야 하는 커밋의 이름을 지정할 수 있는 한 작동합니다.실제로 새 루트 커밋(부모 없음)을 통해 새 파일을 추가하려면 다음과 같은 방법이 필요합니다.

B---C---o---o---o   master

git checkout master
git checkout --orphan new-root
git rm -rf .
git add path/to/file
GIT_AUTHOR_DATE='whenever' git commit
git checkout -
git rebase --root --onto new-root
git branch -d new-root

N                       (was new-root, but we deleted it)
 \
  B'---C'---o---o---o   master

git checkout --orphan비교적 새로운 버전(Git 1.7.2)이지만 이전 버전의 Git에서도 동일한 작업을 수행할 수 있는 다른 방법이 있습니다.

다중 참조 기록에 파일 삽입

리포지토리가 더 복잡할 경우(예: 둘 이상의 참조(브런치, 태그 등), git filter-branch를 사용해야 합니다.git filter-branch를 사용하기 전에 전체 저장소의 백업 복사본을 만들어야 합니다.전체 작업 트리에 대한 간단한 tar 아카이브(.git 디렉터리 포함)만으로도 충분합니다.git filter-filter-filter-filtering은 백업 참조를 생성하지만, 삭제하기만 하면 권한이 없는 필터링에서 복구하는 것이 종종 더 쉽습니다..git백업에서 복원할 수 있습니다.

의 명령어인 " " " " " " 를 합니다.git update-index --addgit addgit add를 사용할 수 있지만, 먼저 외부 위치에서 예상 경로로 파일을 복사해야 합니다.--index-filter이 명령은 비어 있는 임시 GIT_WORK_TREE에서 실행됩니다.

새 파일을 기존의 모든 커밋에 추가하려면 다음 작업을 수행할 수 있습니다.

new_file=$(git hash-object -w path/to/file)
git filter-branch \
  --index-filter \
    'git update-index --add --cacheinfo 100644 '"$new_file"' path/to/file' \
  --tag-name-filter cat \
  -- --all
git reset --hard

기존 커밋의 날짜를 변경할 이유가 없다고 봅니다.--env-filter 'GIT_AUTHOR_DATE=…'만약 당신이 그것을 사용했다면, 당신은 그것이 모든 커밋에 대한 날짜를 다시 쓰도록 조건부로 만들었을 것입니다.

일부 기존 커밋("A") 후 커밋에만 새 파일을 표시하려면 다음 작업을 수행할 수 있습니다.

file_path=path/to/file
before_commit=$(git rev-parse --verify A)
file_blob=$(git hash-object -w "$file_path")
git filter-branch \
  --index-filter '

    if x=$(git rev-list -1 "$GIT_COMMIT" --not '"$before_commit"') &&
       test -n "$x"; then
         git update-index --add --cacheinfo 100644 '"$file_blob $file_path"'
    fi

  ' \
  --tag-name-filter cat \
  -- --all
git reset --hard

기록 중간에 삽입할 새 커밋을 통해 파일을 추가하려면 git filter-branch를 사용하기 전에 새 커밋을 생성하고 추가해야 합니다.--parent-filtergit filter-filter-filter:

file_path=path/to/file
before_commit=$(git rev-parse --verify A)

git checkout master
git checkout "$before_commit"
git add "$file_path"
git commit --date='whenever'
new_commit=$(git rev-parse --verify HEAD)
file_blob=$(git rev-parse --verify HEAD:"$file_path")
git checkout -

git filter-branch \
  --parent-filter "sed -e s/$before_commit/$new_commit/g" \
  --index-filter '

    if x=$(git rev-list -1 "$GIT_COMMIT" --not '"$new_commit"') &&
       test -n "$x"; then
         git update-index --add --cacheinfo 100644 '"$file_blob $file_path"'
    fi

  ' \
  --tag-name-filter cat \
  -- --all
git reset --hard

또한 새 루트 커밋에 파일을 처음 추가하도록 구성할 수 있습니다. gitrebase 섹션에서 "orphan" 메서드를 통해 새 루트 커밋을 만듭니다(캡처:new_commit), ), 를 --index-filter a 리고a.--parent-filter맘에 들다"sed -e \"s/^$/-p $new_commit/\"".

평소와 할 수 때 변수를 합니다.GIT_AUTHOR_DATE그리고.GIT_COMMITTER_DATE적절한 날짜까지.

물론 이렇게 하면 지점의 끝 부분(즉, 현재 헤드 커밋 앞)에서 커밋을 수행할 수 있습니다.만약 당신이 레포에서 그것을 더 뒤로 미루고 싶다면, 당신은 약간 화려해져야 합니다.다음과 같은 이력이 있다고 가정해 보겠습니다.

o--o--o--o--o

그리고 새 커밋("X"로 표시됨)을 두 번째로 표시합니다.

o--X--o--o--o--o

가장 쉬운 방법은 첫 번째 커밋에서 분기하여 새 커밋을 추가한 다음 모든 다른 커밋을 새 커밋 위에 다시 배치하는 것입니다.이와 같은 경우:

$ git checkout -b new_commit $desired_parent_of_new_commit
$ git add new_file
$ GIT_AUTHOR_DATE='your date' GIT_COMMITTER_DATE='your date' git commit -m 'new (old) files'
$ git checkout master
$ git rebase new_commit
$ git branch -d new_commit

이것은 오래된 질문이지만 최근에 우연히 발견했습니다.

git commit --date='year-month-day hour:minutes:seconds' -m "message"

것입니다: 서다음같이보것일입다니과따라것.git commit --date='2021-01-01 12:12:00' -m "message"하여 제로작고습니다검에서 했습니다.GitHub그리고.GitLab.

에 했던 둘 다 해야 합니다.GIT_AUTHOR_DATE그리고.GIT_COMMITTER_DATE:

GIT_AUTHOR_DATE=$(date -d'...') GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" git commit -m '...'

date -d'...'다음과 같은 정확한 날짜일 수 있습니다.2019-01-01 12:00:00 는친척 같은또▁like와 같은 친척.5 months ago 24 days ago.

git 로그의 두 날짜를 보려면 다음을 사용합니다.

git log --pretty=fuller

이는 병합 커밋에도 적용됩니다.

GIT_AUTHOR_DATE=$(date -d'...') GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" git merge <branchname> --no-ff

저의 경우 시간이 지남에 따라 여러 버전의 파일을 myfile_bak, myfile_old, myfile_2010, backups/myfile 등으로 저장했습니다.나는 그들의 수정 날짜를 사용하여 내 파일의 이력을 입력하고 싶었습니다.가장 오래된 파일의 이름을 내 파일로 바꾸고,git add myfile,그리고나서git commit --date=(modification date from ls -l) myfile다음으로 오래된 이름을 내 파일로 바꾸고 --date로 다른 git commit을 지정합니다. 반복합니다...

이를 어느 정도 자동화하기 위해 셸-foo를 사용하여 파일의 수정 시간을 가져올 수 있습니다.는 처에는으로 했습니다.ls -l그리고.cut stat더 직접적입니다. stat(1)보다 더 직접적입니다.

git commit --date='stat -c %y myfile' 내 파일

다음은 변경 사항을 적용하는 데 사용하는 항목입니다.fooN=1과거 일 수:

git add foo
git commit -m "Update foo"
git commit --amend --date="$(date -v-1d)"

더 날짜를 약속하고 , 를 들어 3일 전이라고 .date 인수:date -v-3d.

예를 들어, 어제 어떤 일을 저지르는 것을 잊어버렸을 때, 그것은 정말 유용합니다.

업데이트:--date 은 다과같표사수있습용다니할도현은음과 같은 할 수 있습니다.--date "3 days ago"아니 심지어는--date "yesterday"따라서 명령어를 한 줄로 줄일 수 있습니다.

git add foo ; git commit --date "yesterday" -m "Update"

저의 경우 --date 옵션을 사용하는 동안 Git 프로세스가 중단되었습니다.제가 끔찍한 짓을 했나 봐요그 결과 일부 index.lock 파일이 나타났습니다.그래서 저는 .git 폴더에서 .lock 파일을 수동으로 삭제하고 모든 수정된 파일이 지난 날짜에 커밋되도록 실행했고 이번에는 작동했습니다.여기 있는 모든 답변에 감사드립니다.

git commit --date="`date --date='2 day ago'`" -am "update"
  1. git --date경변사만만 합니다.GIT_AUTHOR_DATE 많은 앱은 하만많은깃앱쇼, 들깃브허어예지를,를 보여줍니다.GIT_COMMITTER_DATE변경해야 합니다.GIT_COMMITTER_DATE도 마찬가지야
  2. git는 기본 UNIX 날짜 출력에서 시간대를 인식하지 않습니다.datetime 형식은 ISO8601과 같은 호환되는 형식으로 포맷해야 합니다.

한 예 (OS X ▁os(▁both▁x예)▁in▁complete변▁os▁example경)GIT_COMMITTER_DATE그리고.GIT_AUTHOR_DATE4시간 전까지):

x=$(date -v -4H +%Y-%m-%dT%H:%M:%S%z); export GIT_COMMITTER_DATE=$x; git commit --amend --date $x

또는 가짜 깃 이력을 사용하여 특정 데이터 범위에 대해 생성할 수도 있습니다.

당신이 찾고 있는 간단한 답은 다음과 같습니다.

GIT_AUTHOR_DATE="2020-10-24T18:00:00 +0200" GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE git commit

표준 시간대 문자열에 주의하고 표준 시간대에 적합한 문자열(예: +0200, -0400)을 설정합니다.

사전 단계.

  • 원격에서 로컬 리포지토리로 모든 데이터를 가져옵니다.

  • 우리는 --syslog 및 --date 스위치를 사용하고 있습니다.

정확한 명령은 다음과 같습니다.

$ git commit --amend --date="YYYY-MM-DD HH:MM:SS"

언제든지 컴퓨터에서 날짜를 변경하고 약속을 한 다음 날짜를 다시 변경하고 밀어 넣을 수 있습니다.

git commit --date='year-month-day hour:minutes:seconds' -m "message"

git push 

따라서 과거 날짜에 Git에서 무언가를 커밋하려면 이 명령을 사용하면 됩니다.

git commit --amend --no-edit --date="Sat Jun 5 20:00:00 2021 -0600"
  1. 하려면 " " " " " " " 를 실행하면 .git add .
  2. 다음을 사용하여 변경 내용 커밋git commit -m "Your commit message".
  3. 실행합니다.git commit --amend --no-edit --date="Sat Jun 5 20:00:00 2021 -0600"커밋 후 명령을 실행하여 타임스탬프가 기록된 마지막 커밋을 수정합니다. 둡니다. --no-edit은 를 그대로 유지합니다.
  4. gitpush를 실행하여 GitHub 또는 사용하는 플랫폼에 변경사항을 푸시합니다.

원하는 날짜와 시간을 변경해야 합니다.이렇게 하면 과거의 특정 날짜에 대한 커밋이 생성되며 GitHub Streak이 손실되지 않습니다.

언급URL : https://stackoverflow.com/questions/3895453/how-do-i-make-a-git-commit-in-the-past

반응형