Create a submodule repository from a folder and keep its git commit history Ask Question

Create a submodule repository from a folder and keep its git commit history Ask Question

I have a web application that explores other web applications in a particular way. It contains some web demos in a demos folder and one of the demo should now have it's own repository. I would like to create a separate repository for this demo application and make it a subpackage submodule from main repository without losing its commit history.

Is it possible to keep the commit history from the files in a repository's folder and create a repository from it and use it as a submodule instead?

ベストアンサー1

Detailed Solution

See the note at the end of this answer (last paragraph) for a quick alternative to git submodules using npm ;)

In the following answer, you will know how to extract a folder from a repository and make a git repository from it and then including it as a submodule instead of a folder.

Inspired from Gerg Bayer's article Moving Files from one Git Repository to Another, Preserving History

At the beginning, we have something like this:

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

In the steps below, I will refer this someLib as <directory 1>.

At the end, we will have something like this:

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

<git repository B>
    someFolders
    someFiles

Create a new git repository from a folder in an other repository

Step 1

Get a fresh copy of the repository to split.

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

Step 2

The current folder will be the new repository, so remove the current remote.

git remote rm origin

Step 3

Extract history of the desired folder and commit it

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>このフォルダーの履歴が 1 つだけ残るようにします。

これは、機密データの削除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

注記

これらすべてを行った後、私の場合は、ネプ代わりに自分の依存関係を管理します。gitのURLとバージョンを指定できます。依存関係としての package.json git URL

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

要約 (代替ソリューション)

使いやすくなるかもしれませんネプそしてGit URL で依存関係を管理する:

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

おすすめ記事