이 특정 시나리오와 비슷한 것을 찾지 못했습니다.
500 개 이상의 지점, 500 개 이상의 태그, 2007 년 중반으로 거슬러 올라가는 역사가 많은 자식 저장소가 있습니다. ~ 19,500 개의 커밋이 포함되어 있습니다. 2010 년 1 월 1 일 이전에 모든 기록을 제거하여 더 작고 다루기 쉽도록 만들었습니다 (기록의 전체 사본을 보관 저장소에 보관함).
나는 새로운 저장소의 뿌리가되고 싶다는 결심을 알고 있습니다. 그러나 해당 커밋으로 시작하기 위해 저장소를 자르는 올바른 git mojo를 알아낼 수는 없습니다. 나는 몇 가지 변형을 추측하고있다.
git filter-branch
이식편과 관련된 것이 필요하다; 또한 우리가 별도로 유지하려는 200여 가지의 각각의 치료 후 (내가 뭔가 다시 함께 REPO을 패치 할 필요가 있습니다 않습니다 어떻게 해야할지).
누구든지 이런 일을 한 적이 있습니까? 중요한 경우 자식 1.7.2.3이 있습니다.
답변
새로운 루트 커밋의 부모에 대한 이식편 을 부모가없는 곳 (또는 저장소의 실제 루트 커밋과 같은 빈 커밋)으로 만드 십시오. 예 :echo "<NEW-ROOT-SHA1>" > .git/info/grafts
이식편을 만든 후에는 즉시 적용됩니다. git log
원하지 않는 오래된 커밋이 사라진 것을 보고 볼 수 있어야합니다 .
$ echo 4a46bc886318679d8b15e05aea40b83ff6c3bd47 > .git/info/grafts
$ git log --decorate | tail --lines=11
commit cb3da2d4d8c3378919844b29e815bfd5fdc0210c
Author: Your Name <your.email@example.com>
Date: Fri May 24 14:04:10 2013 +0200
Another message
commit 4a46bc886318679d8b15e05aea40b83ff6c3bd47 (grafted)
Author: Your Name <your.email@example.com>
Date: Thu May 23 22:27:48 2013 +0200
Some message
모든 것이 의도 한 것처럼 보이면 간단하게 간단 git filter-branch -- --all
하게 만들 수 있습니다.
주의 : filter-branch 단계를 수행 한 후에는 모든 커밋 ID가 변경되므로 이전 저장소를 사용하는 사람은 새 저장소를 사용하는 사람과 병합해서는 안됩니다.
답변
답글을 게시하기에는 너무 늦었을 수 있지만이 페이지가 Google의 첫 번째 결과이므로 여전히 도움이 될 수 있습니다.
git repo에서 공간을 확보하고 싶지만 모든 커밋 (rebase 또는 graft)을 다시 작성하지 않고 전체 저장소가있는 사람들의 푸시 / 풀 / 병합을 계속하려면 git을 사용할 수 있습니다 복제 얕은 복제본 ( –depth 매개 변수).
; Clone the original repo into limitedRepo
git clone file:///path_to/originalRepo limitedRepo --depth=10
; Remove the original repo, to free up some space
rm -rf originalRepo
cd limitedRepo
git remote rm origin
다음 단계에 따라 기존 리포지토리를 좁힐 수 있습니다.
; Shallow to last 5 commits
git rev-parse HEAD~5 > .git/shallow
; Manually remove all other branches, tags and remotes that refers to old commits
; Prune unreachable objects
git fsck --unreachable ; Will show you the list of what will be deleted
git gc --prune=now ; Will actually delete your data
추신 : 이전 버전의 git은 clone / push / pull을 얕은 저장소에서 지원하지 않았습니다.
답변
이 방법 은 이해하기 쉽고 잘 작동합니다. 스크립트 ( $1
)에 대한 인수 는 히스토리를 유지하려는 커밋에 대한 참조 (태그, 해시 등)입니다.
#!/bin/bash
git checkout --orphan temp $1 # create a new branch without parent history
git commit -m "Truncated history" # create a first commit on this branch
git rebase --onto temp $1 master # now rebase the part of master branch that we want to keep onto this branch
git branch -D temp # delete the temp branch
# The following 2 commands are optional - they keep your git repo in good shape.
git prune --progress # delete all the objects w/o references
git gc --aggressive # aggressively collect garbage; may take a lot of time on large repos
참고 된 태그가 여전히 유지됩니다; 수동으로 제거해야 할 수도 있습니다.
비고 : 나는이 거의 @yoyodin 같은 aswer 알고 있지만, 여기에 몇 가지 중요한 추가 명령과 정보가 있습니다. 답변을 편집하려고했지만 @yoyodin의 답변이 크게 변경되었으므로 편집이 거부되었으므로 여기에 정보가 있습니다!
답변
이 방법을 시도하십시오 git history 자르는 방법 :
#!/bin/bash
git checkout --orphan temp $1
git commit -m "Truncated history"
git rebase --onto temp $1 master
git branch -D temp
다음은 $1
SHA-1의 인 당신은 유지하고 스크립트가 사이의 모든 커밋이 포함되어 새로운 지점이 생성됩니다 원하는 커밋 $1
하고 master
모든 이전의 역사를 삭제합니다. 이 간단한 스크립트는라는 기존 분기가 없다고 가정합니다 temp
. 또한이 스크립트는 이전 히스토리에 대한 자식 데이터를 지우지 않습니다. git gc --prune=all && git repack -a -f -F -d
당신이 진정으로 모든 역사를 잃고 싶다는 것을 확인한 후에 실행하십시오 . rebase --preserve-merges
해당 기능의 git 구현이 완벽하지 않다는 경고가 필요할 수도 있습니다 . 사용하는 경우 결과를 수동으로 검사하십시오.
답변
기록을 다시 쓰는 대신, 이 기사에서와 같은 Pro Git 책 의 사용 git replace
을 고려 하십시오 . 논의 된 예제는 부모 커밋을 대체하여 트리의 시작을 시뮬레이션하는 동시에 전체 히스토리를 보호를 위해 별도의 브랜치로 유지합니다.
답변
업스트림 저장소를 전체 히스토리 로 유지 하지만 로컬 소규모 체크 아웃 을 유지 하려면을 사용 하여 얕은 복제를 수행하십시오 .git clone --depth=1 [repo]
커밋을 푸시하면 할 수 있습니다
git fetch --depth=1
오래된 커밋을 정리합니다. 이로 인해 이전 커밋과 해당 개체에 도달 할 수 없습니다.git reflog expire --expire-unreachable=now --all
. 이전 커밋 및 해당 객체를 모두 만료하려면git gc --aggressive --prune=all
오래된 물건을 제거하기 위해
커밋 후 로컬 자식 기록을 제거하는 방법을 참조하십시오 . .
이 “shallow”저장소를 “shallow update not allowed”라는 다른 위치로 푸시 할 수 없습니다. Git 원격 URL을 변경 한 후 원격 거부 (얕은 업데이트는 허용되지 않음)를 참조하십시오 . 당신이 그것을 원한다면, 접목을 고수해야합니다.
답변
내가하고있는 일을 이해하기 위해 몇 가지 답변과 다른 정보를 읽어야했습니다.
1. 특정 커밋보다 오래된 모든 것을 무시하십시오.
파일 .git/info/grafts
은 커밋에 대한 가짜 부모를 정의 할 수 있습니다. 커밋 ID 만있는 줄은 커밋에 부모가 없다고 말합니다. 지난 2000 개의 커밋에만 관심이 있다고 말하고 싶다면 다음과 같이 입력하면됩니다.
git rev-parse HEAD~2000 > .git/info/grafts
git rev-parse는 현재 커밋의 2000 번째 부모의 커밋 ID를 제공합니다. 위의 명령은 이식편 파일이 있으면 덮어 씁니다. 먼저 있는지 확인하십시오.
2. 힘내 역사를 다시 쓰십시오 (선택 사항)
이식 된 가짜 부모를 실제 부모로 만들려면 다음을 실행하십시오.
git filter-branch -- --all
모든 커밋 ID가 변경됩니다. 이 저장소의 모든 사본은 강제로 업데이트해야합니다.
3. 디스크 공간 정리
사본이 업스트림과 호환되도록하려면 2 단계를 수행하지 않았습니다. 디스크 공간을 절약하고 싶었습니다. 이전 커밋을 모두 잊어 버리려면 :
git prune
git gc
대안 : 얕은 사본
다른 저장소의 얕은 사본이 있고 디스크 공간을 절약하려는 경우 업데이트 할 수 있습니다 .git/shallow
. 그러나 이전부터 커밋을 가리키는 것이 아무것도 없도록주의하십시오. 따라서 다음과 같이 실행할 수 있습니다.
git fetch --prune
git rev-parse HEAD~2000 > .git/shallow
git prune
git gc
얕은 항목은 이식편처럼 작동합니다. 그러나 이식편과 얕음을 동시에 사용하지 않도록주의하십시오. 적어도 동일한 항목이 없으면 실패합니다.
오래된 커밋을 가리키는 오래된 참조 (태그, 분기, 원격 헤드)가 여전히 있으면 정리되지 않으며 더 많은 디스크 공간을 절약하지 않습니다.