web-dev-qa-db-ja.com

履歴を保持しながら、ファイルをあるgitリポジトリから別の(クローンではなく)リポジトリに移動する方法

私たちのGitリポジトリは、個々のプロジェクトがそれぞれ独自のツリーを持つような単一のモンスターSVNリポジトリの一部として始まりました。

project1/branches
        /tags
        /trunk
project2/branches
        /tags
        /trunk

明らかに、svn mvを使ってファイルを移動するのはとても簡単でした。しかしGitでは、各プロジェクトはそれ自身のリポジトリにあり、そして今日私はproject2からproject1にサブディレクトリを移動するように頼まれました。私はこのようなことをしました:

$ git clone project2 
$ cd project2
$ git filter-branch --subdirectory-filter deeply/buried/Java/source/directory/A -- --all
$ git remote rm Origin  # so I don't accidentally the repo ;-)
$ mkdir -p deeply/buried/different/Java/source/directory/B
$ for f in *.Java; do 
>  git mv $f deeply/buried/different/Java/source/directory/B
>  done
$ git commit -m "moved files to new subdirectory"
$ cd ..
$
$ git clone project1
$ cd project1
$ git remote add p2 ../project2
$ git fetch p2
$ git branch p2 remotes/p2/master
$ git merge p2 # --allow-unrelated-histories for git 2.9
$ git remote rm p2
$ git Push

しかし、それはかなり複雑に思えます。この種のことを一般的に行うためのより良い方法はありますか?それとも、私は正しいアプローチを採用しましたか?

これには、単に別のリポジトリの一部から新しいスタンドアロンリポジトリを作成するのではなく、履歴を既存のリポジトリにマージすることが含まれます( 前の質問のように )。

429
ebneter

うん、--subdirectory-filterfilter-branchを打つのがキーでした。あなたがそれを使ったという事実は本質的にもっと簡単な方法がないことを証明します - あなたはファイルの(名前を変えられた)サブセットだけに終わってしまいたかったので歴史を書き直すしかないのです。標準のコマンド(例:pull)は履歴を書き換えないので、これを実現するためにそれらを使用することはできません。

もちろん、細部を洗練することもできます - クローン作成や分岐のいくつかは厳密には必要ではありませんでした - しかし、全体的なアプローチは良いです!それはそれが複雑であることは残念ですが、もちろん、gitのポイントは歴史を書き換えやすくすることではありません。

52
Cascabel

あなたの歴史が正しければ、あなたはパッチとしてコミットを取り除き、それらを新しいリポジトリに適用することができます:

cd repository
git log --pretty=email --patch-with-stat --reverse --full-index --binary -- path/to/file_or_folder > patch
cd ../another_repository
git am < ../repository/patch 

または一行で

git log --pretty=email --patch-with-stat --reverse -- path/to/file_or_folder | (cd /path/to/new_repository && git am)

Exherboのドキュメント から取得)

255
Smar

あるGitリポジトリから別のGitリポジトリにファイルやフォルダを移動するためにさまざまな方法を試してみましたが、確実に機能すると思われる唯一の方法を以下に概説します。

ファイルまたはフォルダの移動元のリポジトリのクローン作成、そのファイルまたはフォルダのルートへの移動、Git履歴の書き換え、ターゲットリポジトリのクローン作成、履歴付きのファイルまたはフォルダのこのターゲットリポジトリへの直接コピーを行います。

ステージ1

  1. 次の手順でこのコピーに大きな変更を加えたため、リポジトリAのコピーを作成してください。プッシュしてはいけません。

    git clone --branch <branch> --Origin origin --progress \
      -v <git repository A url>
    # eg. git clone --branch master --Origin origin --progress \
    #   -v https://username@giturl/scm/projects/myprojects.git
    # (assuming myprojects is the repository you want to copy from)
    
  2. それにcd

    cd <git repository A directory>
    #  eg. cd /c/Working/GIT/myprojects
    
  3. 誤ってリモートから変更を加えないようにするために、元のリポジトリへのリンクを削除してください(例:プッシュ)。

    git remote rm Origin
    
  4. 履歴とファイルを調べて、ディレクトリ1にないものをすべて削除します。その結果、ディレクトリ1の内容がリポジトリAのベースに展開されます。

    git filter-branch --subdirectory-filter <directory> -- --all
    # eg. git filter-branch --subdirectory-filter subfolder1/subfolder2/FOLDER_TO_KEEP -- --all
    
  5. 単一ファイル移動のみの場合:残りの部分を調べて、目的のファイル以外のすべてを削除します。 (同じ名前の不要なファイルを削除してコミットする必要があるかもしれません。)

    git filter-branch -f --index-filter \
    'git ls-files -s | grep $'\t'FILE_TO_KEEP$ |
    GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
    git update-index --index-info && \
    mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE || echo "Nothing to do"' --Prune-empty -- --all
    # eg. FILE_TO_KEEP = pom.xml to keep only the pom.xml file from FOLDER_TO_KEEP
    

ステージ2

  1. クリーンアップステップ

    git reset --hard
    
  2. クリーンアップステップ

    git gc --aggressive
    
  3. クリーンアップステップ

    git Prune
    

これらのファイルをルートではなくディレクトリ内のリポジトリBにインポートすることができます。

  1. そのディレクトリを作る

    mkdir <base directory>             eg. mkdir FOLDER_TO_KEEP
    
  2. ファイルをそのディレクトリに移動します

    git mv * <base directory>          eg. git mv * FOLDER_TO_KEEP
    
  3. そのディレクトリにファイルを追加する

    git add .
    
  4. 変更を確定すると、これらのファイルを新しいリポジトリにマージする準備が整いました

    git commit
    

ステージ3

  1. まだ持っていない場合は、リポジトリBのコピーを作成してください。

    git clone <git repository B url>
    # eg. git clone https://username@giturl/scm/projects/FOLDER_TO_KEEP.git
    

    (FOLDER_TO_KEEPがコピー先の新しいリポジトリの名前であると仮定します)

  2. それにcd

    cd <git repository B directory>
    #  eg. cd /c/Working/GIT/FOLDER_TO_KEEP
    
  3. リポジトリBへのブランチとしてリポジトリAへのリモート接続を作成します。

    git remote add repo-A-branch <git repository A directory>
    # (repo-A-branch can be anything - it's just an arbitrary name)
    
    # eg. git remote add repo-A-branch /c/Working/GIT/myprojects
    
  4. このブランチ(移動したいディレクトリーのみを含む)からリポジトリーBに引き出します。

    git pull repo-A-branch master --allow-unrelated-histories
    

    Pullはファイルと履歴の両方をコピーします。注:プルの代わりにマージを使用できますが、プルの方がうまく機能します。

  5. 最後に、リポジトリAへのリモート接続を削除して、少しクリーンアップしたいと思うでしょう。

    git remote rm repo-A-branch
    
  6. プッシュするだけで、すべての設定は完了です。

    git Push
    
67
mcarans

this とても便利です。新しいレポジトリに適用されるパッチを作成するのはとても簡単な方法です。詳しくはリンク先のページをご覧ください。

それは3つのステップだけを含みます(ブログからコピーされた):

# Setup a directory to hold the patches
mkdir <patch-directory>

# Create the patches
git format-patch -o <patch-directory> --root /path/to/copy

# Apply the patches in the new repo using a 3 way merge in case of conflicts
# (merges from the other repo are not turned into patches). 
# The 3way can be omitted.
git am --3way <patch-directory>/*.patch

私が持っていた唯一の問題は私が一度にすべてのパッチを適用することができなかったということでした

git am --3way <patch-directory>/*.patch

Windowsでは、InvalidArgumentエラーが発生しました。だから私はすべてのパッチを次々に適用しなければなりませんでした。

21
anhoppe

ディレクトリ名をキープする

Subdirectory-filter(またはより短いコマンドgit subtree)はうまくいきますが、コミット情報からディレクトリ名を削除するので私にはうまくいきませんでした。私のシナリオでは、あるリポジトリの一部を別のリポジトリにマージし、履歴WITHフルパス名を保持したいだけです。

私の解決策は、ツリーフィルタを使用し、ソースリポジトリの一時的なクローンから不要なファイルやディレクトリを削除し、次にそのクローンから5つの簡単な手順でターゲットリポジトリに移動することでした。

# 1. clone the source
git clone ssh://<user>@<source-repo url>
cd <source-repo>
# 2. remove the stuff we want to exclude
git filter-branch --tree-filter "rm -rf <files to exclude>" --Prune-empty HEAD
# 3. move to target repo and create a merge branch (for safety)
cd <path to target-repo>
git checkout -b <merge branch>
# 4. Add the source-repo as remote 
git remote add source-repo <path to source-repo>
# 5. fetch it
git pull source-repo master
# 6. check that you got it right (better safe than sorry, right?)
gitk
6
Joachim Nilsson

この答えは git am に基づいて、そして例を使って段階的に提示された興味深いコマンドを提供します。

目的

  • いくつかまたはすべてのファイルをあるリポジトリから別のリポジトリに移動したいとします。
  • あなたは彼らの歴史を守りたいのです。
  • しかし、あなたはタグやブランチを維持することを気にしません。
  • 名前が変更されたファイル(および名前が変更されたディレクトリ内のファイル)の履歴は限られています。

手順

  1. を使用して電子メール形式で履歴を抽出する
    git log --pretty=email -p --reverse --full-index --binary
  2. ファイルツリーを再編成し、履歴内のファイル名の変更を更新します[オプション]
  3. git amを使って新しい履歴を適用する

1.電子メール形式で履歴を抽出する

例:file3file4およびfile5の履歴の抽出

my_repo
├── dirA
│   ├── file1
│   └── file2
├── dirB            ^
│   ├── subdir      | To be moved
│   │   ├── file3   | with history
│   │   └── file4   | 
│   └── file5       v
└── dirC
    ├── file6
    └── file7

一時ディレクトリの宛先を消去します

export historydir=/tmp/mail/dir  # Absolute path
rm -rf "$historydir"             # Caution when cleaning

リポジトリのソースを削除します

git commit ...           # Commit your working files
rm .gitignore            # Disable gitignore
git clean -n             # Simulate removal
git clean -f             # Remove untracked file
git checkout .gitignore  # Restore gitignore

各ファイルの履歴を電子メール形式で抽出する

cd my_repo/dirB
find -name .git -Prune -o -type d -o -exec bash -c 'mkdir -p "$historydir/${0%/*}" && git log --pretty=email -p --stat --reverse --full-index --binary -- "$0" > "$historydir/$0"' {} ';'

残念ながら、オプション--followまたは--find-copies-harder--reverseと組み合わせることはできません。これが、ファイルの名前が変更されたとき(または親ディレクトリの名前が変更されたとき)に履歴が切り捨てられる理由です。

変更後:電子メール形式の一時的な履歴

/tmp/mail/dir
    ├── subdir
    │   ├── file3
    │   └── file4
    └── file5

2.ファイルツリーを再編成し、履歴内のファイル名の変更を更新します[オプション]

この3つのファイルをこの別のリポジトリに移動するとします(同じリポジトリにすることができます)。

my_other_repo
├── dirF
│   ├── file55
│   └── file56
├── dirB              # New tree
│   ├── dirB1         # was subdir
│   │   ├── file33    # was file3
│   │   └── file44    # was file4
│   └── dirB2         # new dir
│        └── file5    # = file5
└── dirH
    └── file77

したがって、ファイルを再編成してください。

cd /tmp/mail/dir
mkdir     dirB
mv subdir dirB/dirB1
mv dirB/dirB1/file3 dirB/dirB1/file33
mv dirB/dirB1/file4 dirB/dirB1/file44
mkdir    dirB/dirB2
mv file5 dirB/dirB2

あなたの一時的な歴史は今です:

/tmp/mail/dir
    └── dirB
        ├── dirB1
        │   ├── file33
        │   └── file44
        └── dirB2
             └── file5

履歴内のファイル名も変更します。

cd "$historydir"
find * -type f -exec bash -c 'sed "/^diff --git a\|^--- a\|^+++ b/s:\( [ab]\)/[^ ]*:\1/$0:g" -i "$0"' {} ';'

注:パスとファイル名の変更を反映するように履歴を書き換えます。
 (つまり、新しいリポジトリ内の新しい場所/名前の変更)


3.新しい履歴を適用する

あなたの他のレポは:

my_other_repo
├── dirF
│   ├── file55
│   └── file56
└── dirH
    └── file77

一時履歴ファイルからコミットを適用します。

cd my_other_repo
find "$historydir" -type f -exec cat {} + | git am 

あなたの他のレポは今です:

my_other_repo
├── dirF
│   ├── file55
│   └── file56
├── dirB            ^
│   ├── dirB1       | New files
│   │   ├── file33  | with
│   │   └── file44  | history
│   └── dirB2       | kept
│        └── file5  v
└── dirH
    └── file77

コミットされたコミットの量を確認するにはgit statusを使用してください:-)

注:履歴はパスとファイル名の変更を反映するように書き直されました。
 (すなわち、前のリポジトリ内の場所/名前と比較)

  • 場所/ファイル名を変更するのにgit mvは必要ありません。
  • 全履歴にアクセスするためにgit log --followを使用する必要はありません。

特別なトリック:あなたのリポジトリの中で名前変更/移動されたファイルを検出する

名前が変更されたファイルを一覧表示するには

find -name .git -Prune -o -exec git log --pretty=tformat:'' --numstat --follow {} ';' | grep '=>'

その他のカスタマイズ:オプションgit logまたは--find-copies-harderを使用して、コマンド--reverseを完成させることができます。 cut -f3-と完全パターン '{。* =>。*}'を使用して最初の2つの列を削除することもできます。

find -name .git -Prune -o -exec git log --pretty=tformat:'' --numstat --follow --find-copies-harder --reverse {} ';' | cut -f3- | grep '{.* => .*}'
5
olibre

私がいつも使用しているものはここにあります http://blog.neutrino.es/2012/git-copy-a-file-or-directory-from-another-repository-preserving-history/ 。シンプルで速い.

スタックオーバーフロー標準に準拠するために、次の手順に従います。

mkdir /tmp/mergepatchs
cd ~/repo/org
export reposrc=myfile.c #or mydir
git format-patch -o /tmp/mergepatchs $(git log $reposrc|grep ^commit|tail -1|awk '{print $2}')^..HEAD $reposrc
cd ~/repo/dest
git am /tmp/mergepatchs/*.patch
4
Hugh Perkins

スクラッチに似たかゆみがあったこと(ある特定のリポジトリのいくつかのファイルについてだけですが)、このスクリプトは本当に役に立ちました: git-import

簡単に言うと、既存のリポジトリから、指定されたファイルまたはディレクトリ($object)のパッチファイルを作成します。

cd old_repo
git format-patch --thread -o "$temp" --root -- "$object"

これは新しいリポジトリに適用されます。

cd new_repo
git am "$temp"/*.patch 

詳細は見てください:

3
ViToni

これを試して

cd repo1

これは、言及されたもの以外のすべてのディレクトリを削除し、これらのディレクトリの履歴のみを保存します。

git filter-branch --index-filter 'git rm --ignore-unmatch --cached -qr -- . && git reset -q $GIT_COMMIT -- dir1/ dir2/ dir3/ ' --Prune-empty -- --all

今、あなたはあなたのgitリモコンにあなたの新しいレポを追加し、それにそれをプッシュすることができます

git remote remove Origin <old-repo>
git remote add Origin <new-repo>
git Push Origin <current-branch>

上書きする-fを追加

2
Chetan Basutkar

堅牢で再利用可能なもの(ワンコマンドアンドゴー+元に戻す機能)が欲しいので、次のbashスクリプトを書きました。何度か仕事をしてくれたので、ここで共有したいと思いました。

任意のフォルダ/path/to/foorepo1から/some/other/folder/barからrepo2に移動することができます(フォルダパスは同じでも異なっていてもよく、ルートフォルダからの距離は異なっていてもかまいません)。

入力フォルダー内のファイルに触れるコミットのみを対象とするため(ソースリポジトリのすべてのコミットを対象とするわけではありません)、すべてのフォルダーに触れられていない深くネストされたサブフォルダーを抽出すれば、かなり高速になります。コミット。

これは、古いリポジトリの履歴をすべて使って孤立したブランチを作成し、それをHEADにマージすることなので、ファイル名が衝突した場合でも機能します(そして、最後にマージを解決する必要があります)。 。

ファイル名の衝突がない場合は、最後にgit commitを実行してマージを完了させる必要があります。

欠点は、それに対応するためにGitHubで歓迎されているソースリポジトリ内のファイル名の変更(REWRITE_FROMフォルダーの外側)には追いつかないだろうということです。

GitHubリンク: git-move-folder-repos-keep-history

#!/bin/bash

# Copy a folder from one git repo to another git repo,
# preserving full history of the folder.

SRC_GIT_REPO='/d/git-experimental/your-old-webapp'
DST_GIT_REPO='/d/git-experimental/your-new-webapp'
SRC_BRANCH_NAME='master'
DST_BRANCH_NAME='import-stuff-from-old-webapp'
# Most likely you want the REWRITE_FROM and REWRITE_TO to have a trailing slash!
REWRITE_FROM='app/src/main/static/'
REWRITE_TO='app/src/main/static/'

verifyPreconditions() {
    #echo 'Checking if SRC_GIT_REPO is a git repo...' &&
      { test -d "${SRC_GIT_REPO}/.git" || { echo "Fatal: SRC_GIT_REPO is not a git repo"; exit; } } &&
    #echo 'Checking if DST_GIT_REPO is a git repo...' &&
      { test -d "${DST_GIT_REPO}/.git" || { echo "Fatal: DST_GIT_REPO is not a git repo"; exit; } } &&
    #echo 'Checking if REWRITE_FROM is not empty...' &&
      { test -n "${REWRITE_FROM}" || { echo "Fatal: REWRITE_FROM is empty"; exit; } } &&
    #echo 'Checking if REWRITE_TO is not empty...' &&
      { test -n "${REWRITE_TO}" || { echo "Fatal: REWRITE_TO is empty"; exit; } } &&
    #echo 'Checking if REWRITE_FROM folder exists in SRC_GIT_REPO' &&
      { test -d "${SRC_GIT_REPO}/${REWRITE_FROM}" || { echo "Fatal: REWRITE_FROM does not exist inside SRC_GIT_REPO"; exit; } } &&
    #echo 'Checking if SRC_GIT_REPO has a branch SRC_BRANCH_NAME' &&
      { cd "${SRC_GIT_REPO}"; git rev-parse --verify "${SRC_BRANCH_NAME}" || { echo "Fatal: SRC_BRANCH_NAME does not exist inside SRC_GIT_REPO"; exit; } } &&
    #echo 'Checking if DST_GIT_REPO has a branch DST_BRANCH_NAME' &&
      { cd "${DST_GIT_REPO}"; git rev-parse --verify "${DST_BRANCH_NAME}" || { echo "Fatal: DST_BRANCH_NAME does not exist inside DST_GIT_REPO"; exit; } } &&
    echo '[OK] All preconditions met'
}

# Import folder from one git repo to another git repo, including full history.
#
# Internally, it rewrites the history of the src repo (by creating
# a temporary orphaned branch; isolating all the files from REWRITE_FROM path
# to the root of the repo, commit by commit; and rewriting them again
# to the original path).
#
# Then it creates another temporary branch in the dest repo,
# fetches the commits from the rewritten src repo, and does a merge.
#
# Before any work is done, all the preconditions are verified: all folders
# and branches must exist (except REWRITE_TO folder in dest repo, which
# can exist, but does not have to).
#
# The code should work reasonably on repos with reasonable git history.
# I did not test pathological cases, like folder being created, deleted,
# created again etc. but probably it will work fine in that case too.
#
# In case you realize something went wrong, you should be able to reverse
# the changes by calling `undoImportFolderFromAnotherGitRepo` function.
# However, to be safe, please back up your repos just in case, before running
# the script. `git filter-branch` is a powerful but dangerous command.
importFolderFromAnotherGitRepo(){
    SED_COMMAND='s-\t\"*-\t'${REWRITE_TO}'-'

    verifyPreconditions &&
    cd "${SRC_GIT_REPO}" &&
      echo "Current working directory: ${SRC_GIT_REPO}" &&
      git checkout "${SRC_BRANCH_NAME}" &&
      echo 'Backing up current branch as FILTER_BRANCH_BACKUP' &&
      git branch -f FILTER_BRANCH_BACKUP &&
      SRC_BRANCH_NAME_EXPORTED="${SRC_BRANCH_NAME}-exported" &&
      echo "Creating temporary branch '${SRC_BRANCH_NAME_EXPORTED}'..." &&
      git checkout -b "${SRC_BRANCH_NAME_EXPORTED}" &&
      echo 'Rewriting history, step 1/2...' &&
      git filter-branch -f --Prune-empty --subdirectory-filter ${REWRITE_FROM} &&
      echo 'Rewriting history, step 2/2...' &&
      git filter-branch -f --index-filter \
       "git ls-files -s | sed \"$SED_COMMAND\" |
        GIT_INDEX_FILE=\$GIT_INDEX_FILE.new git update-index --index-info &&
        mv \$GIT_INDEX_FILE.new \$GIT_INDEX_FILE" HEAD &&
    cd - &&
    cd "${DST_GIT_REPO}" &&
      echo "Current working directory: ${DST_GIT_REPO}" &&
      echo "Adding git remote pointing to SRC_GIT_REPO..." &&
      git remote add old-repo ${SRC_GIT_REPO} &&
      echo "Fetching from SRC_GIT_REPO..." &&
      git fetch old-repo "${SRC_BRANCH_NAME_EXPORTED}" &&
      echo "Checking out DST_BRANCH_NAME..." &&
      git checkout "${DST_BRANCH_NAME}" &&
      echo "Merging SRC_GIT_REPO/" &&
      git merge "old-repo/${SRC_BRANCH_NAME}-exported" --no-commit &&
    cd -
}

# If something didn't work as you'd expect, you can undo, tune the params, and try again
undoImportFolderFromAnotherGitRepo(){
  cd "${SRC_GIT_REPO}" &&
    SRC_BRANCH_NAME_EXPORTED="${SRC_BRANCH_NAME}-exported" &&
    git checkout "${SRC_BRANCH_NAME}" &&
    git branch -D "${SRC_BRANCH_NAME_EXPORTED}" &&
  cd - &&
  cd "${DST_GIT_REPO}" &&
    git remote rm old-repo &&
    git merge --abort
  cd -
}

importFolderFromAnotherGitRepo
#undoImportFolderFromAnotherGitRepo
1
jakub.g

http://blog.neutrino.es/2012/git-copy-a-file-or-directory-from-another-repository-preserving-history/ からのインスピレーションを使って、私はこのPowershell関数を作成しました同じことをしてくれたことは、これまで私にとって非常にうまくいっています。

# Migrates the git history of a file or directory from one Git repo to another.
# Start in the root directory of the source repo.
# Also, before running this, I recommended that $destRepoDir be on a new branch that the history will be migrated to.
# Inspired by: http://blog.neutrino.es/2012/git-copy-a-file-or-directory-from-another-repository-preserving-history/
function Migrate-GitHistory
{
    # The file or directory within the current Git repo to migrate.
    param([string] $fileOrDir)
    # Path to the destination repo
    param([string] $destRepoDir)
    # A temp directory to use for storing the patch file (optional)
    param([string] $tempDir = "\temp\migrateGit")

    mkdir $tempDir

    # git log $fileOrDir -- to list commits that will be migrated
    Write-Host "Generating patch files for the history of $fileOrDir ..." -ForegroundColor Cyan
    git format-patch -o $tempDir --root -- $fileOrDir

    cd $destRepoDir
    Write-Host "Applying patch files to restore the history of $fileOrDir ..." -ForegroundColor Cyan
    ls $tempDir -Filter *.patch  `
        | foreach { git am $_.FullName }
}

この例の使用法

git clone project2
git clone project1
cd project1
# Create a new branch to migrate to
git checkout -b migrate-from-project2
cd ..\project2
Migrate-GitHistory "deeply\buried\Java\source\directory\A" "..\project1"

これが終わったら、マージする前にmigrate-from-project2ブランチのファイルを再編成することができます。

1
crimbo

問題のファイルのパスが2つのレポジトリで同じで、1つのファイルまたは少数の関連ファイルだけを持ってきたい場合は、git cherry-pickを使用するのが簡単な方法です。

最初のステップはgit fetch <remote-url>を使って他のリポジトリからのコミットをあなた自身のローカルリポジトリに持ってくることです。これはFETCH_HEADが他のリポジトリからのヘッドコミットを指しているままにします。他のフェッチを行った後でそのコミットへの参照を保持したい場合は、それにgit tag other-head FETCH_HEADというタグを付けます。

次に、そのファイルの初期コミット(存在しない場合)を作成するか、ファイルを他のリポジトリからの最初のコミットでパッチできる状態にするためのコミットを作成する必要があります。もしgit cherry-pick <commit-0>があなたが望むファイルを紹介したのであればcommit-0でこれを行うことができます、あるいはあなたは '手で'コミットを構築する必要があるかもしれません。初期コミットを変更する必要がある場合、チェリーピックオ​​プションに-nを追加します。

その後は、必要に応じてgit cherry-pickを使用して、-n後続のコミットを続けることができます。最も単純な場合(すべてのコミットがまさにあなたが望むものであり、きれいに適用される)、チェリーピックコマンドラインでコミットの完全なリストを与えることができます:git cherry-pick <commit-1> <commit-2> <commit-3> ...

0
Curt J. Sampson

私の場合は、自分が移行していたリポジトリを保存したり、以前の履歴を保存したりする必要はありませんでした。別のリモートから同じブランチのパッチを入手しました

#Source directory
git remote rm Origin
#Target directory
git remote add branch-name-from-old-repo ../source_directory

これら2つのステップで、私は他のリポジトリのブランチを同じリポジトリに表示することができました。

最後に、私は(私が他のリポジトリからインポートした)このブランチをターゲットリポジトリのメインラインに従うように設定しました。

git br --set-upstream-to=Origin/mainline

今はまるでそれが私が同じレポに対して押した別のブランチであるかのように振る舞いました。

0
Jason D