フォルダーからサブモジュールリポジトリを作成し、そのgitコミット履歴を保持する


111

他のWebアプリケーションを特定の方法で探索するWebアプリケーションがあります。demosフォルダーにはいくつかのWebデモが含まれており、デモの1つに独自のリポジトリが必要です。このデモアプリケーション用に別のリポジトリを作成し、それをサブパッケージ コミット履歴を失うことなく、メインリポジトリのサブモジュール

リポジトリのフォルダー内のファイルのコミット履歴を保持し、そこからリポジトリを作成してサブモジュールとして使用することはできますか?


ディレクトリ1をGitリポジトリAからGitリポジトリBに移動する方法を探していました。記事へのリンクを+1してください。
チェタバハナ2015

1

はい、これは確かに非常によく似ています。解決策は少し異なります。これを共有してくれてありがとう
GabLeRoux 2015年

回答:


191

詳細なソリューション

npmを使用したgitサブモジュールの簡単な代替方法については、この回答の最後にあるメモ(最後の段落)を参照してください;)

次の回答では、リポジトリからフォルダを抽出し、そこからgitリポジトリを作成して、フォルダではなくサブモジュールとして含める方法を説明します。

Gerg Bayerの記事「あるGitリポジトリから別のGitリポジトリへのファイルの移動、履歴の保持」に触発されました

最初は、次のようなものがあります。

<git repository A>
    someFolders
    someFiles
    someLib <-- we want this to be a new repo and a git submodule!
        some files

怒鳴るの手順では、私はこれを参照するsomeLibよう<directory 1>

最後に、次のようになります。

<git repository A>
    someFolders
    someFiles
    @submodule --> <git repository B>

<git repository B>
    someFolders
    someFiles

他のリポジトリのフォルダから新しいgitリポジトリを作成する

ステップ1

分割するリポジトリの新しいコピーを取得します。

git clone <git repository A url>
cd <git repository A directory>

ステップ2

現在のフォルダーが新しいリポジトリになるため、現在のリモートを削除します。

git remote rm origin

ステップ3

目的のフォルダの履歴を抽出してコミットします

git filter-branch --subdirectory-filter <directory 1> -- --all

これdirectory 1で、関連するすべてのコミット履歴を含むリポジトリのルートにあるファイルを含むgitリポジトリが作成されました。

ステップ4

オンラインリポジトリを作成し、新しいリポジトリをプッシュしてください!

git remote add origin <git repository B url>
git push

upstream最初のプッシュのブランチを設定する必要があるかもしれません

git push --set-upstream origin master

クリーン<git repository A>(オプション、コメントを参照)

我々は、(履歴ファイルとコミット)トレースを削除したい<git repository B>から<git repository A>一度だけあり、このフォルダの履歴そう。

これは、githubから機密データ削除することに基づいています。

新しいフォルダに移動し、

git clone <git repository A url>
cd <git repository A directory>
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch <directory 1> -r' --prune-empty --tag-name-filter cat -- --all

<directory 1>削除するフォルダに置き換えます。-r指定されたディレクトリ内で再帰的にそれを行います:) 今すぐにプッシュorigin/masterして--force

git push origin master --force

ボスステージ(下の注を参照)

作成サブモジュールをから<git repository B><git repository A>

git submodule add <git repository B url>
git submodule update
git commit

すべてが期待どおりに機能したかどうかを確認し、 push

git push origin master

注意

これをすべて行った後、私は自分の依存関係を管理するためにnpmを使用する方が適切であることに気づきました。git urlとバージョンを指定できます。package.jsongit urlsを依存関係として参照してください。

この方法で行う場合、要件として使用するリポジトリはnpmモジュールである必要があるため、package.jsonファイルが含まれている必要があります。そうしないと、次のエラーが発生しますError: ENOENT, open 'tmp.tgz-unpack/package.json'

tldr(代替ソリューション)

あなたはそれが簡単に使用することを見つけるかもしれNPMをしてgitのURLで依存関係を管理します

  • フォルダを新しいリポジトリに移動する
  • npm init両方のリポジトリ内で 実行する
  • npm install --save git://github.com/user/project.git#commit-ish依存関係をインストールしたい場所で実行する

39
手順「<git repository A>のクリーンアップ」は避けてください。これを行うと、履歴から古いバージョン/コミットを完全に復元/チェックアウトすることはできません。フォルダをgit rmしてサブモジュールを追加するだけです。したがって、古いコミットをチェックアウトするときは、完全に機能するコピーがあることを確認してください。
サイボット2014

cd someLibステップ2の前にすべきではありませんか?「現在のフォルダーが新しいリポジトリになる」と言いましたが、実際にはそうではありません。新しいリポジトリ(サブモジュール)はそのフォルダにあります。
Jago

1
確認:はい、複数のサブモジュールで機能します。詳細な回答をありがとうございました。また、npmを使用する必要はありませんでした。
Breno Inojosa、2015年

2
私が追加した情報についてrefs/original/...、ステップ3で作成された
エミール・バージェロン

6
:GitHubには、新しいリポジトリへのフォルダの抽出を達成する方法についての記事作ら help.github.com/articles/...
jrobichaud

9

@GabLeRouxによるソリューションはブランチと関連するコミットを押しつぶします。

これらすべての余分なブランチとコミットを複製して保持する簡単な方法:

1-このgitエイリアスがあることを確認してください

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'

2-リモートの複製、すべてのブランチのプル、リモートの変更、ディレクトリのフィルタリング、プッシュ

git clone git@github.com:user/existing-repo.git new-repo
cd new-repo
git clone-branches
git remote rm origin
git remote add origin git@github.com:user/new-repo.git
git remote -v
git filter-branch --subdirectory-filter my_directory/ -- --all
git push --all
git push --tags

3

GabLeRouxのソリューションgit lfsは、デタッチするディレクトリの下に大きなファイルがある場合を除いて、うまく機能します。その場合、ステップ3の後、すべての大きなファイルは、実際のファイルではなくポインタファイルのままになります。おそらく.gitattributes、フィルターブランチプロセスでファイルが削除されたことが原因と考えられます。

これを実現するために、私は次の解決策が私にとってうまくいくと思います:

cp .gitattributes .git/info/attributes

.gitattributes大きなファイルを追跡するためにどのgit lfsが使用するかを.git/ディレクトリにコピーして、削除されないようにします。

フィルターブランチが完了し.gitattributesたら、新しいリポジトリにgit lfsを使用する場合は、忘れずに元に戻す必要があります。

mv .git/info/attributes .gitattributes
git add .gitattributes
git commit -m 'added back .gitattributes'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.