자식 분기를 어떻게 보관할 수 있습니까?


305

내 자식 저장소에 더 이상 활발히 개발되지 않은 오래된 지점이 있습니다. 실행시 기본적으로 표시되지 않도록 분기를 보관하고 싶습니다 git branch -l -r. 기록을 유지하고 싶기 때문에 삭제하고 싶지 않습니다. 어떻게해야합니까?

심판 / 헤드 이외의 심판을 만들 수 있다는 것을 알고 있습니다. 예를 들면 다음과 같습니다 refs/archive/old_branch. 그렇게하면 어떤 결과가 있습니까?


자식-RM은 단지 인덱스에서 제거, 저장소에서하지 삭제 자원을 수행 kernel.org/pub/software/scm/git/docs/git-rm.html 쉽게 사용하여 이러한 자원을 복원 할 수 있습니다git checkout [rev] file
온건 다나

1
내가 아는 한에서는 아니다. 그래도 Attic/<branchname>가벼운 태그를 사용 하여 브랜치를 보관합니다.
Jakub Narębski

태그는 빠르고 안전하며 제정신입니다.
kch

답변:


401

이 작업을 수행하는 올바른 방법은 지점에 태그를 지정하는 것입니다. 태그를 지정한 후 분기를 삭제하면 분기를 효과적으로 유지하지만 분기 목록을 어지럽히 지 않습니다.

지점으로 돌아가려면 태그를 확인하십시오. 태그에서 분기를 효과적으로 복원합니다.

브랜치를 아카이브하고 삭제하려면 다음을 수행하십시오.

git tag archive/<branchname> <branchname>
git branch -d <branchname>

얼마 후 지점을 복원하려면 다음을 수행하십시오.

git checkout -b <branchname> archive/<branchname>

지점의 기록은 태그를 지정할 때와 동일하게 유지됩니다.


11
나는 힘내 초보자이지만, 이것을 시도 할 때, 지점을 복원하기위한 적절한 명령은 다음과 같다고 생각한다.git checkout -b <branchname> archive/<branchname>
Steve

6
이 경우 객체 태그를 사용하지 않는 이유가 있습니까? 지사를 보관 한 사람과 언제 재미 있는지 확인할 수 있습니다.
Grégory Joseph

7
@ GrégoryJoseph : 소위 "주석이 붙은 태그"입니다. 그리고 그렇습니다, 그것을 사용하는 것은 많은 의미가 있습니다.
onnodb

22
branch -D이런 식으로 보관하는 경우 완전히 병합되지 않을 가능성 이 있기 때문에 아마 원할 것입니다.
Arkadiy Kukarkin

5
아주 좋아요 다음 은 설명이 포함 된 전체 자습서입니다.
guyaloni 2019

123

Jeremy의 대답은 원칙적으로 맞지만 IMHO가 지정한 명령은 옳지 않습니다.

분기를 체크 아웃하지 않고 분기를 태그에 보관하는 방법은 다음과 같습니다 (따라서 해당 분기를 삭제하기 전에 다른 분기를 체크 아웃하지 않아도 됨).

> git tag archive/<branchname> <branchname>
> git branch -D <branchname>

분기를 복원하는 방법은 다음과 같습니다.

> git checkout -b <branchname> archive/<branchname>

18
아직 충분한 점수가 없었지만 기존 답변을 편집하려고 할 때 더 좋을 것입니다-+1 어쨌든 :)
jkp

5
다른 사용자의 코드와 명령을 편집하는 @jkp는 git 명령의 미묘한 변경이 크게 다른 작업을 수행 할 수 있고 원래 작성자가 자신의 방식대로 무언가를 쓴 이유를 이해할 수 없기 때문에 일반적으로 눈살을 찌푸립니다. 자신의 답변을하거나 의견을 남기는 것이 좋습니다.
Dan Bechard 2018 년

또는 극도로 다른 것들보다 더 나쁜 명령이나 코드의 미묘한 변화는 미묘하게 다른 결과를 초래할 수 있습니다. 실제로는 이해하기 어려울 수 있습니다. 대답으로 포스터를 편집하거나 응답 할 수 있도록 의견으로 남겨 두는 것이 좋습니다 잠재적으로 다른 결과를 참조하는 이의 제기 신청 (이러한 이의 제기 신청이 다소 일반적 임)
Nicholas Pipitone (

22

git update-ref.를 사용하여 비표준 접두사로 참조를 만들 수 있습니다 . 예 :

  • 지점을 보관하십시오. git update-ref refs/archive/old-topic topic && git branch -D topic
  • 분기를 복원하십시오 (필요한 경우). git branch topic refs/archive/old-topic

비표준 접두사 (여기서는 refs/archive)가있는 참조는 평소 git branch에 표시 git log되지 않습니다 git tag. 여전히을 (를) 함께 나열 할 수 있습니다 git for-each-ref.

다음 별칭을 사용하고 있습니다.

[alias]
    add-archive = "!git update-ref refs/archive/$(date '+%Y%m%d-%s')"
    list-archive = for-each-ref --sort=-authordate --format='%(refname) %(objectname:short) %(contents:subject)' refs/archive/
    rem = !git add-archive
    lsrem = !git list-archive

또한 보관 된 분기를 자동으로 (또는 원샷으로) 푸시하는 것과 같이 리모컨구성 할 수도 있습니다 .push = +refs/archive/*:refs/archive/*git push origin refs/archive/*:refs/archive/*

다른 방법은 분기를 삭제하기 전에 어딘가에 SHA1을 기록하는 것이지만 한계가 있습니다. 어떤 심판이없는 커밋이 될 것입니다 3개월 (또는 reflog없이 몇 주) 후 GC'd 혼자 매뉴얼을 보자 git gc --prune. 심판이 지적한 커밋은 GC로부터 안전합니다.

편집 : @ap에 의해 동일한 아이디어의 perl 구현을 찾았 습니다 .git-attic

편집 ^ 2 : Gitster가 동일한 기술을 사용 하는 블로그 게시물을 찾았 습니다 .


3
이 스레드의 다른 모든 사람을 제외하고는 실제로 질문에 대답했습니다.
tzrlk

20

리모컨의 변경 사항을 반영하기 위해 Steve의 답변 을 확장했습니다.

 git tag archive/<branchname> <branchname>
 git branch -D <branchname>
 git branch -d -r origin/<branchname>
 git push --tags
 git push origin :<branchname>

리모컨에서 복원하려면 이 질문을 참조하십시오 .


18

다른 저장소에 지점을 보관할 수 있습니다. 그다지 우아하지는 않지만 가능한 대안이라고 말하고 싶습니다.

git push git://yourthing.com/myproject-archive-branches.git yourbranch
git branch -d yourbranch

4
git-bundle별도의 저장소 대신 만들 수 있습니다 .
Jakub Narębski

9

이에 대한 별명은 다음과 같습니다.

arc    = "! f() { git tag archive/$1 $1 && git branch -D $1;}; f"

다음과 같이 추가하십시오 :

git config --global alias.arc '! f() { git tag archive/$1 $1 && git branch -D $1;}; f'

곰 염두에두고있다 git archive당신이 사용할 수 있도록 이미 명령 archive별칭 이름으로.

또한 '아카이브 된'브랜치 목록을 볼 수 있도록 별칭을 정의 할 수 있습니다.

arcl   = "! f() { git tag | grep '^archive/';}; f"

별명 추가 정보


3
(제안 자식의 최신 버전으로 여기 ),이 별명은 완성을 제공합니다 :!git tag archive/$1 $1 && git branch -D
부족

5

보관 된 분기를 숨기려면 다음 별칭을 사용하고 있습니다.

[alias]
    br = branch --no-merge master # show only branches not merged into master
    bra = branch                  # show all branches

따라서 git br적극적으로 개발 된 지점 git bra을 표시하고 "아카이브 된" 지점을 포함한 모든 지점을 표시 합니다.


5
브랜치가 마스터로 병합되었는지 여부는 아카이브 상태와 관련이 없습니다. 예를 들어 개발자 팀에는 테스트를 위해 특별히 만들어진 몇 개의 지점이 있습니다. 우리는 그 브랜치를 아카이브에 보관하고 싶지만 마스터로 병합하고 싶지는 않습니다.
Bart

4

지점을 보관하지 않습니다. 다른 방법으로, 브랜치 자체 보관하십시오. 당신이 원하는 것은 고고학자와 관련된 정보를 신뢰할 수있는 방법으로 찾을 수 있도록하는 것입니다. 일상적인 개발을 지원하고 작업 수행 프로세스에 추가 단계를 추가하지 않는다는 점에서 신뢰할 수 있습니다. 즉, 사람들이 지점을 완성하면 태그를 추가하는 것을 기억하지 않을 것입니다.

여기에 두 가지 간단한 단계의 그 도움 고고학 크게 의지 개발.

  1. 간단한 이름 지정 규칙을 사용하여 각 작업 분기를 이슈 트래커의 관련 이슈와 연결하십시오 .
  2. 항상 git merge --no-ff작업 분기를 병합 하는 데 사용하십시오 . 단 하나의 커밋에 대해서도 병합 커밋과 히스토리 버블을 원합니다.

그게 다야. 왜? 코드 고고학자로서, 브랜치에서 어떤 작업이 수행되었는지 알고 싶어하는 경우는 거의 없습니다. 훨씬 더 자주 그것은 비명을 지르는 9 개의 지옥에서 코드가 이런 식으로 작성된 이유입니다! 코드를 변경해야하지만 이상한 기능이 있으며 중요한 것을 깨뜨리지 않기 위해 문제를 해결해야합니다.

다음 단계는 git blame연관된 커밋을 찾은 다음 로그 메시지가 설명되기를 바랍니다. 더 깊이 파고 들어야 할 경우, 작업이 지점에서 수행되었는지 확인하고 지점을 전체로 읽습니다 (문제 추적기의 주석과 함께).

git blame커밋 XYZ의 포인트를 가정 해 봅시다 . Git 히스토리 브라우저 (gitk, GitX git log --decorate --graph등)를 열고 XYZ 커밋을 찾아서 ...

AA - BB - CC - DD - EE - FF - GG - II ...
     \                       /
      QQ - UU - XYZ - JJ - MM

내 지점이 있습니다! QQ, UU, XYZ, JJ 및 MM은 모두 동일한 지점의 일부이므로 자세한 내용은 해당 로그 메시지를 확인해야합니다. GG는 병합 커밋이 될 것이며 추적기의 문제와 관련이있는 지점의 이름을 갖습니다.

어떤 이유로 든 이전 분기를 찾으려면 git log병합 커밋에서 분기 이름을 실행 하고 검색 할 수 있습니다 . 매우 큰 리포지토리에서도 충분히 빠릅니다.

그것이 브랜치 자체를 보관한다고 말할 때의 의미입니다.

모든 브랜치에 태그를 지정하면 작업을 수행하는 데 불필요한 작업이 추가되고 (무자비하게 간소화되어야하는 중요한 프로세스), 매우 가끔 유용하고 수백 개의 태그로 태그 목록 (성능에 대해서는 말하지 않지만 사람의 가독성)을 강조합니다. ' 심지어 고고학에 매우 유용합니다.


2
그러나 혼란은 어떻습니까? 아마도 10 입방 야드의 흙 아래에 오래된 가지를 숨길 수있는 방법이 있었을 것입니다.
bvj

1
이것은 유용하지만 병합되지 않은 분기에는 적용되지 않습니다. 때로는 지점에서 실험을했으며 나중에 유용하게 사용될 수 있도록 내용을 유지하려고합니다.
Neil Mayhew

1
@bvj이 답변은 항상 병합 커밋을 통해 다시 분기 할 수 있기 때문에 병합 된 분기를 삭제해야한다고 제안합니다. 동의합니다.
닐 메이 휴

@NeilMayhew 네, 저와 같은 약 10 개의 병합되지 않은 지점이 있습니다. 각각은 열린 작업과 관련되어 있으므로 내가하고있는 일을 기억할 수 있습니다. 나는 그들과 함께 무언가를 할 것입니다, 또는 그들은 더 이상 관련성이 없어지고 그것들을 삭제할 것입니다. 나는 "나중에 필요할지도 모른다"지점에서 절대 익사하는 프로젝트를 진행하여 우리가하고있는 일을 거의 볼 수 없었다. 일부 개발자에게는 스스로 정리할 필요가 없다는 것은 변명이었습니다. 약간의 여유는 괜찮지 만 통제력을 벗어나지 못하게하십시오.
슈 베른

@Schwern 동의합니다. 나도 그런 프로젝트에 있었다. 분기 목록을 태그로 변환하는 것이 혼란을 제거하는 좋은 방법이라고 생각합니다. 태그 목록은 항상 커지는 반면 지점 목록은 계속 증가해서는 안되기 때문입니다. 태그에 네임 스페이스를 사용하면 목록을보다 관리하기 쉽게 만들 수 있지만, Packrat 경향은 반드시 저항되어야합니다. 다른 사람이 궁극적으로 사용할 가능성이 없으면 개발자는 자신의 컴퓨터에 커밋을 유지해야합니다.
Neil Mayhew 2015 년

2

내 접근 방식은 상관없는 모든 분기의 이름을 "trash_"접두어로 바꾸고 다음을 사용하는 것입니다.

git branch | grep -v trash

(쉘 키 바인딩으로)

활성 분기의 채색을 유지하려면 다음이 필요합니다.

git branch --color=always | grep --color=never --invert-match trash

2
분기의 이름을 바꾸는 경우 네임 스페이스 "archive /"
qneill

1

브랜치를 보관할 스크립트를 사용할 수 있습니다

아치

접두사 archive /를 사용하여 태그를 생성 한 다음 분기를 삭제합니다. 그러나 코드를 사용하기 전에 확인하십시오.


사용법- $/your/location/of/script/archbranch [branchname] [defaultbranch]

위치를 쓰지 않고 스크립트를 실행하려면 경로에 추가하십시오

그럼 당신은 그것을 호출 할 수 있습니다

$ archbranch [branchname] [defaultbranch]

[defaultbranch]이 보관이 완료되면로 이동합니다 지점입니다. 색상 코딩에는 문제가 있지만 그 외에는 문제가 있습니다. 프로젝트에서 오랫동안 사용해 왔지만 여전히 개발 중입니다.


1
스택 오버플로 도움말 에서는 제품과의 관계를 공개해야합니다.
LittleBobbyTables-Au Revoir 2016 년

미안, 몰랐어 나는 대본의 저자입니다.
Banezaka

0

때로는 다음과 같이 분기를 보관합니다.

  1. 패치 파일을 생성하십시오 format-patch <branchName> <firstHash>^..<lastHash>( 예 :을 사용하여 firstHash 및 lastHash 가져 오기) git log <branchName>.
  2. 생성 된 패치 파일을 파일 서버의 디렉토리로 이동하십시오.
  3. 분기 삭제 (예 : git branch -D <branchName>

브랜치를 다시 사용해야 할 때 패치를 "적용"하십시오. 그러나 패치 파일 ( git am)을 적용하는 것은 대상 브랜치의 상태에 따라 어려울 수 있습니다. 또한이 방법은 지점의 커밋을 가비지 수집하고 리포지토리 공간을 절약 할 수 있다는 이점이 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.