1. ホーム
  2. git

[解決済み] あるブランチを別のブランチに似せるための git コマンド

2023-04-15 07:58:48

質問

あるブランチに変更を加え、それを分岐した上流と同じに戻そうとしています。変更は両方ともローカルで、github にプッシュされているので、どちらも git reset でも git rebase は本当に実行可能なのでしょうか?なぜなら、履歴を変更してしまうからです。これは、すでにプッシュされているブランチではまずいことです。

また、私は git merge を試してみましたが、どれもローカルの変更を元に戻すことはできませんでした。つまり、私がファイルを追加した場合、マージによって他のファイルを元の位置に戻すことができますが、上流にはないファイルがまだ残っています。

上流から新しいブランチを作成することもできますが、改訂履歴の観点から、私のブランチを取って再び上流と同一にするためにすべての変更を適用するマージが本当に欲しいのです。そのようなコマンドまたは一連のコマンドはありますか?

どのように解決するのですか?

上流のブランチを自分の dev ブランチにマージすることができます。 カスタムマージドライバ "keepTheirs" :

"を参照してください。 " git merge -s theirs " が必要です - しかし、それが存在しないことを知っている "。

あなたの場合、たった一つの .gitattributes が必要であり keepTheirs のようなスクリプトが必要です。

mv -f $3 $2
exit 0


git merge --strategy=theirs シミュレーション#1

上流を最初の親とするマージとして表示されます。

Jefromi が(コメントで)言及している merge -s ours を使用すると、上流(または上流から始まる一時的なブランチ)で自分の作業をマージし、そのマージ結果に自分のブランチを早送りすることができます。

git checkout -b tmp origin/upstream
git merge -s ours downstream         # ignoring all changes from downstream
git checkout downstream
git merge tmp                        # fast-forward to tmp HEAD
git branch -D tmp                    # deleting tmp

これは、上流の先祖を最初の親として記録するという利点があり、そのため mergeは、"このトピックブランチを破棄して上流に置き換える"ではなく、"この古くなったトピックブランチを吸収する"を意味します。 .

(2011年編集)。

このワークフローは、以下のように報告されています。 のブログ記事で報告されています。 :

<ブロッククオート

なんでまたこんなの欲しいんだろう?

私のレポが公開バージョンと何の関係もない限り、これはすべて問題ありませんでした。しかし、他のチームメンバーや外部の貢献者と WIP で照合する機能が必要になったので、私の公開ブランチを他の人がブランチしてプルできるように信頼性を確保したいのです。

ということで、どのように進めるべきかということになります。

99%の時間、私のコピーは上流のマスターに入るので、私は自分のマスターを作業し、ほとんどの時間上流にプッシュしたいです。

しかし、たまに、私が持っているものは wip にあるものが上流に行くにつれて無効になり、私は自分の wip .

その時点で、私は自分のマスターを上流と同期させたいのですが、公にプッシュされたマスターのコミットポイントを破壊することはありません。すなわち、私のコピーを上流と同一にする変更セットで終わる上流とのマージが欲しいのです。 .

そして、それは git merge --strategy=theirs はそうすべきなのです。


git merge --strategy=theirs シミュレーション#2

私たちのものを最初の親として、マージとして表示されます。

(提案者 jcwenger )

git checkout -b tmp upstream
git merge -s ours thebranch         # ignoring all changes from downstream
git checkout downstream
git merge --squash tmp               # apply changes from tmp but not as merge.
git rev-parse upstream > .git/MERGE_HEAD #record upstream 2nd merge head
git commit -m "rebaselined thebranch from upstream" # make the commit.
git branch -D tmp                    # deleting tmp


git merge --strategy=theirs シミュレーション#3

これは のブログ記事で触れています。 :

git merge -s ours ref-to-be-merged
git diff --binary ref-to-be-merged | git apply -R --index
git commit -F .git/COMMIT_EDITMSG --amend

このようなことをしたいと思うこともあるでしょうし、自分の経歴に"cunk"があるからというわけでもないでしょうが おそらく、リベースが避けられるはずの公開リポジトリで、開発のためにベースラインを変更したいからでしょう。 .


git merge --strategy=theirs シミュレーション #4

(同じブログ記事)

<ブロッククオート

あるいは、ローカルの上流ブランチを早送りできるようにしておきたい場合、妥協案として、sid/unstableでは、上流ブランチは時折リセット/リベースされる可能性があることを理解して作業することが考えられます(最終的に上流プロジェクト側では制御できない事象に基づいています)。

これは大きな問題ではなく、この前提で作業することで、ローカルの上流ブランチを早送りのみの更新を行う状態に保つことが容易になります。

git branch -m upstream-unstable upstream-unstable-save
git branch upstream-unstable upstream-remote/master
git merge -s ours upstream-unstable
git diff --binary ref-to-be-merged | git apply -R --index --exclude="debian/*"
git commit -F .git/COMMIT_EDITMSG --amend


git merge --strategy=theirs シミュレーション #5

(提案者 バラク・A・パールムター ):

git checkout MINE
git merge --no-commit -s ours HERS
git rm -rf .
git checkout HERS -- .
git checkout MINE -- debian # or whatever, as appropriate
git gui # edit commit message & click commit button


git merge --strategy=theirs シミュレーション#6

(提案者:同 マイケル・ゲベツローザー ):

<ブロッククオート

Michael Gebetsroither は、私が "cheating" していると主張し、より低レベルの配管コマンドによる別の解決策を示しました。

(git のみのコマンドで可能でなければ git ではない。git の diff/patch/apply のすべては本当の解決策ではない ;).

# get the contents of another branch
git read-tree -u --reset <ID>
# selectivly merge subdirectories
# e.g superseed upstream source with that from another branch
git merge -s ours --no-commit other_upstream
git read-tree --reset -u other_upstream     # or use --prefix=foo/
git checkout HEAD -- debian/
git checkout HEAD -- .gitignore
git commit -m 'superseed upstream source' -a


git merge --strategy=theirs シミュレーション 第7回

<ブロッククオート

必要な手順は、次のように記述できます。

  1. ワークツリーをアップストリームに置き換える
  2. インデックスに変更を適用する
  3. アップストリームを第二の親として追加
  4. コミット

コマンド git read-tree はインデックスを別のツリーで上書きし、次のことを実現します。 第二段階 を達成し、作業木を更新するフラグを持っています。 第一段階 . コミットするとき、git は .git/MERGE_HEAD にある SHA1 を第二の親として使用するので、マージコミットを作成するためにこれを入力することができます。 したがって、これは次のように実現できます。

git read-tree -u --reset upstream                 # update files and stage changes
git rev-parse upstream > .git/MERGE_HEAD          # setup merge commit
git commit -m "Merge branch 'upstream' into mine" # commit