2014-01-19 9 views
7

されていないコミットサブツリーとして)。 external/mainの変更をmainリポジトリに移行したいのですが、これらのコミットだけで、external/<anything-else>のような他の無関係なコミットはありません。削除は、私が実際に2つのリポジトリを持っているサブツリーにも、元のリポジトリに

私は実際に古典を試してみた:

git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter main -- --all 

をしかし、それはあまりにも初期mainリポジトリに行われたすべてのコミットを削除し、のみexternal gitリポジトリで行われたものを残します。


ので:のみのコミットを保持する方法:

A)

b)はexternalのサブツリーに作られた初期mainリポジトリに作られた(external/mainを)


git pull -s subtree ../externalを試すと、サブツリー内の何も変更されていないコミットを含むすべてのコミットがマージされます。私はサブツリー内の何かを実際に変更したコミットと、サブツリーからのファイルに関する情報だけを持っていたいと思います。

+0

'ZZZ'はどのように' AAA'にマージされましたか? – LopSae

+0

少しの意味を伝え、リポジトリの 'main'や' external'といった質問の読みやすさを助ける名前を使うこともできます。 – LopSae

+0

通常のメカニズムでは、 'external'でリポジトリを取得し、' read-tree'を使って 'external'リポジトリのディレクトリに置きます。 – bwoebi

答えて

2

あなたはあなたのコマンドの<rev-list options>セクションで--not --remotesを使用してfilter-branchによって書き換えコミットを制限することができるはずです。

git filter-branch --tag-name-filter cat --prune-empty 
    --subdirectory-filter main -- --all --not --remotes 

これはあなたのリモートブランチから到達可能なコミットを含めることfilter-branchない原因となります。複数のリモコンがある場合は、--remotes=originのようなものを使用して、どのリモートを考慮するかを指定できます。 external二つのものに起こったすべての関連の変更が発生する必要があります。mainに持ち込むためには

+0

うーん...非常に素晴らしいです!ありがとう!それはちょうど何とか別の無関係のサブツリーマージコミット含ま:https://github.com/krakjoe/phpdbg/commit/efc7d6db18a4f5ecc6c4437041c78f067c96e05dそれを削除する方法任意のアイデアが...それは何とかルートになったブランチのコミットの問題を引き起こしているもの... – bwoebi

+0

@bwoebiリポジトリに慣れていないので、ここで起こったことを私が視覚化するのは難しいです。あなたは、単に現在のルートがコミット削除したい場合は、[この質問](http://stackoverflow.com/questions/645450/git-how-to-insert-a-commit-as-the-first-を参照することができますすべてのコミットを新しい* empty * rootコミットに書き換える方法を示しています)。これで 'rebase -i'を使って古いルート(今度は2番目のコミット)を削除することができます。 – Chris

+1

まあ...それは助けにはなりませんでしたが、http://stackoverflow.com/a/6149972/2153758でした。とにかくありがとうございます...あなたは恩恵に値するでしょう。 – bwoebi

1

  • は元main
  • はそれをmainexternal
  • で起こったすべてのコミットを持参隔離

最初に、オリジナルを隔離するmain

おそらくmainが独自のリポジトリにあるようです。

オリジナルのmainがサブディレクトリexternal/mainを作成したコミットの親として設定されている場合は、externalリポジトリから取得できます。そのような例は、Git Book Subtree Merging pageに記載されているプロセスです。

導入されたサブツリーは、in this answerのように見つけられます。

そしてそれはちょうどmainの基底であるコミットの全体のセットをつかんでそれからリポジトリを作ることです。第二のために


externalで起こったすべてのコミットmainにそれを持参:あなたはすでにexteral/mainサブフォルダに変更を含むコミットを単離したが、あなたは状態として、それが含まれていません

元のmainがコミットします。

git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter main -- --all 

filter-branchが唯一のサブディレクトリを作成しread-treeような、より複雑な操作を処理する方法を知らなくても、特定のサブディレクトリの場所にファイルをチェックするためです。

filter-branch操作の後に、main/externalで発生したすべての変更を含むコミットセットが残ります。コミットのこのセットはfilteredMainブランチで到達できると仮定してください。

コンテンツがサブディレクトリからルートに移動されたので、ファイルの場所は今度はmainリポジトリの内容と同じになります。これにより、両方のツリーが結合されます。この2つのツリー、mainのマスターブランチとfilterBranchは共通の履歴がないので、コミットの変更を再生することによってrebaseに参加できます。この後filteredMain分岐がmainリポジトリ内の元master枝の上に再生external/mainに起こったすべての変更が含まれている必要があり

# in the main repository 

# bring the external repository and get the branch 
git remote add external /path/to/external 
git fetch external filteredMain 
git checkout filteredMain 

# We need the first commit of this tree for the rebase command 
firstCommit=$(git rev-list --max-parents=0 HEAD) 

# run the rebase 
git rebase --onto master $firstCommit filteredMain 

+0

は有効な代替のように見えますが、それは)lessコマンドであり、b)一つだけの枝の上に動作するものとして、実際に上記の答えははるかに実用的です。 – bwoebi

+0

私はこの問題を誤解しているかもしれません。なぜなら、 'main'コミットと' external/main'の両方を単一のツリーとして保持するために、単一の 'filter-branch'コマンドをどのように使うことができないのか分かりません。いずれにしても心配はありません。私はこの質問に対する回答が数日間、個人的な好奇心のためだけにあり、質問が終わってもそれを終えることに決めました。 – LopSae

関連する問題