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を確認します。


マスターの上でコミットしたところでマスターを "後方にマージ"したい場合(つまり、 masterHEADを指すようにしたい場合)、1つのライナーは次のようになります。

git checkout -B master HEAD
  1. それはすでに存在していても、 masterという名前の新しいブランチを作成します( masterを動かしていて、それが私たちが望むものです)。
  2. 新しく作成されたブランチは、あなたがいるHEADを指すように設定されています。
  3. 新しいブランチがチェックアウトされているので、後で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 HEADfatal: 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 HEADrefs/heads/master
    "master"というブランチがチェックアウトされます。
  • git rev-parse refs/heads/master yield 17a02998078923f2d62811326d130de991d1a95a
    そのコミットは、マスターブランチの現在のヒントまたは "ヘッド"です。
  • git rev-parse HEADもまた、 17a02998078923f2d62811326d130de991d1a95a生成17a02998078923f2d62811326d130de991d1a95a
    これが「象徴的な基準」であることを意味します。 他の参照によってオブジェクトを指し示します。
    (シンボリックリファレンスはもともとシンボリックリンクとして実装されていましたが、シンボリックリンクを持たないプラットフォームでも使用できるように、後で余分な解釈が可能なプレーンファイルに変更されていました)。

HEADrefs/heads/master17a02998078923f2d62811326d130de991d1a95a

HEADがデタッチされると、ブランチを経由して間接的に指すのではなく、直接コミットを指します。 分離されたHEADは、名前のないブランチ上にあると考えることができます。

  • git symbolic-ref HEADfatal: 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




git