削除 - git ブランチ間 マージ




あるブランチを別のブランチとするためのgitコマンド (5)

私は変更を加えて分岐を取ってそれを分岐させた上流と同一に戻そうとしています。 変更はローカルでgithubにプッシュされているので、 git resetまたはgit rebaseどちらも歴史を変えるので実際に実行可能ではありません。これは、すでにプッシュされているブランチでは悪いことです。

私もgit mergeをさまざまな方法でgit mergeしようとしましたが、ローカルの変更を元に戻すことはできません。つまり、ファイルを追加した場合、マージによって他のファイルが改行される可能性がありますが、持っている。

アップストリームから新しいブランチを作成することはできますが、私は本当にリビジョン履歴の観点からすべての変更をブランチに適用してアップストリームと同じにするようにしたいので、その変更を安全に押し込むことができます歴史を壊さずに そのようなコマンドや一連のコマンドがありますか?


git merge -s theirs ref-to-be-mergedのもう1つのシミュレーションは、 git merge -s theirs ref-to-be-mergedれることをgit merge -s theirs ref-to-be-merged

git merge --no-ff -s ours ref-to-be-merged         # enforce a merge commit; content is still wrong
git reset --hard HEAD^2; git reset --soft [email protected]{1} # fix the content
git commit --amend

二重リセットの代わりに、逆パッチを適用することもできます。

git diff --binary ref-to-be-merged | git apply -R --index

カスタムマージドライバ "keepTheirs"を使用して、アップストリームブランチをdevブランチにマージできます。
" " git merge -s theirs "が必要ですが、それが存在しないことは分かります"を参照してください。
あなたの場合、1つの.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

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

(2011年編集):

このワークフローは、OPのブログ記事で報告されています。

なぜ私はこれをもう一度したいのですか?

私のレポがパブリックバージョンとは関係ない限り、これは問題ありませんでしたが、今では他のチームメンバーや外部の寄稿者とWIPでコロコード化できるようになりたいと考えています。私はリモートバックアップにプッシュしたものをリベースして再設定する必要がなくなりました。これは現在GitHubと一般公開されています。

そうすれば、私はどのように進めるべきかがわかります。
私のコピーが上流のマスターに入る時間の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

時々あなたはこれをやりたいと思っているのですが、あなたの歴史の中に「うんざり」があるわけではありませんが、 おそらくリベースを避けるべきパブリック・リポジトリの開発のベースラインを変更したいからです

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

Barak A. Pearlmutterによって提案された):

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によって提案された):

Michael Gebetsroitherは私が「不正行為をしている」と主張して)、低レベルの配管命令​​を備えた別の解決策を出しました:

(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 fetch origin
$ git merge origin/master -s recursive -Xtheirs

これは、あなたのローカルレポを原点と同期させ、履歴を保存します。


また、配管命令の助けを借りることのない方法もあります - IMHOは最も簡単です。 2つのブランチの "theirs"をエミュレートしたいとします。

head1=$(git show --pretty=format:"%H" -s foo)
head2=$(git show --pretty=format:"%H" -s bar)
tree=$(git show --pretty=format:"%T" -s bar)
newhead=$(git commit-tree $tree -p $head1 -p $head2 <<<"merge commit message")
git reset --hard $newhead

これは、任意の数のヘッド(上記の例では2)を、それらのうちの1つのツリーを使用してマージします(コミットツリーは低レベルのコマンドです。彼らは気にしない)。 頭はちょうど1になることができることに注意してください(チェリーピックと "自分の"と同等です)。

親の頭が最初に指定されていることは、いくつかのことに影響を与えることに注意してください(例えば、git-logコマンドの--first-parent参照)。

git-showの代わりに、ツリーやコミットハッシュを出力することができるものは何でも使用できます(cat-file、rev-list、...)。 あなたはコミットメッセージを対話的に美しくするためにgit commit --amendですべてを追跡できます。


重い手渡し、しかし、地獄、何が間違って行くことができますか?

  • あなたがYのように見せたいブランチXをチェックしてください
  • cp -r .git / tmp
  • ブランチYをチェックアウト
  • rm -rf .git && cp -r /tmp/git。
  • 差をコミットしてプッシュします
  • 完了しました。




branching-and-merging