ドットファイルをシンボリックリンクする代わりにgitに$ HOMEを入れることには落とし穴がありますか?


38

私は長年にわたって$HOMEディレクトリ全体をSubversionにチェックインしてきました。これには、すべてのドットファイルとアプリケーションプロファイル、多くのスクリプト、ツール、ハック、私の好みの基本的なホームディレクトリ構造、少数の奇妙なプロジェクト、および大量のランダムデータが含まれています。これは良いことでした。それが続いた間。

しかし、それは手に負えなくなっています。基本的なチェックアウトは数十のシステムで同じですが、すべてが私のマシンに適しているわけではありません。すべてが異なるディストリビューションでうまく再生されるわけでもありません。

私は家の掃除をしています-データが属する場所を分離し、いくつかのスクリプトを別々のプロジェクトとして分割し、自動化すべきものの壊れたリンクを修正します。

私の意図は、交換することであるsubversiongitのトップレベルのチェックアウトのために$HOME、私は、私はドットファイル、いくつかのディレクトリといくつかの基本的なカスタムスクリプトを意味し、すべての私のシステムにしたいのですが物事にこのダウンを削り取っしたいと思います。

オンラインで読むと、多くの人がシンボリックリンクアプローチを使用してこれを行っているよう$HOMEです。サブディレクトリにクローンを作成し、リポジトリからシンボリックリンクを作成します。私が持っていたた$HOME10年以上のフルバージョン管理の下で、私はこのaproachのアイデア好きではないと人々はストレート精算方法にとても嫌うようで、なぜ私が理解することはできません。トップレベルのチェックアウトとして特定する必要がある落とし穴はありますか?git$HOME

PS良いコーディングの練習の一部として、ルートチェックアウトをgithubで公開することも計画しています。考え直さずに共有できるはずのないファイルに、どれだけ多くのセキュリティ機密情報を収集することが許されているかは恐ろしいことです!WiFiパスワード、パスフレーズなしのRSAキーなど。


5
$ HOMEは考え直さずに共有可能であるべきだという信念につながったものに興味があります‽暗号化されたRSA秘密鍵でさえ共有すべきではありません。
-derobert

3
あなたが実際にホームディレクトリの内容をgitに入れることについて話している場合は注意してください:git履歴を掘り下げて慎重に機密項目を永久に削除することは難しい(しかし不可能ではない)また、ブランチまたはチェックアウトを切り替えると、以前のリビジョンgit644チェックアウト後にファイルのパーミッションを変更することに注意してください。これはプライベートsshキーのようなものにとっては悪いことです。ただしetckeeper、/ etc /のアクセス許可でgitを使用するためのソリューションです
cwd

@デロバート:私はそれをよく知っています。私は$ HOMEをパブリックにすることではなく、単なるドットファイルと便利なスクリプトについて話しました。それらは私が所属していないものを見つけてきた場所です。そして、はい、私は共有することができるはずです.zshrc.vimrc最初にそれらをサニタイズすることなく、同様のものを!
カレブ

4
まだご覧になっていない場合は、vcs-home wikiとメーリングリストをご覧ください。これは基本的にこれについて議論している人々です-$ HOMEをリビジョン管理下に置く方法。
ジム・パリ

gitの振る舞いをどれだけ変更できるかはわかりませんが、少なくともdebian-repositoryから外れて動作する方法では、追跡/追跡解除/変更されたファイルを検索し、自動的にすべてのファイルに責任があると感じています。mrbはすでにこれを述べています。ホームディレクトリでそれを望んでいない比較的小さなプロジェクトでさえ、この欲張りな行動にイライラすることがあります。なぜgitを使用したいのですか?また、バージョン管理システムを使用して、ホスト間で構成ファイルを同期していますが、CVSは非常に単純であるため非常に満足しています!Gitはそのために(あまりにも!)パワフルです
Bananguin

回答:


17

はいgit心配しないホームディレクトリを管理することを考えるとき、少なくとも1つの大きな落とし穴がありsubversionます。

Gitはデフォルトで貪欲で再帰的です

Subversionは、知らないものを無視し、知らない(または別のリポジトリに属している)フォルダーにチェックアウトすると、フォルダーの処理を停止します。一方、Gitはすべての子ディレクトリに再帰し続けるため、名前空間の問題のためにネストされたチェックアウトが非常に複雑になります。ホームディレクトリは、他のさまざまなgitリポジトリをチェックアウトして作業する場所でもある可能性が高いため、ホームディレクトリをgitに置くことは、ほぼ間違いなくあなたの人生を不可能な混乱に陥れます。

結局のところ、これが人々がドットファイルを隔離されたフォルダーにチェックアウトし、そこにシンボリックリンクする主な理由です。あなたのの子ディレクトリで何かをするとき、それはgitを邪魔にしないようにします$HOME。あなたの家を転覆にチェックインする場合、これは純粋に好みの問題ですが、gitを使用する場合、それは必要な問題になります。

ただし、代替ソリューションがあります。Gitは、「偽のルート」と呼ばれるものを許可します。このルートでは、すべてのリポジトリマシンが、チェックアウト作業ディレクトリから物理的に分離できる代替フォルダーに隠されます。その結果、gitツールキットが混乱することはありません。リポジトリを見ることも、作業コピーだけを見ることもありません。いくつかの環境変数を設定することで、ホームディレクトリを管理している瞬間に商品を見つける場所をgitに渡すことができます。環境変数が設定されていないと、誰も賢くなく、家は昔ながらのファイルのように見えます。

このトリックの流れを少しスムーズにするために、素晴らしいツールがいくつかあります。VCS-ホームメーリングリストを開始するデファクト場所、約ページはHOWTOや人々の経験の便利なラップアップを持っているように思えます。途中に、vcshmrのような気の利いた小さなツールがいくつかあります。ホームディレクトリをgitに直接保持する場合は、vcshがほぼ必須のツールです。あなたは舞台裏でいくつかのrepostoriesに分割するホームディレクトリを終わる場合は、組み合わせるvcshmr、迅速かつあまり汚いやり方は、一度にすべてを管理するため。


2
しかし、単に.gitignoreファイルに「*」を追加しないのはなぜですか?こうすると、gitはすでにリポジトリにあるファイルを除くすべてを無視し、で新しいファイルを追加できますgit add -f <file>
アリックス

@ALiX:gitツールは、プロジェクトの別のgitリポジトリであるサブディレクトリにいたとしても、ホームディレクトリリポジトリで作業しているとみなすためです。このソリューションは、ホームディレクトリ全体を他のすべてのgit作業の制限から外します。
カレブ

5
ただし、.gitignoreの「*」は、home-dirリポジトリにないすべてのファイルが無視されることを意味します。また、サブディレクトリで新しいgitリポジトリをチェックアウトしても、すべてが期待どおりに動作するはずです(私は思う)。私の知る限り、gitツールは最初の.gitディレクトリを探し、ディレクトリ階層を上に移動します。そのため、サブディレクトリで作業する場合、正しいgitリポジトリが使用されます。もちろん、gitの環境変数を使用している場合、物事が面倒になる可能性があります。しかし、そうでなければ、なぜこれが機能しないのかわかりません。
アリックス

@ALiXが正しい。ネストされたgitリポジトリは、親リポジトリでgitignoreしている限り正常に動作するようです。gitの環境変数で起こりうる問題は別として、この非常に単純なアプローチの欠点は何でしょうか。
evanrmurphy

1
今日これを試しています。既定ではすべてを無視しますが、ディレクトリを追加するのがはるかに簡単になるため、私は/*よりうまくいくと思います*。代わりにand (.gitignoreファイル自体用)のような接頭辞付きパターンgit add -fを使用して、明示的にレポジトリに追加します。!!/.vimrc!/.gitignore
evanrmurphy

14

ホームディレクトリ全体がバージョン管理にチェックインされるのは望ましくありません。というのは、それが入ってくるすべてのサブディレクトリがホームディレクトリのバージョン管理コンテキストを持っているからです。そのようなコマンドにgit checkoutは実際のアクションがあり、間違ったディレクトリから何かを誤って実行すると、gitそれ自体かgitを呼び出すスクリプトかどうかに問題が発生します。

また、レポジトリに不要なものを追加する可能性が高くなります。これは、すべてをチェックインした場合は問題になりませんでしたが、現在は問題になります。秘密鍵ファイルを誤って(おそらく習慣から)追加して、githubにプッシュした場合はどうなりますか?

そうは言っても、主な欠点は実際には技術的なものではなく、自分を救いたいだけです。

シンボリックリンクについて:リポジトリをサブディレクトリに複製し、更新が必要なシンボリックリンクを更新するスクリプトを作成できます。ただし、このスクリプトに必要なメンテナンスの量は、このスクリプトを使用する利点を上回る場合があります。シンボリックリンクは作業量が少なくなることがあります。

シンボリックリンクを使用すると、gitにチェックインされるディストリビューション固有(またはホスト固有)の追加を簡単に行うこともできます。symlink-updateスクリプトは、互換性のないプラットフォームまたは異なるホスト向けのファイルを無視し、適切なもののみを更新します。

何かのようなもの:

HOMEREPO=$HOME/homerepo
HOST=$(hostname)
UNAME=$(uname)

for dotfile in $HOMEREPO/shared/* $HOMEREPO/host-$HOST/* $HOMEREPO/uname-$UNAME/*
do
    target=$HOME/$(basename $dotfile)
    [ ! -r $target ] && ln -s $dotfile $target
done

個人的に:私はシンボリックリンクを使用し、ディレクトリをシンボリックリンクしません。内のファイルのみ。これにより、これらのディレクトリでサイトローカルの変更を行う柔軟性が得られます(つまり、ファイルの追加/削除)。すべてのシンボリックリンクを手動で再作成する必要があるため、新しいシステムでアカウントをセットアップするのは面倒です。


どれでもgit私が実行したコマンドは、どちらかのホームディレクトリ自身のためになるか、NONに少なくとも1つの深いディレクトリをコミット埋葬されるだろう。svnこの1つのフォルダーの分離を使用することは非常に効果的であり、10年間で問題を引き起こすことはありません。最初の段落は何か他のものを示しています。これは実際にgit動作方法の違いですか?
カレブ

また、私の構成とスクリプトには、さまざまなホストとプラットフォーム用の条件付きロジックが既に組み込まれているため、スクリプトを使用して条件付きとして異なるリンクを設定することは、gitブランチを管理しやすいという点ではあまり得策ではないようです。まだ何か足りないものがあるのでしょうか、それとも好みになりますか?
カレブ

3
ワンフォルダ分離は本当に分離株ないgit程度ではないことを確認- svnしかし、たとえば、のための- git init foo && mkdir -p foo/bar/baz/spam && cd foo/bar/baz/spam && git statusあなたはまだしていること(または他のgitコマンド)ショーfooのバージョン管理コンテキスト。
Mrb

構成とスクリプト:すべてのドットファイルが条件をサポートしているわけではないため、別のアプローチを提案しました。これらはすべて、人々がバージョン管理を使用しないことを好むと思う理由です$HOME-そして、バージョン管理はドットファイルimoにとってはあまり価値がありません-しかし、最終的にはあなたのホームディレクトリです。頑張れ!
MRB

情報をありがとう。実際、gitが分離を許可していないというコメントが最も有用なビットです。あなたはあなたの答えにそれを顕著に取り組むかもしれません。Subversionの動作はその点で大きく異なり、このユースケースでは重要です。
カレブ

6

別の見方をするために、私はgitの下に$ HOMEを持っていますが、欠点は見つかりませんでした。私は明らかにこのgitリポジトリをgithubに同期しません。私はプライベートリポジトリを持つサービスを使用しています。また、メディアファイル、ダウンロード、パッケージをgitの制御下に置くこともありません。

  • git status 「やること、きれいにする」チェックリストの一種です。

  • 私は~/tmp一時的なものを持っていますが、これは無視されます。

  • git status最近インストールしたソフトウェアが$ HOMEに追加することを敢えてし、これらのファイルを削除したり、犯人をアンインストールしたりすることを何でも見るのが好きです。

  • 本当に便利なローカルファイルとディレクトリを手動でに追加します.gitignore。これには、「インストール時に何をするかを知っている」という利点があります。

  • 新しいVMを構築するか、新しいPCをインストールする場合、リモートホームを$ HOMEに複製するだけで、すぐに必要なものすべてを手に入れることができます。

  • vimプラグインのvundleのようなものはもう必要ありません。

私は複雑さが嫌いです。rcfileを微調整するときは、コミットしてプッシュするだけです。その後、反射として、1日おきに$ HOMEをgit pullし、常に最新の構成を保持します。とても簡単です。

現在このレジメンの下にあるマシン:自宅のラップトップ、職場のPC、職場のVM、および3つまたは4つのリモートサーバー。


あなたの家の中に他のgitチェックアウトがネストされていますか?
カレブ

いいえ、他のことを/ workディレクトリに置き、vim puginsのような小さなツールのクローンを作成しません。
GB。

1
〜/ Sites内で作業を行い、このアプローチも実行します。ネストされたgitリポジトリに問題はありません
-philfreo

1
私はこのセットアップをしばらく使用しています。私は「エイリアスsq = git status -uno」を持っています。ネストされたgitリポジトリで問題が発生したことはありません。git init --baressh経由でプッシュするプライベートサーバーがあります(レポジトリにパスワードを入れませんが、メモファイルがあります)。
アンハンマー

5

私は両方を試してみましたが、最終にはシンボリックリンクのアプローチを好みました:

  • どこでもチェックアウト
  • make install
  • ログアウトしてから再度ログインして、X設定をロードします

短所:

  • する必要があるファイルを移動し、それらを追加する前にレポへ
  • Makefileのシンボリックリンクリストを維持する必要があります

利点:

  • 大規模なものは必要ありません.gitignore~謙虚なUbuntuボックスには133個のドットファイルがあります)
  • することができ、メンテナンススクリプトキープと他の~(のような関連のものMakefileとをcleanup.sh邪魔にならないように
  • 個人設定と公開設定を個別にバージョン管理できます

制限事項:

  • @mrbとは異なり、シンボリックリンクのみを作成し~ます。これにより、シンボリックリンクがシンプルに保た~/.vimれ、非常にまれな.gitignoreメンテナンスを犠牲にして、たとえばで新しいファイルに気付くのが簡単になります。

最後の2つの利点は、私の場合、規模を大きく変えました。ホームディレクトリを散らかしたくはありません。プライベートコンテンツとパブリックコンテンツを明確に分けたいと思います。

私が知っている唯一のアプリケーションは、シンボリックリンクの処理に問題がある(または少なくとも問題がある)Pidginでした。これは、通常のファイルでシンボリックリンクを上書きし続けました。


各アプローチの長所と短所についてご意見をお寄せいただきありがとうございます。私のフォローアップでは、追加の配線を設定して始めても大丈夫な場合、両方の世界を最大限に活用できる第3のアプローチがあることを発見しました。
カレブ

3

ここでは一つだ:あなたがしようとするgit rebase -i --rootと、あなたがチェックした.gitconfig最初のリポジトリにコミットするには、gitが一時的に削除されます.gitconfig、それはやって自分の名前と電子メールを必要とするので、今度はそれができないリベース操作を完了するようになりますファイルを、それは、そのファイルに保存されます。

あなたはそれらを再び設定してやり直すことができますがgit rebase --continue、それを行ってリベース操作を完了した後、gitリポジトリは以前にリポジトリの最初のコミットであったコミットの前にコミットメッセージなしで空のコミットを得ました取り除く方法。

git rebase -i <commit>代わりに行うとどうなるかわかりませんが、の.gitconfigあとのコミットと一緒にチェックインされます<commit>

おそらく最も簡単な解決策は.gitconfig、リポジトリへの追加を控え、代わりにリストすることです.gitignore


2

これは私がそれを行う方法です:

  1. クリーンなLinuxをインストールします(必要ではありませんが、ステップ4で生活をより快適にします)
  2. etckeeperをインストールする
  3. git initあなたの家で走る
  4. .gitignoreを作成し、興味のないように見えるものや、大きく変わる可能性のあるものをすべて追加します。以下のようなものを追加してください*.cache*.lock私などの追加はお勧めしません。/*自宅に何か新しいものが追加されたときに自動的に通知されないためです。これはブラックリストアプローチとホワイトリストアプローチであり、基本的には、揮発性のものと気にしないソフトウェアを除くすべてのソフトウェアの設定を保持します。後でシステムをマージ、移行、または比較するときに、すべてを差分できるのは非常に便利です。.bashrcと他のいくつかのドットファイルを保存するだけの場合よりもはるかに高速に新しいシステムをセットアップできます。この方法では、GUIを使用して設定する可能性のある設定を保持し、どのドットファイルが設定を保存するかを認識しません。(揮発性ファイルをコミットしたことが判明した場合でも、gitに変更を想定しないように伝えることができます)
  5. 走る etckeeper init -d /home/username
  6. 走る git commit -d /home/username
  7. シェルにエイリアスを設定して、コマンドラインをより良くします homekeeper checkout

etckeeperを使用する理由は、ファイルのアクセス許可などのメタデータを保存するためです(sshキーなどの特定のものではなく重要です)。これで、メタデータを自動的に保存する事前コミットフックができました。チェックアウト後についてはよくわかりません。おそらく使用する必要etckeeper checkout xxx -d /home/userがあります。もう少し詳しく見て、この答えを詳しく説明します。


-1

ホームディレクトリでGitを使用する場合の主な問題は、Gitがファイルのアクセス許可やタイムスタンプなどのファイル属性を保存しないことです。私にとっては、特定のファイルがいつ作成されたかを知ることが重要です。さらに、ファイルやディレクトリへのアクセス許可を失うなどの.ssh問題があります。.sshGit を使用しないことを計画していることは理解していますが、アクセス許可が重要になる可能性のある他の場所(非圧縮Webサイトのバックアップなど)があります。


実際に間違っていない場合、これは誤解を招きます。Gitはデフォルトで、許可を含む多くのファイル属性を保持します。.sshしばらくの間gitを問題なく保持していますが、適切な安全なアクセス許可が保持されています。基本構成で行わないことは、所有権またはタイムスタンプを保持することです。ただし、これらのいずれかが特定のユースケースの問題である場合、これらの追加プロパティを通常のワークフローの一部として処理できるプラグインがあります(metastoreまたはgit-cache-metaを参照)。
カレブ

たとえそれらが保存されていなくても、VCにないホームディレクトリを持っているよりも悪いことはどうですか?gitは、ファイルの変更を要求しない限り、mtimesを積極的に上書きしません。
poolie

-1

gitベースのソリューションは、ファイルを別のマシンにデプロイする必要がある場合に特に役立ちます。すべてのマシンに共通する部分と一部のマシンに固有の部分がある場合はさらに便利です。複数のリポジトリを作成し、multigitvcshなどのツールを使用して、同じディレクトリ(この場合はホームディレクトリ)にクローンを作成できます。


ありがとう、しかしあなたは質問を逃したかもしれません。私はこれの使い方をよく知っています(最初にそれをやりたかった理由です)、この質問は、gitでこれを行うことに新しい人が(私が尋ねたときにそうだったように)気づかないかもしれない落とし穴についてでした。これはその質問にまったく答えていないようです。
カレブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.