git - headとは - 分離されたHEADとマスター/起源を調和させるにはどうすればよいですか?
git headとは (17)
独自のブランチへの独立したコミットを取得する
単にgit checkout -b mynewbranch
実行します。
その後、 git log
実行すると、この新しいブランチでコミットがHEAD
になっていることがわかります。
私はGitの枝分かれの複雑さでは新しい。 私は常に1つのブランチで作業し、変更をコミットしてから、定期的にリモートの起点にプッシュします。
最近、どこかのファイルをリセットしてコミットステージングを解除し、その後最近のローカルコミットを取り除くためにrebase -i
を実行しました。 今私は理解していない状態です。
私の作業領域では、 git log
は、私が期待していたことを正確に示していgit log
私は行ってほしくないコミットと、そこに新しいものなど、正しい電車に乗っています。
しかし、私は遠隔のリポジトリに押し込んだばかりです。何が違うのですか?リベースで殺されたコミットのいくつかがプッシュされ、ローカルにコミットされた新しいコミットがそこにはありません。
私は「マスター/起源」はHEADから切り離されていると思いますが、その意味、コマンドラインツールで視覚化する方法、そしてそれを修正する方法について100%明確ではありません。
EclipseでEGitを使用している場合:マスターが主な開発ブランチであると仮定します
- ブランチに変更をコミットします。通常は新しいブランチに変更します
- その後、リモートからプル
- プロジェクトノードを右クリックし、チームを選択してから表示履歴を選択します
- マスターを右クリックし、チェックアウトを選択します
- もしEclipseがあなたに言うならば、ローカルのものとリモートのものの2つのマスターがあります。
その後、元のマスターに再接続できるはずです。
git checkout origin/master
を実行する代わりに
ちょうどgit checkout master
やる
git branch
があなたのgit branch
を確認します。
マスターの上でコミットしたところでマスターを "後方にマージ"したい場合(つまり、 master
がHEAD
を指すようにしたい場合)、1つのライナーは次のようになります。
git checkout -B master HEAD
- それはすでに存在していても、
master
という名前の新しいブランチを作成します(master
を動かしていて、それが私たちが望むものです)。 - 新しく作成されたブランチは、あなたがいる
HEAD
を指すように設定されています。 - 新しいブランチがチェックアウトされているので、後で
master
なります。
私はこれがサブリポジトリの場合には特に有用であることを発見しました。サブリポジトリは分離された状態になりがちです。
あなたがマスターブランチを持っていて、 "開発"するか、機能をやり直したいのであれば、
git checkout origin/develop
注: 起源を確認する/開発する 。
あなたは分離されたHEAD状態です。 あなたは見渡すことができ、実験的な変更を行い、それらをコミットすることができます。また、別のチェックアウトを実行してブランチに影響を与えることなく、この状態で行ったコミットを破棄することができます...
次に
git checkout -b develop
できます :)
これは完全に私のために働いた:
1. git stash
を使ってローカルの変更を保存する
変更を破棄したい場合
git clean -df
git checkout -- .
git cleanは、すべての未追跡ファイルを削除します(警告:.gitignoreで直接言及された無視されたファイルは削除されませんが、フォルダにある無視されたファイルは削除されます)。
2. git checkout master
をメインブランチに切り替えます(マスタを使用したいと仮定します)
3.マスターブランチからの最後のコミットを引き出すためにgit pull
4.すべてのgit status
を確認するためにgit status
を確認する
On branch master
Your branch is up-to-date with 'origin/master'.
クリスが指摘したように、私は次のような状況にあった
git symbolic-ref HEAD
はfatal: ref HEAD is not a symbolic ref
失敗しますfatal: ref HEAD is not a symbolic ref
しかし、 git rev-parse refs/heads/master
は回復できる場所からの良いコミットを指していました(私の場合は最後のコミットで、 git show [SHA]
それ以後、私は面倒なことをたくさんしましたが、固定されているように見えるのはちょうど、
git symbolic-ref HEAD refs/heads/master
頭がついている!
以下は私のために働いた(ブランチマスタのみを使用)。
git push origin HEAD:master
git checkout master
git pull
最初のものは、分離したHEADを遠隔地の原点にプッシュします。
2番目はブランチマスターに移動します。
3つ目は、ブランチマスタに接続されるHEADを回復します。
プッシュが拒否された場合、最初のコマンドで問題が発生する可能性があります。 しかしこれはもはや切り離された頭部の問題ではなく、切り離された頭部がいくつかの遠隔的な変化を認識していないという事実に関するものです。
最初に、 HEADが何であるか、それが分離されたときの意味を明確にしましょう。
HEADは、現在チェックアウトされているコミットの記号名です。 HEADがデタッチされていない場合(「通常の」状況:ブランチがチェックアウトされている)、HEADは実際にブランチの「ref」を指し、ブランチはコミットを指します。 したがって、HEADはブランチに「接続」されます。 新しいコミットを行うと、HEADが指し示すブランチは、新しいコミットを指すように更新されます。 HEADはブランチを指しているだけなので自動的に続きます。
-
git symbolic-ref HEAD
はrefs/heads/master
"master"というブランチがチェックアウトされます。 -
git rev-parse refs/heads/master
yield17a02998078923f2d62811326d130de991d1a95a
そのコミットは、マスターブランチの現在のヒントまたは "ヘッド"です。 -
git rev-parse HEAD
もまた、17a02998078923f2d62811326d130de991d1a95a
生成17a02998078923f2d62811326d130de991d1a95a
これが「象徴的な基準」であることを意味します。 他の参照によってオブジェクトを指し示します。
(シンボリックリファレンスはもともとシンボリックリンクとして実装されていましたが、シンボリックリンクを持たないプラットフォームでも使用できるように、後で余分な解釈が可能なプレーンファイルに変更されていました)。
HEAD
→ refs/heads/master
→ 17a02998078923f2d62811326d130de991d1a95a
HEADがデタッチされると、ブランチを経由して間接的に指すのではなく、直接コミットを指します。 分離されたHEADは、名前のないブランチ上にあると考えることができます。
-
git symbolic-ref HEAD
はfatal: ref HEAD is not a symbolic ref
失敗しますfatal: ref HEAD is not a symbolic ref
-
git rev-parse HEAD
結果は17a02998078923f2d62811326d130de991d1a95a
シンボリックリファレンスではないので、コミット自体を直接指し示す必要があります。
我々はHEAD
を持っている→ 17a02998078923f2d62811326d130de991d1a95a
分離されたHEADで覚えておくべき重要なことは、それが指し示すコミットが参照されていない場合(他のREFには到達できない)、別のコミットをチェックアウトするときに "ダングリング"になります。 結局のところ、このようなダンプのコミットは、ガベージコレクションプロセスによって省略されます(デフォルトでは、少なくとも2週間は保持され、HEADのreflogによって参照されることにより長く保持される可能性があります)。
1切り離されたHEADを使って "通常の"作業をするのはまったく問題ありません。あなたはreflogから履歴を削除しないようにするために何をしているのかを把握しておくだけです。
インタラクティブ・リベースの中間ステップは、分離されたHEADで実行されます(部分的にアクティブなブランチのreflogを汚染しないようにするため)。 完全なリベース操作を完了すると、元のブランチがリベース操作の累積結果で更新され、HEADが元のブランチに再接続されます。 私が推測することは、あなたがリベースプロセスを完全に完了したことはないということです。 これにより、リベース操作によって最後に処理されたコミットを指し示す分離されたHEADが残されます。
状況から回復するには、分離したHEADが現在ポイントしているコミットを指すブランチを作成する必要があります。
git branch temp
git checkout temp
(これら2つのコマンドは、 git checkout -b temp
と略記することができます)
これはあなたのHEADを新しいtemp
ブランチに再接続します。
次に、現在のコミット(とその履歴)を、正常に動作することが予想される通常のブランチと比較する必要があります。
git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp
(おそらく、ログオプションを試してみてください:add -p
、-- --pretty=…
ままにしてログメッセージ全体を見るなど)
あなたの新しいtemp
ブランチがうまくいくように見えたら、それを指すように(例えば) master
を更新したいかもしれません:
git branch -f master temp
git checkout master
(これら2つのコマンドは、 git checkout -B master temp
と略記することができます)
一時的なブランチを削除することができます:
git branch -d temp
最後に、再構築された履歴をプッシュしたいと思うでしょう:
git push origin master
リモートブランチを新しいコミットに「早送り」することができない場合(つまり、ドロップしたか、既存のコミットを書き直した場合や、そうでなければ少しの履歴を書き直した場合)、このコマンドの最後に--force
を追加する必要があるかもしれません)。
あなたがrebase操作の途中だったなら、おそらくそれをきれいにするべきです。 rebaseが進行中であったかどうかは、 .git/rebase-merge/
ディレクトリを調べて確認できます。 そのディレクトリを削除するだけで、進行中のリベースを手動でクリーンアップすることができます(たとえば、アクティブなリベース操作の目的とコンテキストを覚えていない場合など)。 通常はgit rebase --abort
を使用しますが、これはおそらく回避したいいくつかの余分な再設定を行います(HEADを元のブランチに戻して元のコミットに戻します)。 )。
現在のデタッチされたHEADをpushしたい場合(前にgit log
チェックしてください)、次のようにしてください:
git push origin HEAD:master
分離したHEADをマスターブランチに送信します。 pushが拒否された場合は、 git pull origin master
先に実行して、元の位置から変更を取得してください。 起点からの変更を気にせず、拒否された場合は、意図的なリベースを行い、origin / masterを現在分離しているブランチに置き換えたい場合は、強制的に( -f
)することができます。 以前のコミットにアクセスできなくなった場合は、 git reflog
を実行してすべてのブランチからの履歴を見ることができます。
マスターブランチに戻り、変更を保存するには、次のコマンドを実行します。
git rebase HEAD master
git checkout master
参照: Git: "現在、どのブランチにもありません。" 変更を維持しながら、ブランチに戻る簡単な方法はありますか?
私にとっては、地元の枝をもう一度削除するのと同じくらい簡単でした。なぜなら私は、私が押したがっているローカルなコミットがなかったからです。
だから私はした:
git branch -d branchname
そして、ブランチをもう一度チェックアウトする:
git checkout branchname
私の場合はgit status
を実行していましたが、私は自分の作業ディレクトリにいくつかの追跡されていないファイルがあることがわかりました。
rebaseを動作させるために、私は(私はそれらを必要としなかったので)それらをきれいにしなければならなかった。
私は今日、この問題を抱えていました。サブモジュールを更新しましたが、ブランチにはありませんでした。 私はすでにコミットしていたので、隠して、チェックアウトして、ぶら下げても動作しませんでした。 私は孤独な頭のコミットをチェリーピックアップしてしまった。 だから私がコミットした直後(プッシュが失敗したとき)、私はこうしました:
git checkout master
git cherry-pick 99fe23ab
私の思考は行きました:私は離れた頭の上にいますが、私はマスターになりたいです。 私の分離状態が主人公とあまり変わらないと仮定して、私がマスターにコミットを適用することができれば、私は設定されるだろう。 これはまさにチェリーピックがすることです。
私は今日この問題に遭遇し、私はそれを解決して解決したと確信しています:
git branch temp
git checkout master
git merge temp
私はこれを行う方法を見つけたとき私の仕事のコンピュータ上にあった、そして今私は私のパーソナルコンピュータで同じ問題に遭遇しています。 月曜日まで仕事用コンピュータに戻ってきて、私がどのようにしたかを正確に見るために待つ必要があります。
私は本当に愚かな状態になった、私は他の誰かがこの便利な見つけるだろう...しかし、
git ls-remote origin
0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b HEAD
6f96ad0f97ee832ee16007d865aac9af847c1ef6 refs/heads/HEAD
0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b refs/heads/master
私は結局それを修正した
git push origin :HEAD
私も同じ問題がありました。 私はgit stash
stashで自分の変更をgit stash
、以前のコミット(私はそれが原因だと思った)に地方の支店をハードリセットし、その後git pull
、私はその頭を今離していない。 あなたの変更をもう一度git stash apply
ためにgit stash apply
を忘れないでください。
git checkout checksum # You could use this to peek previous checkpoints
git status # You will see HEAD detached at checksum
git checkout master # This moves HEAD to master branch