別のgitリポジトリからコミットを選択することはできますか?


726

私は、最初の何も知らない別のgitリポジトリからのコミットが必要なgitリポジトリを使用しています。

通常HEAD@{x}、reflogのを使用してチェリーピックしますが、これ.gitはこのreflogエントリ(物理ディレクトリが異なる)を何も知らないため、どのようにチェリーピックすることができますか?

私は使用していgit-svnます。私の最初の分岐は、使用しているgit-svntrunkSubversionのレポの、そして次の分岐を使用しているgit-svnSubversionのブランチに。


2
これは、によって与えられた理由であるベン・リーこの質問に報奨金を開くために:「私は正しい答えではなく、受け入れ答えに賞に報奨金をつもりです私はそうすることを24 [時間]を待たなければなりません。」しかし、どれが「正しい答え」であるはずなのか、なぜ受け入れられた答えが「正しい」ものではないのか、私にはわかりません。

1
問題の性質が明確ではありません。これらの異なるレポはどのように関連していますか?1つは別のフォークですか?または、実際には2つの完全に独立した無関係なプロジェクトですか?

@Cupcake、受け入れられた答えは良好であり、明らかにOPを助けたので、受け入れられるべきです。「正しい」とは、私が本当に「自分に合った」ことを意味するだけです(コメントを判断すると、他の何人かの人々にも適切です)。私が賞金をあげたのは、受け入れられた答えと同じくらいの担当者に値するものだと思いました。
ベン・リー

回答:


557

他のリポジトリをリモートとして追加し、その変更を取得する必要があります。そこからコミットが表示され、チェリーピックすることができます。

そのように:

git remote add other https://example.link/repository.git
git fetch other

これで、すべての情報を簡単に入手できますgit cherry-pick

ここでのリモート操作の詳細:https : //git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes


1
git-svnを使用している場合はどうなりますか?私の最初のブランチはトランクのgit-svnを使用しており、次のブランチはブランチでgit-svnを使用しています(迅速な返信に感謝)
gitcoder182

1
Subversionリポジトリを最初に複製するときは、トランクだけでなくリポジトリ全体を複製してください。また--stdlayout、Subversionで標準のトランク/ブランチ/タグのレイアウトを使用している場合は、必ずgit-svnのオプションを使用してください。そうすると、Subversionブランチは単なるリモートgitブランチになります。
ヴィルヘルムテル、2011

33
Githubを使用している場合は、コミットURLに.patchを追加してパッチをプルし、それをで適用できgit am < d821j8djd2dj812.patchます。GH以外では、以下の代替回答で参照されているように、同様の概念を実行できます。
radicand

2
@radicand以下の「代替」の答えはどれですか?リンクしてください。

7
別のリポジトリからチェリーピックする詳細な手順:coderwall.com/p/sgpksw/git-cherry-pick-from-another-repository
T. Kim Nguyen

854

答えは、与えられたとおり、format-patchを使用することですが、問題は別のフォルダーからチェリーピックする方法だったので、これを行うコードの一部を次に示します。

$ git --git-dir=../<some_other_repo>/.git \
format-patch -k -1 --stdout <commit SHA> | \
git am -3 -k

@cong maからの説明)

このgit format-patchコマンドは、some_other_repoSHAで指定されたのコミットからパッチを作成します(-1単一のコミットのみ)。このパッチはにパイプされgit am、ローカルでパッチを適用します(-3つまり、パッチが正しく適用されない場合に3者間マージを試みます)。それが説明することを願っています。


18
これは適切ですが、誰かがこれを拡張できればすばらしいでしょう-何が起こっているかを正確に分析すること(特にこれらのフラグで)は非常に役立つでしょう。
ニックF

46
@NickF、git format-patchコマンドは、some_other_repoSHAで指定されたコミットからパッチを作成します(-11つの単一コミットのみ)。このパッチはにパイプされgit am、ローカルでパッチを適用します(-3つまり、パッチが正しく適用されない場合に3者間マージを試みます)。それが説明することを願っています。
コンマ14

3
エラー:パッチが失敗しました:somefile.cs:85エラー:somefile.cs:パッチが適用されませんパッチを手動で編集しましたか?インデックスに記録されているblobには適用されません。3者間マージにフォールバックできません。0001でパッチが失敗しましたGUIパーツが追加されました。失敗したパッチのコピーは次の場所にあります:<some_other_repo> /。git / rebase-apply / patchこの問題を解決したら、「git am --continue」を実行します。このパッチをスキップしたい場合は、代わりに「git am --skip」を実行してください。元のブランチを復元してパッチ適用を停止するには、「git am --abort」を実行します。
トム

8
@Tomを使ってみてください--ignore-whitespace。フルコマンド: git --git-dir=../<some_other_repo>/.git format-patch -k -1 --stdout <commit SHA> | git am -3 -k --ignore-whitespace
ジェイクグラハムアーノルド、

7
@BoomShadowの方が簡単だからです。リモートを追加してフェッチすると、他のすべてのリポジトリの変更が反映されます。このコマンドラインは1回限りのアクションです。
Jonathon Reinhart 2017年

152

これは、リモートフェッチマージの例です。

cd /home/you/projectA
git remote add projectB /home/you/projectB
git fetch projectB

次に、次のことができます。

git cherry-pick <first_commit>..<last_commit>

またはブランチ全体をマージすることもできます

git merge projectB/master

54
git merge projectB/master 非常に間違っています。チェリーピックのように単一のコミットからの変更を適用していないため、実際には自分のブランチに含まれていないすべての変更をマージしprojectB/masterていますmaster

4
これが元のポスターの意図だと私は思っていました。そうでなければ、はい、これは彼らにとって正しいオプションではありません。
ブライアン

5
2つのリポジトリが関連している場合、これは見事に機能します。
Ronny Ager-Wick 2014年

1
私はgitリポジトリからコピーを作成し(元のリポジトリを壊さずに「ただ遊ぶ」ため)、そのソースで最新に保つために、ブライアンからの答えはまさに私が必要とするものなので、カップケーキ、私は「間違っている」というわけではなく、別のユースケースです。しかし、潜在的な災害を指摘するのはあなたからうれしいです:D
ferrari2k

6
IMOこれは受け入れられるソリューションである必要があります。さらに、リモートからチェリーピックした後でリモートを削除する場合は、を使用しますgit remote rm projectB。またgit tag -d tag-name、リモートリポジトリから取得したタグを削除するためにも使用します。リモートコミットは履歴に表示されなくなり、プルーニングによって最終的にストレージから削除されます。
ADTC、2016

130

できますが、2つのステップが必要です。方法は次のとおりです。

git fetch <remote-git-url> <branch> && git cherry-pick FETCH_HEAD

<remote-git-url>チェリーピックするリポジトリのURLまたはパスに置き換えます。

<branch>リモートリポジトリから選択したいブランチまたはタグの名前に置き換えます。

FETCH_HEADブランチからgit SHAに置き換えることができます。

更新:@pkalinowのフィードバックに基づいて変更されました。


8
ブランチ名では機能しますが、SHAでは機能しません。ハッシュで示されたコミットをチェリーピックする場合は、代わりにこれを使用しますgit fetch <repo-url> <branch> && git cherry-pick <sha>
pkalinow 2014年

ありがとう。これは、この目的のために作成した、あるリポジトリから別のリポジトリに多数のコミットを挿入するために必要なものでした。
wojciii 2014

これは、さまざまなクライアント(それぞれが独自のリポジトリ/フォークを持っている)のためのコードの多くのカスタム実装で必要なものであり、ベース/トランクへの特定のコミットを取得する方法が必要でした。ありがとう!
RedSands 2016年

これは、複数のリポジトリにわたるワンショットチェリーピックで受け入れられる答えになるはずです。すでにローカルであるリポジトリ間を選択するときは常にそれを使用します。リモートURLはローカルファイルシステムパスにすぎません。
Amedee Van Gasse、

61

リモートを追加してブランチをフェッチし、コミットをチェリーピックする手順は次のとおりです

# Cloning our fork
$ git clone git@github.com:ifad/rest-client.git

# Adding (as "endel") the repo from we want to cherry-pick
$ git remote add endel git://github.com/endel/rest-client.git

# Fetch their branches
$ git fetch endel

# List their commits
$ git log endel/master

# Cherry-pick the commit we need
$ git cherry-pick 97fedac

出典:https : //coderwall.com/p/sgpksw


17

How to create and apply a patch with Gitを参照してください。(あなたの質問の文言から、私はこの他のリポジトリはまったく異なるコードベース用であると想定しました。それが同じコードベースのリポジトリである場合は、@ CharlesBによって提案されているようにリモートとして追加する必要があります。別のリポジトリ用であってもコードベース、それをリモートとして追加することはできますが、ブランチ全体をリポジトリに入れたくないかもしれません...)


11

次のように1行で実行できます。あなたがチェリーピックの変更を必要とするgitリポジトリにいて、ブランチを修正するためにチェックアウトしたことを願っています。

git fetch ssh://git@stash.mycompany.com:7999/repo_to_get_it_from.git branchToPickFrom && git cherry-pick 02a197e9533
# 

git fetch [ブランチURL] [ブランチからチェリーピックへ] && git cherry-pick [コミットID]


1
乾杯、ssh://パートは必要ありませんでしたhttps://
レオ

5

はい。リポジトリをフェッチし、リモートブランチからチェリーピックします。


1

Aチェリーピックするレポであり、チェリーピックするレポであるとすると、にB追加</path/to/repo/A/>/.git/objectsすることでこれを行うことができます</path/to/repo/B>/.git/objects/info/alternates。このalternatesファイルが存在しない場合は作成してください。

これにより、リポジトリBがリポジトリAのすべてのgitオブジェクトにアクセスできるようになり、適切な選択が可能になります。


0

私の状況は、チームがプッシュするベアリポジトリと、そのすぐ隣にあるそのクローンの状況です。Makefileの次の一連の行は、私にとっては正しく機能します。

git reset --hard
git remote update --prune
git pull --rebase --all
git cherry-pick -n remotes/origin/$(BRANCH)

ベアリポジトリのマスターを最新の状態に保つことにより、ベアリポジトリに公開された変更案を簡単に選択できます。また、レビューとテストを統合するために複数のブラケットをチェリーピックする(より複雑な)方法もあります。

「何も知らない」が「リモートとして使用できない」を意味する場合、これは役に立たないが、このワークフローを思いついて探していたので、このSOの質問が浮上したので、貢献したいと思った。


-nはgit docsによるとコミットなしを意味し、私はコミットを行う前に変更を確認することが非常に重要です
canbax

0

特定のコミットに到達するまで、特定のファイルの複数のコミットを選択したい場合は、以下を使用します。

# Directory from which to cherry-pick
GIT_DIR=...
# Pick changes only for this file
FILE_PATH=...
# Apply changes from this commit
FIST_COMMIT=master
# Apply changes until you reach this commit
LAST_COMMIT=...

for sha in $(git --git-dir=$GIT_DIR log --reverse --topo-order --format=%H $LAST_COMMIT_SHA..master -- $FILE_PATH ) ; do 
  git --git-dir=$GIT_DIR  format-patch -k -1 --stdout $sha -- $FILE_PATH | 
    git am -3 -k
done
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.