どうすればgitブランチをアーカイブできますか?


305

私のgitリポジトリには、現在活発に開発されていない古いブランチがあります。実行時にデフォルトで表示されないように、ブランチをアーカイブしたいと思いますgit branch -l -r。履歴を残したいので削除したくありません。これどうやってするの?

refs / headsの外にrefを作成することは可能です。たとえば、refs/archive/old_branch。それを行うことの結果はありますか?


git-rmはリポジトリからリソースを削除せず、インデックスからリソースを削除するだけですkernel.org/pub/software/scm/git/docs/git-rm.htmlこれらのリソースはgit checkout [rev] file
Dana the Sane

1
私が知っていることではありません。Attic/<branchname>ただし、軽量のタグを使用してブランチをアーカイブしています。
JakubNarębski、2009

タグは迅速かつ安全で健全な選択です。
2009

回答:


401

これを行う適切な方法は、ブランチにタグを付けることだと思います。タグを付けた後でブランチを削除すると、ブランチを効果的に維持できますが、ブランチリストが乱雑になることはありません。

ブランチに戻る必要がある場合は、タグを確認してください。タグからブランチを効果的に復元します。

ブランチをアーカイブして削除するには:

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

しばらくしてからブランチを復元するには:

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

ブランチの履歴は、タグ付けしたときとまったく同じように保持されます。


11
私はGitの初心者だけど、これを試しに、私はブランチを復元するための適切なコマンドがあると思う:git checkout -b <branchname> archive/<branchname>
スティーブ

6
この場合にオブジェクトタグを使用しない理由はありますか?誰がブランチをアーカイブしたか、いつ興味深いかを確認できること。
グレゴリージョセフ

7
@GrégoryJoseph:いわゆる「注釈付きタグ」です。そうですね、それを使用することには大きな意味があります。
onnodb 2013

22
branch -Dちなみに、この方法でアーカイブすると完全にマージされない可能性が高いため、おそらくお望みでしょう
Arkadiy Kukarkin 14年

5
非常に素晴らしい。ここに説明付きの完全なチュートリアルがあります。
guyaloni 2015

123

ジェレミーの答えは原則として正しいですが、彼が指定するコマンドが私見では正しくありません。

ブランチをチェックアウトせずに(したがって、そのブランチを削除する前に別のブランチにチェックアウトしなくても)、ブランチをタグにアーカイブする方法は次のとおりです。

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

ブランチを復元する方法は次のとおりです。

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

18
まだ十分なポイントはなかったと思いますが、既存の回答を編集するほうが良いでしょう-とにかく+1します:)
jkp

5
@jkpが他のユーザーのコードやコマンドを編集することは、通常gitコマンドの微妙な変更が劇的に異なることを行う可能性があり、元の作者が彼らがした方法で何かを書いた理由を理解していない可能性があるため、通常は嫌われます。自分で答えるか、コメントを残した方がいいです。
Dan Bechard

または、劇的に異なるものよりもさらに悪いことに、コマンドまたはコードの微妙な変更が微妙に異なる結果につながる可能性があり、それを理解するのが非常に難しい場合があります。回答の投稿者が自分で編集または応答できるように、コメントとして残すことをお勧めします可能性のある異なる結果を参照する
反訴

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

また、あなたがしたいことのconfigureのリモコンのようにpush = +refs/archive/*:refs/archive/*、自動的に(またはアーカイブされた枝をプッシュするgit push origin refs/archive/*:refs/archive/*ワンショットのため)。

別の方法は、ブランチを削除する前にSHA1をどこかに書き留めることですが、制限があります。参照なしのコミットは、手動は言うまでもなく、3か月後(またはreflogなしの数週間後)GCされますgit gc --prune。参照によって指されたコミットは、GCから安全です。

編集:@apによって同じアイデアのperl実装が見つかりました:git-attic

編集^ 2: Gitster自身が同じテクニックを使用しているブログ投稿を見つけまし


3
このスレッドの他の全員を除いて、あなたは実際に質問に答えました。
tzrlk 2017

20

リモコンの変更を反映するためにスティーブの答えを拡張して、

 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別のリポジトリの代わりに作成できます。
JakubNarębski、2009

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の新しいバージョン(ここで提案されているように)では、このエイリアスが完成します:!git tag archive/$1 $1 && git branch -D
Lack

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

ブランチはアーカイブしません。言い換えると、ブランチは自分自身をアーカイブします。あなたが望むのは、考古学者に関連する情報が信頼できる方法で見つけられることを確実にすることです。毎日の開発を支援し、作業を完了するプロセスに余分なステップを追加しないという点で信頼できます。つまり、ブランチが完成したら、タグを忘れずに追加できるとは思いません。

考古学開発に大いに役立つ2つの簡単なステップを次に示します。

  1. 単純な命名規則を使用して、各タスクのブランチを課題追跡の関連する課題にリンクします
  2. git merge --no-ffタスクブランチをマージするために常に使用します。1つのコミットだけでも、コミットと履歴をマージする必要があります。

それでおしまい。どうして?コード考古学者として、私はめったにブランチで行われた作業を知りたいと思うことから始めることはないからです。はるかに頻繁に、それはすべての叫び声の9つの地獄でコードがこのように書かれている理由です!?コードを変更する必要がありますが、奇妙な機能がいくつかあり、重要なものを壊さないように、それらを混乱させる必要があります。

次のステップはgit blame、関連するコミットを見つけて、ログメッセージが説明であることを期待することです。さらに深く掘り下げる必要がある場合は、作業がブランチで行われたかどうかを確認し、ブランチ全体を(課題トラッカーでのコメントとともに)読みます。

git blameXYZのコミットを指しているとしましょう。私は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 2018年

1
これは便利ですが、マージされていないブランチには適用できません。ブランチで実験が行われ、後で一部が役立つ場合に備えてコンテンツを保持したい場合があります。
Neil Mayhew

1
@bvj私はこの答えは、マージされたブランチを常に削除する必要があることを示唆しています。マージコミットを介していつでもブランチに戻ることができるためです。これに同意する。
Neil Mayhew

@NeilMayhewはい、私はそのような約10個のマージされていないブランチを開いています。それぞれが開いているタスクに関連付けられているので、自分が何をしていたかを思い出すことができます。私はそれらを使って何かをするか、または古くなりすぎて関係がなくなったので削除します。私は「後で必要になるかもしれない」ブランチで完全に溺死するプロジェクトに取り組んだので、私たちが何をしていたかほとんどわかりませんでした。一部の開発者が自分でクリーンアップする必要がないのは、本当に言い訳でした。多少の余裕はありますが、制御不能にさせないでください。
シュヴェルン

@Schwern同意する。私もそのようなプロジェクトに参加しています。ブランチをタグに変換することは、混乱を取り除くための良い方法だと思います。タグのリストは常に大きくなる一方、ブランチのリストは大きくならないためです(これは、進行中の作業量を表すためです)。タグに名前空間を使用すると、リストが管理しやすくなりますが、packratの傾向には必ず抵抗する必要があります。他の誰かが最終的にコミットを使用する可能性が十分にない限り、開発者は自分のマシンでコミットを保持する必要があります。
Neil Mayhew

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
Stack Overflow Helpに従って、製品との関係を開示する必要があります。
LittleBobbyTables-Au Revoir 2013年

ああ、すみません、知りませんでした。私は脚本の作者です。
Banezaka 2014年

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.