14

私はリモコンのFooとBarを持っています。Foo は多数のディレクトリを持つ Web アプリケーションであり、それらの中で関連するのは、/publicさまざまなファイルやその他のディレクトリを含むものです。

Bar はライブラリのセットであり、フロントエンドで使用されないものであるため/public/bar、Foo に入れる必要があります。Foo にはファイルがありません。

それは、サブモジュールまたはサブツリーのマージのいずれかを使用すると、すべて簡単になります。しかし…</p>

Bar のツリーはごちゃごちゃしており、PSD や FLA などのあらゆる種類のプリプロダクション ファイルが含まれており、その中にあるものだけが本当に便利な部分です/www/tools

だから、私がやりたい/www/toolsのは、 Bar を Foo にマージし/public/bar、Bar のツリーの残りの部分が存在しないふりをすることです。

できる?

(これは、最初に自分のプロジェクトをサブツリーとしてマージしたプロジェクトからマージする方法と非常に似ていると思います。これも方法がわかりません。)

4

5 に答える 5

11

次のコマンドを使用してこれを正常に実行しました(シナリオ用に書き直しました)。

$ git remote add Bar /path/to/bar
$ git merge -s ours --no-commit Bar/master
$ git read-tree --prefix=public/bar -u Bar/master:www/tools/

大きな警告!Bar からフェッチ/マージする方法をまだ考え中です。これにより、すべてが一度だけ取り込まれます。

変更をマージする現在の方法は次のようになります。

$ get fetch Bar
$ git pull -X subtree=public/bar Bar master

これにより、大量のファイルが削除されたという競合が残ります。git rmそれらを削除してからgit commit.

変更をプルするためのより良い方法についての提案を歓迎します。

これは古いスレッドなので、Git 1.7.9 を実行していることを付け加えておきます。

于 2012-08-21T03:43:19.370 に答える
4

これにはgit subtreeを使用してみてください。プロジェクトのサブツリーを別のプロジェクトに抽出し、それを自分のプロジェクトにマージできます。

于 2009-08-20T18:23:22.310 に答える
2

編集:あなたがこれをただで行うことができると私は思いますgit merge --no-commit。これによりマージが試行され、競合していなくても、コミットする直前に停止します。この時点で、不要なすべてのジャンクを削除し(必要に応じて競合するファイルを復元することを含む)、目的のサブツリーのみを含むマージコミットを作成できます。

元の答え:

あなたは確かにこれのためにフィルターブランチを使うことができます。アウトライン:

ソースリポジトリのクローンを作成します。

git clone --bare /path/to/bar /path/to/bar_clone

ベアクローンを使用すると、作業ディレクトリを作成する時間とスペースを節約できます。

次に、クローンでfilter-branchを使用します。

git filter-branch --index-filter 'git rm -rf <unwanted files/directories>' -- --all

--all、現在のHEADだけでなく、すべての参照を使用することを通知します。これで、目的のサブディレクトリとそれに関連付けられたすべての履歴のみを含むリポジトリが作成されます。

注:申し訳ありませんが、必要なもの以外をすべて削除するための本当に簡単な方法はわかりません。gitディレクトリを壊したくないので、ワイルドカードに注意する必要があります。これはうまくいくものですが、特にファイルがたくさんある場合は遅くなります。

git filter-branch --index-filter 'git rm -f `git ls-files | grep -v ^www/tools`' -- --all

とにかく、削除するファイルのリストを管理する場合でも、サブツリーのマージを続行して、からプルすることができbar_cloneますfoo

于 2009-07-28T19:30:24.947 に答える
0

サブツリーを 2 回使用することをお勧めします。1 回目はすべての /www/tools を抽出するため、もう 1 回は /public を抽​​出するためです。/public は独自のリポジトリにある必要があるように思われるため、/public を新しいリポジトリにプッシュすることをお勧めします。そのすべてがサブツリー履歴であり、/www/tools のサブツリー履歴を新しい /public リポジトリにマージし、それを Foo のサブツリーとして追加します。

cd foo
git subtree split --prefix=public --branch=new-shared-public --annotate='(split) '
cd../bar
git subtree split --prefix=www/tools --rejoin --branch=new-shared-www-tools --annotate='(split) '

これで、リポジトリに 2 つの新しいブランチが作成されました。1 つは public のコミット履歴、もう 1 つは www/tools です。ここからは割愛cdします。

新しいパブリック リポジトリを作成し (ここでは github を想定していますが、ローカルでやりたいと思われるかもしれません)、そこにサブツリーをプッシュします: git checkout new-shared-public git push git@github.com:my_id/new-shared- repo.git HEAD:マスター

次に、他のブランチをそれにマージします。

git checkout new-shared-www-tools
git remote add Foo git@github.com:my_id/new-shared-repo.git
git merge -s ours --no-commit Bar/master

oursコミットポリシーとして指定しましたが、おそらく (おそらく) 関係ありません。

最後に、マージを実行して新しいリポジトリにプッシュした後、Foo リポジトリに戻ります。そこから公開履歴を Git rm し、新しい公開リポジトリをサブツリーとして追加します。

git subtree add --squash --prefix shared git@github.com:my_id/new-shared-repo.git master
git subtree pull --squash --prefix shared git@github.com:my_id/new-shared-repo.git master
git push
于 2012-10-25T14:28:24.700 に答える
0

マージ自体を使用してこれを実行できるとは思いませんが、少なくとも最終製品に関する限り、これらの手順でうまくいく可能性があります。初め:

% git fetch Bar

これにより、Bar リポジトリから最新のコミットが取得されますが、マージは試行されません。コミットの SHA を .git/FETCH_HEAD に記録します。

% cat .git/FETCH_HEAD
b91040363160aab4b5dd46e61e42092db74b65b7                branch 'Bar' of ssh://blah...

これは、リモート ブランチからの最新のコミットの SHA 識別子が何であるかを示しています。

% git checkout b91040363160aab4b5dd46e61e42092db74b65b7 www/tools

これは、フェッチされたコミットの www/tools にあるファイルのコピーを取得し、作業ツリーにあるものを上書きします。その後、通常どおり、これらの変更をローカル リポジトリにコミットできます。結果のコミットには、それがどこから来たのかへの参照はありませんが、少なくとも、必要なファイルのバージョンを含むリポジトリを取得する必要があります。

于 2009-07-23T21:27:05.937 に答える