チェックアウトせずにブランチポインターを別のコミットに移動する


760

チェックアウトしたブランチのブランチポインターを移動するには、git reset --hardコマンドを使用します。しかし、チェックアウトされていないブランチのブランチポインターを別のコミットを指すように移動する方法(追跡されたリモートブランチなど、他のすべてのものを保持する方法)


11
あなたがしたいことのように聞こえるのは、それが今から作成されたものとは異なるコミットからのブランチです。私の理解が正しければ、作成したいコミットから新しいブランチを作成してgit branch <branch-name> <SHA-1-of-the-commit>、古いブランチを使用してダンプしてみませんか?
yasouser 2011年

6
@yasouser-「マスター」ブランチをダンプするのが良い考えかどうかはわかりません。
Bulwersator 2013年

回答:


578

任意の参照に対してそれを行うことができます。これは、ブランチポインタを移動する方法です。

git update-ref -m "reset: Reset <branch> to <new commit>" refs/heads/<branch> <commit>

一般的な形式:

git update-ref -m "reset: Reset <branch> to <new commit>" <ref> <commit>

必要に応じて、reflogメッセージについてnitを選択できますbranch -f。1つは1つとは異なると思いますが、reset --hardこれは厳密にはどちらでもありません。


39
メッセージはどこに役立ちますか?どこに保存され、後で読む方法は?
Mot

4
注:これは、ベアリポジトリでは機能しません。ベアリポジトリでは、 'git branch -f master <commit>'を使用してブランチを更新する必要があります(以下の回答を参照)。
6月のロードス

37
私のように、誤ってrefs / heads / <branch>の代わりに<branch>を使用すると、.git / <branch>の.gitディレクトリに新しいファイルが作成され、次のようなメッセージが表示されます。 「refname 'master' is ambiguous」を操作しようとすると、.gitディレクトリからファイルを削除して修正できます。
David Minor

34
これがに勝る理由が十分に説明されていませんgit branch -f。具体的には、この方法は次のように見えます:(A)使いにくい(B)覚えにくい(C)より危険
Steven Lu

10
「任意の参照が正確に何を意味するか」-ブランチは、コミットを指す唯一の種類の参照ではありません。タグがあり、ブランチでもタグでもない任意のrefs / whatevs / myrefスタイルの参照を自分で作成することもできます。これが「より良い」かもしれないというスティーブン・ルーの質問にも答えると思います。ブランチを使用している場合は、branch -fが最も簡単であることに同意します。
アダムA

964
git branch -f <branch-name> <new-tip-commit>

24
または任意の参照文献について、git update-ref -m "reset: Reset <branch> to <new commit>" <branch> <commit>。(必要に応じて、reflogメッセージについてnitを選択できますbranch -f。1つは1つとは異なると思いますが、reset --hardこれは正確にはどちらでもありません。)
Cascabel

4
ジェフロミ、投票できるように別の答えを書いてください。:)
Mot

16
99%のケースを処理し、実際にドキュメントに準拠しているため、これはより良い答えです。git help branch「-f、--force <branchname>がすでに存在する場合は、<force>を<startpoint>にリセットします。-fを指定しないと、gitブランチは既存のブランチの変更を拒否します。」
AlexChaffee

12
私がやっていてgit branch -f master <hash>、それはfatal: Cannot force update the current branch.私が今何をしなければならないのかと私に伝えています、このコマンドを使用することを許可される前に他のランダムブランチをチェックしてください?
Qwertie 2014

20
これは、移動しようとしているブランチが現在のブランチ(HEADそれを指す)である場合は機能しません。
Vladimir Panteleev、2015

135

git reset --hardコミット参照を渡すこともできます。

例えば:

git checkout branch-name
git reset --hard new-tip-commit

私はこのようなことをやや頻繁にしています。

この歴史を想定して

$ git log --decorate --oneline --graph
* 3daed46 (HEAD, master) New thing I shouldn't have committed to master
* a0d9687 This is the commit that I actually want to be master

# Backup my latest commit to a wip branch
$ git branch wip_doing_stuff

# Ditch that commit on this branch
$ git reset --hard HEAD^

# Now my changes are in a new branch
$ git log --decorate --oneline --graph
* 3daed46 (wip_doing_stuff) New thing I shouldn't have committed to master
* a0d9687 (HEAD, master) This is the commit that I actually want to be master

これは、通常、HEADまたはHEAD ^を使用してブランチチップを前に戻すという点で最も理にかなっています。したがって、これは先にコミットを指定するために一貫しています。
justingordon 2014

11
作業ツリーがクリーンであればこれで問題ありません。段階的な変更または段階的でない変更がたくさんある場合はgit update-ref、上で説明したように行う方が良いでしょう。
有料オタク、

16
あなたの「答え」はすでに質問の一部ではないものを追加しないことに気づきましたか?– OPによると、チェックアウトされている場合はgit reset --hard ...、ここで繰り返す必要はありません。:-(
ロバート・シーマー

6
@ロバート:そう思わない。質問はそれをどのように使用するを言っていませんでした、そしてこれはそうします。そんなに探しに行かなくて良かったです。
Wilson F

7
@WilsonF、これをここで見つけて良かったかもしれませんが、質問にまったく答えていません。多分それはいくつかの他の質問の答えですが、ここでは間違っています。
Robert Siemer、2015

52

ディスカッションを充実させるために、myBranchブランチを現在のコミットに移動する場合は、2番目の引数を省略します-f

例:

git branch -f myBranch


rebaseDetached HEAD状態にいるとき、私は通常これを行います:)


13

gitk --all

  • 必要なコミットを右クリック
  • -> 新しいブランチを作成
  • 既存のブランチの名前を入力してください
  • その名前の古いブランチの置き換え確認するダイアログでReturnキーを押します。

既存のブランチを変更する代わりに再作成すると、追跡ブランチ情報が失われることに注意してください。(これは、リモートが1つだけあり、ローカルブランチがリモートの対応するブランチと同じ名前である単純なユースケースでは一般に問題ではありません。詳細についてはコメントを参照してください。この不利な点を指摘してくれた@mbdevplに感謝します。)

gitkダイアログボックスに3つのオプション(上書き、既存の変更、またはキャンセル)がある機能があったら、すばらしいでしょう。


あなたが通常私のようなコマンドライン中毒者でgit guiありgitk、git使用のサブセット用に非常にうまく設計されている場合でも、私は、それらの得意な分野(つまり、git guiでインデックスにハンクを選択的にステージング/アウトすること、およびコミットすること)を使用することを強くお勧めします(署名付きの行を追加するにはctrl-s、コミットするにはctrl-enter 。)

gitk いくつかのブランチを追跡しながら、アップストリームに送信するパッチシリーズに変更を整理したり、複数のブランチの途中にあるものを追跡する必要がある場合に最適です。

グラフィカルファイルブラウザーも開いていませんが、gitk / git guiが大好きです。


1
とても簡単!gitgからgitkに変換したばかりかもしれません。
Michael Cole

ただし、この方法では、追跡ブランチ情報は失われます。
mbdevpl 2017年

@mbdevpl:私は本当にgitのエキスパートではありません。私はあなたが何を意味しているのか理解していると思いますが、その影響は理解できません。私はこれをかなり頻繁に使用しましたが、それらのブランチをリモート上の同じ名前のブランチにプッシュすることができました。ブランチとそのリモート追跡ブランチの間の関連付けは何をしますか?
Peter Cordes 2017年


1
@PeterCordes Ineed、ブランチ名が一致しない場合は重要です。また、複数のリモートがある場合。また、gitプロンプトを使用してブランチのステータスを表示している場合は、追跡ブランチまでのコミット距離が表示されます(設定されている場合)。また、git status出力も影響を受けます。さらに、いくつかのケースではgit fetchgit pushあなたが追跡ブランチを設定しない場合は、明示的に指定せずに、リモート動作しません。すべてのケースについてはわかりませんが、私にとっての一般的な経験則は、作業の便宜とスピードのためには、ブランチを順番に追跡することをお勧めします。
mbdevpl 2017年

7

推奨される解決策git branch -f branch-pointer-to-move new-pointerTortoiseGit

  • 「Git Showログ」
  • 「すべてのブランチ」をチェック
  • ブランチポインターを移動する行で(new-pointer):
    • 右クリックして、「このバージョンでブランチを作成」
    • 「ブランチ」の横に、移動するブランチの名前を入力します(ブランチポインターから移動)
    • [ベースオン]で、新しいポインターが正しいことを確認します
    • 「力」をチェック
    • OK

ここに画像の説明を入力してください

ここに画像の説明を入力してください


4

正直なところ、このgit pushコマンドについて誰も考えなかったのには驚きました。

git push -f . <destination>:<branch>

ドット(。)はローカルリポジトリを参照します。宛先が「リモートの対応するオブジェクトの背後にある可能性があるため、-fオプションが必要になる場合があります。

このコマンドは変更をサーバーに保存するために使用されますが、結果はリモートブランチ(<branch>)をローカルブランチ(<destination>)と同じコミットに移動した場合とまったく同じです


-fローカルで何かを壊さないようにせずにこれを行うこともできます。たとえば、git fetch origin && git push . origin/develop:developチェックアウト不要のフェイルファストバージョンgit checkout develop && git pull --ff-only
btown

1

ファイルを開き、.git/refs/heads/<your_branch_name>そこに保存されているハッシュを、ブランチのヘッドを移動する場所に変更します。テキストエディタでファイルを編集して保存するだけです。変更するブランチが現在アクティブなブランチでないことを確認してください。

免責事項:おそらくお勧めできない方法ですが、仕事は成し遂げられます。


1
これが無秩序な方法なのか、邪悪な方法なのかはわかりません。🤔😉
キース・ラッセル

@KeithRussellは両方とも可能性があります:P
GuillermoGutiérrez

0

指し示したいコミットが現在のブランチよりも進んでいる場合(現在のブランチの最後のコミットを取り消したくない場合はそうであるはずです)、単に次のようにすることができます:

git merge <commit>

ブランチがチェックアウトされていない場合の対処について質問されました。
キースラッセル

エラーが発生しました。その場合git push . <commit>:<branch>、すでに提案されているように行うことができます。
ジャンポール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.