コミットされた(プッシュされていない)変更をプル後に新しいブランチに移動する


460

私はかなりの作業を行いました(「あなたのブランチは37回のコミットで 'origin / master'の前にあります。」)master。これらのコミットは私のローカルマシンにのみ存在し、にプッシュされていませんがorigin、他の開発者がプッシュしていて、origin/masterこれらの変更をプルしたため、状況は多少複雑です。

37個のローカルコミットを遡って新しいブランチに移動するにはどうすればよいですか?ドキュメントに基づいて、これを行うgit rebase --onto my-new-branch masterか、または...origin/master行う必要があるようですが、どちらも「致命的:単一のリビジョンが必要です」というエラーを表示します。 man git-rebaseはリビジョンを提供することについて何も述べておらずrebase、その例はそうではないので、このエラーを解決する方法がわかりません。

これがあること(注ないの複製既存の移動、Gitリポジトリの新しいブランチにコミットされていない作品、別のGitのブランチに私の地元のコミットされていない変更をマージする方法は?これらの質問は、ローカルの作業ツリー内のコミットされていない変更、いない変化に対応として、ローカルでコミットされました。)


このソリューションを確認してください。簡単で清潔なようです。
トニー

このソリューションを確認してください。簡単で清潔なようです。
トニー

回答:


518

まだ他のどこにもコミットをプッシュしておらず、ブランチの履歴を後で自由に書き換えることができるため、これで問題ありませんorigin/master。最初にa git fetch originを実行して、それorigin/masterが最新であることを確認します。現在を使用しているとすると、次のことmasterができるはずです。

git rebase origin/master

...ここではない、あなたのコミットの全て再生しますorigin/masterの上をorigin/master。rebaseのデフォルトのアクションは、マージコミット(たとえば、git pullおそらくsが導入したもの)を無視することで、各コミットによって導入されたパッチをに適​​用しようとしますorigin/master。(途中でいくつかの競合を解決する必要がある場合があります。)次に、結果に基づいて新しいブランチを作成できます。

git branch new-work

...次にmaster背中をリセットしますorigin/master

# Use with care - make sure "git status" is clean and you're still on master:
git reset --hard origin/master

枝を操作し、この種のを行うときgit branchgit resetなど、私はそれが有用頻繁に見に見つけると、グラフコミットgitk --allまたは同様のツール、ちょうどすべての異なるレフリーが指している場所を私は理解していることを確認するために。

または、マスターが最初にどこにあるかに基づいてトピックブランチを作成し(git branch new-work-including-merges)、master上記のようにリセットすることもできます。ただし、トピックブランチにはからのマージが含まれてorigin/masterおり、まだ変更をプッシュしていないため、履歴を整理するためにリベースを行うことをお勧めします。(また、最終的にトピックブランチをマージしてマスターに戻すと、変更がより明確になります。)


8
@オリー:いいえ、答えは質問の仮定と私が答えの上部に示した仮定の下では正しいです。別の新しいブランチにあるはずのコミットはすでににありmasterます。リベースは書き換えmaster新しいコミットが上に直線状になるように分岐しorigin/master、その後、git branch new-work作成new-workの先端に分岐ポインティングmaster(現在の分岐)せずに現在のブランチを切り替えますnew-work。だから今new-workはすべての新しいコミットが含まれています。次に、リセットにより現在のブランチが(まだmaster)に戻りorigin/masterます。
Mark Longair

1
@Quintesse:失業してすみませんでしたが、元の質問者が述べた状況に対してこの回答が正しいと確信しています。(私はOlieの発言に返信したところ、うまくいけば明確化します。)とにかく、あなたの仕事を取り戻すのに役立つ場合に備えて、あなたの仕事が過去数日以内にコミットされた場合(この質問と回答の仮定の1つ) )git reflogで簡単に取得できるはずです。
Mark Longair、2015年

5
@Olie:おそらくより良い説明方法:gitのブランチは、特定のコミットを指すラベルと同じです。そのブランチ上で作成した場合、またはgit reset他のさまざまな方法で移動できる場合、それらは自動的に新しいコミットに移動されます。これgit branch new-workは、「現在のブランチ(この場合はマスター)にとどまっている間に、このコミットを指すブランチを作成する」と言っているだけです。したがって、コミットをマスターから新しいブランチに移動するコマンドを用意する必要はありません。そこで新しいブランチを作成し、マスターをリセットすると、新しいブランチはマスターがいた場所に残ります
Mark Longair

1
パーティーには少し遅れますが、@ Olie、新しいブランチでのgitステータスがmasterの前にコミットを表示しないからといって、実際にはコミットがそこにないわけではありません(それが理由であなたが心配していたと仮定します)。原点に新しいブランチをプッシュしてみてください。あなたがコミットがあるでしょう
フェリックス・ガニオン-グルニエ

2
@FélixGagnon-Grenier、「後期」について心配する必要はありません。古い質問を探している人が常にいて、すべての明確化が役立ちます。ありがとう!:)
Olie

148

コミット数が少なく、これらが1つのメガコミットに結合されているかどうかを気にしない場合、これはうまく機能し、実行するほど恐ろしくありませんgit rebase

ファイルをアンステージします(1をコミット数で置き換えます)

git reset --soft HEAD~1

新しいブランチを作成する

git checkout -b NewBranchName

変更を追加

git add -A

コミットする

git commit -m "Whatever"

5
わかりやすいグラフを表示するには、を使用してくださいgit log --all --decorate --oneline --graph
EliuX 2018年

こんにちは@EliuX-ここには関連性がありません。拡張できますか?
Stachu

これは、あなたがしたことで望んだ結果を得たかどうかを確認するのに役立ちます
EliuX

4
ありがとう!!これは非常にシンプルなソリューションであり、完全に機能しました!!
Chris Sim、

91

私は同じ問題で立ち往生しました。私は共有したい最も簡単な解決策を見つけました。

1)変更を加えた新しいブランチを作成します。

git checkout -b mybranch

2)(オプション)リモートサーバーに新しいブランチコードをプッシュします。

git push origin mybranch

3)マスターブランチにチェックアウトします。

git checkout master

4)リモートサーバーでマスターブランチコードをリセットし、ローカルコミットを削除します。

git reset --hard origin/master

10
これが本当に最も簡単な方法です
18

4
ステップ2は省略できます。私は、トップの回答以降、gitが変更され、この手順が以前は許可されていなかったと思います。
セバスチャン

これは私の意見では最良の答えです。
Macindows

1
この答えはトップに移動する必要があります。ありがとうございました。
アミット

27

もう1つの方法は、branch1-コミットされた変更を含むブランチであるbranch2-望ましいブランチであると仮定します

git fetch && git checkout branch1
git log

移動する必要があるコミットIDを選択します

git fetch && git checkout branch2
git cherry-pick commit_id_first..commit_id_last
git push

最初のブランチからプッシュされていないコミットを元に戻す

git fetch && git checkout branch1
git reset --soft HEAD~1

5
チェリーピックは本当に最高の「単一のコミットのコピー/移動」コマンドです。歴史があなたの目的のための荷物であるとき。
John Neuhaus

これは、これまでのところ、質問に対する最も便利な回答です。コマンドありがとうございます!
ファラー

1またはnがプッシュされていないコミットの数である最後のコメントを更新できますか?これは、まだこの質問に対して本当に良い解決策です。
chAlexey

9

または、間違ったブランチにコミットした直後に、次の手順を実行します。

  1. git log
  2. git diff {previous to last commit} {latest commit} > your_changes.patch
  3. git reset --hard origin/{your current branch}
  4. git checkout -b {new branch}
  5. git apply your_changes.patch

ステップ1と2にはより簡単なアプローチがあると想像できます。


6

何について:

  1. 現在のHEADから分岐します。
  2. 新しいブランチではなく、masterにいることを確認してください。
  3. git reset 変更を始める前の最後のコミットに戻ります。
  4. git pull リセットで破棄したリモートの変更だけを再度プルするには、

それとも、ブランチを再度マージしようとすると爆発しますか?


2
ああ、これは基本的に上記の@ Mark-Longairで説明されているオプションBです
Tim Keating

2

これははるかに簡単な方法です:

  1. 新しいブランチを作成する

  2. 新しいブランチでa- git merge masterこれはコミットされた(プッシュされていない)変更を新しいブランチにマージします

  3. ローカルマスターブランチgit branch -D masterを削除するブランチを強制的に削除するので、-D代わりにを使用し-dます。

  4. git fetchmasterブランチでa を実行し、masterブランチでaを実行git pullするだけで、チームに最新のコードを確実に提供できます。


1

私が使用しているより単純なアプローチ(4つのコミットを移動したい場合):

git format-patch HEAD~4

(最後のコマンドを実行したディレクトリから4つの.patchファイルを探します)

git reset HEAD~4 --hard

git checkout -b tmp/my-new-branch

次に:

git apply /path/to/patch.patch

好きな順番で。


0
  1. ソースの新鮮なコピーをチェックアウト

    git clone ........

  2. 希望の位置から分岐する

    git checkout {position} git checkout -b {branch-name}

  3. リモートリポジトリを追加

    git remote add shared ../{original sources location}.git

  4. リモートソースを取得する

    git fetch shared

  5. チェックアウトしたいブランチ

    git checkout {branch-name}

  6. ソースをマージ

    git merge shared/{original branch from shared repository}


0

私にとってこれは最良の方法でした:

  1. 変更を確認して競合をマージする git fetch
  2. 新しいブランチgit branch my-changesを作成してリモートにプッシュする
  3. 上流を新しく作成されたブランチに変更する git master -u upstream-branch remotes/origin/my-changes
  4. コミットを新しい上流ブランチにプッシュします。
  5. 前のアップストリームに切り替えます git branch master --set-upstream-to remotes/origin/master
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.