私はブランチで作業しており、いくつかのコミットを元に戻す必要がありました。だから私はやった
$> git reset --hard bd53134
これは、頭が切り離されていることを除いて、望ましい効果がありました:(
$> git status
HEAD detached at bd53134
どうすればこれを修正できますか?
あなたはまだこれをいじっているように見えるので、ここに少し背景があります. あなたはコメントで、あなたが始めて、いつも不平を言っgit rebase
て立ち往生していたと述べました. git rebase --continue
(これは実際には元の質問の一部であったはずです。)
最初のメモ:HEAD
通常 (「切り離されていない」?) または「切り離された」可能性があります。「通常」HEAD
はブランチ名だけで構成されます。あなたが「支店にいる」場合はmaster
、HEAD
単に「支店長に」と言います。フランス革命の何かのように聞こえる「切り離された HEAD」は、生の SHA-1 コミット ID の代わりに構成されます。以下の図では、添付された HEAD を のように書きHEAD=branch
、矢印を使用して特定のコミットを指すように、分岐がどこを指しているかを示します。
リベースを開始する前に、次のようなコミット グラフがあります。
...- A - B - E - F <-- master, origin/master
\
C - D <-- HEAD=branch
この場合、私はあなたがgit checkout -b branch
fromを実行し、 (作成と) でmaster
いくつかのコミットを行い、その後おそらくandを実行して、コミットとfrom "リモート" を引き継いだと仮定しました。次に、(したがって)に戻りました。branch
C
D
git checkout master
git pull
E
F
origin
branch
git checkout branch
HEAD=branch
C
次に、とD
の上に両方をリベースする必要があると判断しF
、より直線的なコミット シーケンスを提供します。
...- A - B - E - F <-- master, origin/master
\
C' - D' <-- HEAD=branch
C'
(これらがandD'
の代わりにC
andである理由をすぐに示しますD
。) したがって、コミットをgit rebase master
「移動」して.C
D
master
Rebase は実際にはコミットを移動しません。それは、いくつかの既存のコミットをコピーして、「同じことを行い」、「同じくらい良い」新しいコミットを作成することです (私たちは願っています!)。したがって、リベースは維持されます。特別なラベル を使用して、コミットを追跡します(および、リベース操作全体のすべての進行状況を追跡するための一連の追加ファイル - 実際、これらのファイルは、リベースが「進行中」であることを git が認識する方法です)。C
D
ORIG_HEAD
D
.git/rebase-apply/
Rebase は、これORIG_HEAD
を追加して「HEAD をデタッチ」することでプロセスを開始します。リベースのターゲット (この場合はcommit ) を直接指すように「切り離された HEAD」を設定します。F
(調べてみると、ドキュメントはブランチをリセットすることについても少し嘘をついているようです。しかし、これは git の古いバージョンでは異なる場合があります。ドキュメントはある時点で正確だったと思います。)したがって:
...- A - B - E - F <-- master, origin/master
\ \
\ \...... HEAD [detached]
\
C - D <-- ORIG_HEAD, branch
次に、各コミット (C
およびD
ここ) に対して、コミットで行われた変更を取得し、それらの同じ変更をHEAD
コミットに適用しようとします。すべてがうまくいけば (通常はうまくいきます)、古いコミットと同じメッセージで新しいコミットが作成されます。それは commitC'
です:
...- A - B - E - F <-- master, origin/master
\ \
\ C'..... HEAD [detached]
\
C - D <-- ORIG_HEAD, branch
makecoming offへの適用C
に成功した後、rebase コマンドは、新しい (ただしまだ切り離されている)への適用を試みます。ただし、今回は問題が発生しました。パッチは適用されません。F
C'
F
D
HEAD
C'
CONFLICT ...
Failed to merge in the changes.
Patch failed at ...
The copy of the patch that failed is found in:
...
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
この時点で、コミット グラフは、上で描いた (やや乱雑な) グラフのようになります。
リベースの出力として、次のことができます。
git rebase --continue
、またはD
この場合は)をドロップすることを選択しますgit rebase --skip
git rebase --abort
ます。最後のオプションを選択すると、rebase は rebase の試行を停止しHEAD
、元の状態に戻し、「rebase in progress」ステータス/追跡ファイルを削除するように指示されます。これにより、新しい (まだブランチでラベル付けされていない) コミットのチェーン全体も削除されます。(技術的には、それらは reflog にまだ残っています。通常は表示されません。)
最初のオプション (「手動で解決」) を実行するか、中間のオプション (「スキップ」) を選択すると、リベースを続行できます。問題を解決したとしましょうgit rebase --continue
。rebase がコミットを使い果たすと (そしてD
それが最後のコミットになります)、ブランチ名を最終コミットに移動し、HEAD
再びブランチ名に設定します。したがって、この場合、次のようになります。
...- A - B - E - F <-- master, origin/master
\ \
\ C' - D' <-- HEAD=branch
\
C - D <-- ORIG_HEAD
が指すコミットは通常は表示されないため、 と のようにORIG_HEAD
見えなくなり、コピー (と) だけが残ったコミットになります。(いつものように、実際にはまだそこにあり、reflog エントリが期限切れになるまでしばらくの間残ります。)C
D
C'
D'
C
D
これらすべてを念頭に置いて、「切り離された HEAD」状態になると、git reset --hard
影響を受けるブランチ名はありません。移動HEAD
し、作業ディレクトリを変更しHEAD
ますが、コミットを直接指します。したがってgit reset
、リベースの途中で行う s は、せいぜい奇妙です。HEAD
(リベースを続行すると、その時点でどこにでも追加し続けるため、リベースを続行すると何が起こるかをいじります。)
より通常のケース (「ブランチ上」にいる場合) では、HEAD
ブランチの名前を持ちます。それから(そしてその時だけ)、git reset
ブランチ名が指すコミットを変更することができます。
どのアクションgit reset
が実行され、何が起こっているかをどのように伝えますか? 答えは、使用することgit status
です。何が起こっているのかわからない場合はgit status
、役立つはずです。ここ数年で、実際の支援も大幅に改善されました。:-)
ブランチにいる場合は、ブランチgit reset --hard bd53134
を更新することになっており、そのブランチに残されます。そのため、実際にはブランチにいなかったのではないかと思います。
それが正しければ、ブランチに戻って修正する 1 つの方法:
git checkout <branch>
git reset
次に、既に使用した同じコマンドを再度実行します。