2

私はブランチで作業しており、いくつかのコミットを元に戻す必要がありました。だから私はやった

$> git reset --hard bd53134

これは、頭が切り離されていることを除いて、望ましい効果がありました:(

$> git status
HEAD detached at bd53134

どうすればこれを修正できますか?

4

2 に答える 2

12

あなたはまだこれをいじっているように見えるので、ここに少し背景があります. あなたはコメントで、あなたが始めて、いつも不平を言っgit rebaseて立ち往生していたと述べました. git rebase --continue(これは実際には元の質問の一部であったはずです。)

最初のメモ:HEAD通常 (「切り離されていない」?) または「切り離された」可能性があります。「通常」HEADはブランチ名だけで構成されます。あなたが「支店にいる」場合はmasterHEAD単に「支店長に」と言います。フランス革命の何かのように聞こえる「切り離された HEAD」は、生の SHA-1 コミット ID の代わりに構成されます。以下の図では、添付された HEAD を のように書きHEAD=branch、矢印を使用して特定のコミットを指すように、分岐がどこを指しているかを示します。

リベースを開始する前に、次のようなコミット グラフがあります。

...- A - B - E - F         <-- master, origin/master
           \
             C - D         <-- HEAD=branch

この場合、私はあなたがgit checkout -b branchfromを実行し、 (作成と) でmasterいくつかのコミットを行い、その後おそらくandを実行して、コミットとfrom "リモート" を引き継いだと仮定しました。次に、(したがって)に戻りました。branchCDgit checkout mastergit pullEForiginbranchgit checkout branchHEAD=branch

C次に、とDの上に両方をリベースする必要があると判断しF、より直線的なコミット シーケンスを提供します。

...- A - B - E - F         <-- master, origin/master
                  \
                   C' - D' <-- HEAD=branch

C'(これらがandD'の代わりにCandである理由をすぐに示しますD。) したがって、コミットをgit rebase master「移動」して.CDmaster

Rebase は実際にはコミットを移動しません。それは、いくつかの既存のコミットをコピーして、「同じことを行い」、「同じくらい良い」新しいコミットを作成することです (私たちは願っています!)。したがって、リベースは維持されます。特別なラベル を使用して、コミットを追跡します(および、リベース操作全体のすべての進行状況を追跡するための一連の追加ファイル - 実際、これらのファイルは、リベースが「進行中」であることを git が認識する方法です)。CDORIG_HEADD.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 コマンドは、新しい (ただしまだ切り離されている)への適用を試みます。ただし、今回は問題が発生しました。パッチは適用されません。FC'FDHEADC'

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 エントリが期限切れになるまでしばらくの間残ります。)CDC'D'CD


これらすべてを念頭に置いて、「切り離された HEAD」状態になると、git reset --hard影響を受けるブランチ名はありません。移動HEADし、作業ディレクトリを変更しHEADますが、コミットを直接指します。したがってgit reset、リベースの途中で行う s は、せいぜい奇妙です。HEAD(リベースを続行すると、その時点でどこにでも追加し続けるため、リベースを続行すると何が起こるかをいじります。)

より通常のケース (「ブランチ上」にいる場合) では、HEADブランチの名前を持ちます。それから(そしてその時だけ)、git resetブランチ名が指すコミットを変更することができます。

どのアクションgit resetが実行され、何が起こっているかをどのように伝えますか? 答えは、使用することgit statusです。何が起こっているのかわからない場合はgit status、役立つはずです。ここ数年で、実際の支援も大幅に改善されました。:-)

于 2013-11-12T12:04:57.263 に答える
9

ブランチにいる場合は、ブランチgit reset --hard bd53134を更新することになっており、そのブランチに残されます。そのため、実際にはブランチにいなかったのではないかと思います。

それが正しければ、ブランチに戻って修正する 1 つの方法:

git checkout <branch>

git reset次に、既に使用した同じコマンドを再度実行します。

于 2013-11-12T08:17:02.407 に答える