ブランチベースを変更する


145

私はこのような木を持っています:

(commit 1) - master
                \-- (commit 2) - (commit 3) - demo
                                                \-- (commit 4) - (commit 5) - PRO

PROブランチをマスターに移動する必要があります

(commit 1) - master
                |-- (commit 2) - (commit 3) - demo
                \-- (commit 4) - (commit 5) - PRO

git rebase masterPROブランチから試してみましたが、何も起こりません。

明確にするために:私はマスターで作業していたので、製品のデモ(git checkout -b demoおよびいくつかのコミット)を行わなければなりませんでした。次に、誤ってデモから別のブランチを作成し(git checkout -b PRO一部のコミット)、今度はPROブランチをマスターに移動して、デモをそのまま残す必要があります。最後に、デモとPROの両方がマスターからハングします。


回答:


281

--ontoそのために使用します:

git rebase --onto newBase oldBase feature/branch

あなたのケースを考えると:

git checkout PRO # Just to be clear which branch to be on.
git rebase --onto master demo PRO

基本的には、すべてのコミットを後からdemoまで取りPRO、それらをmasterコミットにリベースします。


状況が逆の場合も、それは進むべき道ですか?==マスターの2番目のブランチから-bをチェックアウトしましたが、最初のブランチから実行したかったのです。つまりgit rebase --onto first-branch second-branch second-branch、構文は
わかり

1
その場合の@Fla、それはgit rebase --onto first-branch master second-branch
nVitius

9
私はこの読みガイド上を--onto、そして、彼らは私を助け書いたかgit rebase --onto newBase oldBase feature/branch
ゲイブ

@PhilipRego不正解です。私の例のorigin/newBaseようnewBaseに、ブランチの名前です。ローカルリポジトリに存在するブランチ(newBase)またはリモートリポジトリに存在するブランチ()にリベースするかどうかに依存しますorigin/newBase
loganfsmyth

@PhilipRegoこれらは独立したものではありません。newBaseはローカルブランチorigin/newBaseの名前であり、リモートブランチの名前です。どちらを使用するかは、リベースする対象によって異なります。それは、人が機能することと機能しないことではなく、彼らが別のものにリベースすることです。元の質問ではリモートについて言及されていないため、私の例でリモートを使用すると、尋ねられた質問と一致しません。
loganfsmyth

22

私はできる限り一般的になるよう努めます。まず、目的のブランチにいることを確認してください:

git checkout current-branch

次に、次のコマンドを使用します(new-base-branchは、新しいベースにしたいcurrent-base-branchブランチで、現在のベースであるブランチです)。

git rebase --onto new-base-branch current-base-branch

競合がない場合は、すばらしい-完了です。(ほとんどの場合)そうするなら、次に読んでください。

競合が発生する可能性があり、手動で解決する必要があります。Gitはcurrent-branchcurrent-base-branchとの間で「3ウェイマージ」を実行しようとしますnew-base-branch。大まかにこれはgitが内部でどのように動作するかです:

  1. Gitは最初に current-base-branchの上にnew-base-branch。競合があるかもしれません。手動で解決する必要があります。その後、通常はとをgit add .行いgit rebase --continueます。これにより、新しい一時的なコミットが作成されますtemp-commit-hash

  2. この後、Gitはにcurrent-branch基づいてリベースしますtemp-commit-hash。さらに競合が発生する可能性があるため、手動で解決する必要があります。完了したら、再び続行しgit add .git rebase --continueあなたがあなたを成功しリベースてきた後、current-branch上にnew-base-branch


注:失敗を始めた場合はgit rebase --abort、リベースプロセス中にいつでも行うことができ、開始点に戻ることができます。


rebase「:無効な上流の現在のベース・ブランチ"致命的」掲示などのコマンドは、私だけを与えます。また、現在のブランチの現在の親ブランチが何であるかをGITに通知する必要があるのはなぜですか?これをすでに知っているのではないでしょうか?
マットアーノルド

21

PROブランチにチェックアウトし、このブランチの最も古い(commit4)および最新の(commit5)コミットハッシュをコピーして、別の場所に貼り付けます。

$ git checkout PRO
$ git log            # see the commit history
# copy the oldest & latest commit-hash 

PROブランチを削除します(安全のためにバックアップを保持します)。PROから新しいブランチを作成してチェックアウトしますmaster

$ git branch PRO.bac    # create a new branch PRO.bac = PRO as backup

$ git checkout master
$ git branch -D PRO     # delete the local PRO branch
$ git checkout -b PRO   # create and checkout to a new 'PRO' branch from 'master'

前のブランチのコミットの範囲を新しいブランチに(cherry-pick)します。PROPRO

$ git cherry-pick commit4^..commit5   # cherry-pick range of commits
# note the '^' after commit4

ここで、すべて問題なければ、強制的にremote PROブランチにプッシュ(-f)し、ローカルPRO.bacブランチを削除します。

$ git log                  # check the commit history

$ git push -f origin HEAD  # replace the remote PRO by local PRO branch history
# git branch -D PRO.bac    # delete local PRO.bac branch

1

ブランチの削除と再作成を回避し、ブランチを切り替える必要をなくすために、リセットとスタッシュを使用するわずかに異なるアプローチがありました。

$ git checkout PRO
$ git reset commit4 # This will set PROs HEAD to be at commit 4, and leave the modified commit 5 files in ur working index
$ git stash save -m "Commit message"
$ git reset commit 3
$ git stash save -m "Commit message"
$ git reset master --hard
$ git stash pop
$ git stash pop
$ git push --force # force if its already been push remotely

コミットごとのコミットでブランチをリセットすることにより、基本的には一度にコミットを履歴にブランチする巻き戻しだけを行います。


4行目の「commit」と「3」の間のスペースを削除する必要がありますか?
Alexis Wilke
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.