2016-05-09 7 views
0

動機:私は、Gitがうまくいくように見えますが、それにもかかわらず、特定の作業を必要とするほど珍しいシナリオがあります。基本的には、少なくとも10秒ごとに自動的に更新されるテキストファイル(コードなし)の束です。変更は相当なものであり、少なくとも時間の経過とともにリポジトリのサイズは比較的大きくなります。ローカルリポジトリは、ネットワークに常時接続されていない組み込みシステム上にあるので、ローカルのコミットをローカルで収集し、機会があればプッシュし、必要に応じてプッシュしたものを削除します。ヒストリはデバイスを一時的に保持するのに便利ですが、最も重要なことは、デバイスからそれを削除することが可能であることです。 (それは遠隔地に永遠に保たれている)。アプリケーション固有のいくつかの要因によっては、シナリオが多少拡張されている可能性があります.Gitで追加機能を活用するかもしれませんが、私が概説した基本的な構造は同じままでなければなりません。Git:リベースまたはフィルタブランチのない「恒久的な削除」

具体的には、リポジトリと1つのリモートのローカルコピーが1つあり、ローカルはリモートに(特定のブランチを)プッシュしません(プルしません)。コミット・グラフは単純であり、「直線」はマージまたは平行線のない順番にコミットします。プッシュする機会があれば(上記のように)、さらなるコミットのために新しいブランチが作成されます。したがって、たいていの場合、コミットのタイムラインを整理する機能だけを持つ新しいブランチがあります。これとは別に、ブランチを切り替えることはありません。

したがって、古いブランチを削除することができます。これは、前述のように、特にスペースが問題になるときの私たちの目標です。

 
date=$(date +"%m-%d-%y--%H-%M-%S") 

git $opt checkout -b "$date" 

git $opt branch -d $to_push 

# the first commit will be the single 'initial' commit in the master 
# branch, which is permanent and never 'deleted' 
git $opt replace --graft \ 
    $(git $opt log -n 1 --pretty="%H") \ 
    $(git $opt rev-list --max-parents=0 HEAD) 

git $opt reflog expire --expire=now --all 
git $opt gc --aggressive --prune=now 
git $opt repack -a -d -l 

opt変数は、作業ツリーとgit dirを指定するだけです。コミットとブランチを「完全に削除」するには、次のようにしました。私たちが実行したグラフト(後のgcなどで)は、普通のgit logのコミットを無事に削除していますが、実際には空き領域を解放していますが、まだコミットで保持されているdiffによって占有されていたスペースを解放していないようです。 ;たとえば、作成、コミット、および削除された大きなファイルは、コミットがこのように排除された後でも引き続きスペースを占有します。特に大きなファイルは実際にはありませんが、変更のデータ(差分)はまだリポジトリに保存されているという点で、この動作はより一般的であると想定しています。削除の心配。

私は構成の 'フェッチ'グロブからブランチを削除し、git fetch --prune originを実行するなど、私に示唆されたいくつかのトリックを使って残りの構造をぐるぐる回しました。例えばgit update-ref -d refs/remotes/origin/05-07-16--15-48-59となりましたが、これは問題のスペースを解放しませんでした。それが現在立っているとして、次のデータがリポジトリの状態を説明します。件名に記載された基準について

 
$ git log --all --oneline --graph --decorate 
* de345b6 (HEAD -> 05-07-16--15-50-56, replaced) sam. mai 7 15:44:16 EDT 2016 
| * 50272b5 sam. mai 7 15:44:16 EDT 2016 
|/ 
| * 0b96272 sam. mai 7 15:29:48 EDT 2016 
|/ 
| * b764118 sam. mai 7 15:28:13 EDT 2016 
|/ 
| * efa0536 sam. mai 7 15:14:45 EDT 2016 
|/ 
| * 40c8806 sam. mai 7 15:13:57 EDT 2016 
|/ 
| * 6f7c2f9 sam. mai 7 15:12:26 EDT 2016 
|/ 
| * fa33771 sam. mai 7 15:11:21 EDT 2016 
|/ 
| * 8698acd sam. mai 7 15:11:08 EDT 2016 
|/ 
* b2d9486 (origin/master, master) initial 
 
$ git show-ref 
de345b670e24ac68bbbf4aa7efd22598ef3c7251 refs/heads/05-07-16--15-50-56 
b2d9486d5d427d1ae4bb88828f334454a2fb6954 refs/heads/master 
b2d9486d5d427d1ae4bb88828f334454a2fb6954 refs/remotes/origin/master 
0b96272e47cab0b29e2706cae83b8154f8e412ea refs/replace/0afdaca4e6d071fc026d209249a7b0532c11122a 
b7641184c898ff08917d363435d5f45e5e9664ed refs/replace/498f8846c6a742f96997b599f5e25f5ad20b568c 
6f7c2f9b7700b39b4fd837c34ab7911a08d5438a refs/replace/4df4f9cf8cc01500c800f3f04cbbd655a866c9ba 
8698acd667d406fab764389b87518d133de887a6 refs/replace/9a91b7248da808a9fc6e1531c4206a6865273005 
40c880617db664cb73390d90e1401a049bc8c303 refs/replace/9edc1e243f4f36034a800c566fdeeac511e077a3 
efa0536a40e68d92751193fa0c6dec502d77ce72 refs/replace/d6256dbe48a10461e17ca3cf7e7c40700937d249 
fa3377117750fd81c703519038268fec89b65dce refs/replace/db9923391013d8e5d2974f328037f6315af85783 
50272b55f66b8d7c55305a3502db8e9f88b2db03 refs/replace/de345b670e24ac68bbbf4aa7efd22598ef3c7251 

を作業ツリー内のデータがあるので、我々はrebaseまたはfilter-branchを行うにはしたくありません議論の通り、頻繁に更新されています。作業ツリーをどこか別の場所にコピーしてそこで削除を実行することはできますが、それはスペース制約をさらに悪化させます。そして、別の場所にコピーして、リベースまたはフィルタブランチで古いデータを正常に削除したとしても、コピーしたリポジトリの新しい変更をrsyncして、コピーしたものをすべてライブにコピーする必要があります。積極的にリポジトリの内容を読み込んだり変更したりするプロセスに関しては、不可分な面倒なように思えますが、オープンになっています。

もう1つの提案は、とamを使用して、コミットを「シリアル化」し、テキストファイルパッチの形式でリモートリポジトリ上の構造を再構築することでした。次に、ローカルに新しいリポジトリを作成して古いデータを取り除くことができます。しかし、これは不必要に複雑に思えますし、基本的にgitが行うように設計された作業をやり直すように見えます。私たちはこの可能性(あるいはこれのために別のVCSに切り替える可能性、または何かカスタムになる可能性)には目を向けていますが、これがうまくいくように近いと思われます。

さらに詳しい情報を提供することができます。また、リポジトリを再作成して、さまざまな手順を試したり、さまざまな手順でコマンド出力を表示したりすることもできます。御時間ありがとうございます。

編集

ヴァンパイアの提案、およびその他の情報のための彼の要求後:

 
$ git rev-list --all | xargs -l $git describe --all --always    
replace/de345b670e24ac68bbbf4aa7efd22598ef3c7251 
replace/0afdaca4e6d071fc026d209249a7b0532c11122a 
replace/498f8846c6a742f96997b599f5e25f5ad20b568c 
replace/d6256dbe48a10461e17ca3cf7e7c40700937d249 
replace/9edc1e243f4f36034a800c566fdeeac511e077a3 
replace/4df4f9cf8cc01500c800f3f04cbbd655a866c9ba 
replace/db9923391013d8e5d2974f328037f6315af85783 
replace/9a91b7248da808a9fc6e1531c4206a6865273005 
heads/05-07-16--15-50-56 

答えて

1

あなたの問題は、あなたがgit replaceを使用することです。
git replace gitは実際には1つのコミットが別のコミットであるか、またはあなたのケースでは1つのコミットの親が別のコミットの親であるとふります。
元のオブジェクトはまだそこにありますが、ほとんどのgitコマンドでは論理的に置き換えられますが、rebaseまたはfilter-branchまたはそれに類するものを使用しない限り、物理的に置き換えられません。

しかし、私はあなたが後に実際にあるか、あなたは間違って取得していない場合は、次のように簡単です:その後、

git reset --soft <initial commit> 
git commit -m "recording current state as the only commit after the initial commit" 

とあなたも、ものをゴミ箱

を一掃するために詰め替えとかgitエイリアスの中にある2つのコマンドは、私が覚えている限り、Gitの原子操作にします。

+0

ありがとうございます。残念ながら、これはリポジトリのサイズを縮小していないように見え、後のコミットはまだ 'log --all --oneline --graph --decorate'に表示されます。 'git reflog expire -expire = now allは'エラー:すべてのポイントはどこにもない! 'を与えています。これはすでに起こっていて、私は自分の投稿で言及するのを忘れました(私は追加します)。現在のテストリポジトリに問題があると思われる場合は、新しいテストリポジトリを作成して試すことができます。 –

+0

あなたは 'all'の前に' --'がないと思うので、 'all'の代わりに' --all'を使います。さもなければ、エラーが示唆するようにどこでも指していない 'all'というブランチのreflogを期限切れにします。 – Vampire

+0

ああ、申し訳ありません、それは明らかだったはずです。 reflogの有効期限が切れ、その後のgcとrepackを使用すると、私は120Mから80Mまでのサイズを持っています。その余分なスペースを取っているのは何ですか?私はそれがすべてか何かであると思ったでしょう。 –

関連する問題