2016-07-18 9 views
1

gitで分離されたHEADについての私の理解:ブランチを作成せずに古いバージョンのコードをチェックアウトしました。新しいコードをコミットしようとすると、古いバージョンに戻るリンクを持つ新しいコミットが作成されますが、それはあなたの頭です。 「切り離された」部分は、新しいコミットの存在を示すブランチがないため、変更を失ったという事実を指します。新しいものをコミットすると、新しい新しい変更がログに表示されますが、古い変更は反映されません。うん、私は混乱している。イラスト:1エントリーのgit repoはどのようにして分離頭部状態になりますか?

A->B(HEAD) 
'git checkout A' 
A (DETACHED HEAD) 
'write a video game' 
'git commit' 
A->C(HEAD) 
/// And B is lost unless you know how to scour the raw git objects for trees 

今ここに私のレポのステータスです:

? git log --all --oneline --graph --decorate 
* 3c43b31 (HEAD, master) Original site files 

    ? git status 
HEAD detached at 3c43b31 
Untracked files: 
    (use "git add <file>..." to include in what will be committed) 

    page.html 
    page.css 

告白:「チェックアウトを」これは私が使用してコミット、既存のものに戻ってすべての私の変更を元に戻す試みた直後の状態です'checkout 3c43b31'を使用していますが、どちらもうまくいきませんでした。

質問:なぜHEADを取り外すのですか?唯一のコミットがあり、我々はそれに座っている。

質問:私のチェックアウトはなぜ機能しませんでしたか?

答えて

3

gitでHEADを分離したことについての理解:ブランチを作成せずにコードの古いバージョンをチェックアウトしました。

これは一種の権利です。技術的な詳細は間違っていますが、それはあなた自身の状況で問題になり始めます。

「デタッチヘッド」状態の正確な定義は、という名前がブランチ名を含むのではなく、特定のコミットIDへのポインタになります。

ブランチ名自体はです。特定のコミットIDへのポインタは常にです。この名前は、そのブランチのチップコミットを指しています(ちょっと愚かですが、これはチップコミットの定義なので、ブランチ名が指すものです)。それは次のとおりです。

A->B(HEAD) 

近いが、非常に適切ではありません。 masterに、HEADポイントです

   HEAD 
       | 
       v 
A <- B <-- master 

、およびBに(ないAへ)masterポイント:私たちが持っていることは代わりです。そして、それは後ろ向きですが(とにかく気をつける必要はほとんどありませんが)、2回目のコミットBは、最初のコミットAへのコミットを指します。少なくとも一つのコミットがあるたび

HEAD 
    | 
    v 
A <- B <-- master 

ので、これが発生する可能性があります(一部がにすべてのこれらの名前のコミットが必要である:独立した頭で

は、我々は単に直接コミットにHEADを指します指し示す)。

git checkoutコマンドは、HEADを設定するコマンドです。あなたはそれを頼む時:

git checkout master 

それがすべてでmaster自体を変更せずに、masterを指すようにHEADを設定します。しかし、古いコミットをチェックアウトするときのように、未処理のコミットID()または--detachフラグを与えるときは、HEADをブランチ名にする代わりにHEADにコミットを直接指すように設定します。再び

A (DETACHED HEAD) 
'write a video game' 
'git commit' 
A->C(HEAD) 
/// And B is lost unless you know how to scour the raw git objects for trees 
は、これは正しい、しかしすることはかなり近い矢印は(かなりマイナーである)他の方法を指し、そして Bmasterので、(これはかなり大きなある)すべてで失われていませんまだそれを指して:

B <-- master 
/
A 
    \ 
    C <-- HEAD 

問題は、今あなたがgit checkout masterを使用している場合、それが失われたとなっCをコミットしていることです。 (それを見つけるために秘密の場所がHEADためREFLOGであるが、これはまだkeisterの痛みである。)

あなたがこの状態にあるときは、git checkout -b newname、またはgit branch newnameを使用して、newnameという名前の新しいブランチを作成します。 Cをコミットするために指して:

B <-- master 
/
A 
    \ 
    C <-- newname 

HEADを行うには、当然のことながら、git checkout -bgit branchありを使用しての違い:

git checkout -b newname 

は、新しいブランチを指すようにHEADを変更します。名前を作成するためにgit branchを使用し

B <-- master 
/
A 
    \ 
    C <-- newname 
      ^
       | 
      HEAD 

が切り離さHEADの葉:

だから、
B <-- master 
/
A 
    \ 
    C <-- newname 
    ^
    | 
    HEAD 

、再び、 "デタッチHEAD" は、単にストレートに」HEADポイントを意味し、最初に支店名を迂回することなくコミットしてください。 "

1

一般にgit checkout <sha1>は、取り外したHEADを作成します。分離されたHEADを名前のないブランチと見なすことができます。 git rebase --onto <sha1> <sha1A> <sha1B>のような他のコマンドは、このコマンドがgit checkout <sha1B>を内部的に実行するため、HEADを分離する可能性があります。

あなたの場合、Bは失われません。あなたが支店にいる場合は、git checkout <branch>を実行して復元することができます。切り離されたHEADは名前のないブランチであり、Bを指す前のブランチはまだそこにあるので、git checkoutを使用してこれらの2つのブランチを切り替えることができます。離されたHEADにいた場合はgit reflogまたはgit log -gを実行してBのsha1 backを見つけることができます。

関連する問題