2016-04-01 12 views
1

Pro Gitは、このようなgit resetについて説明します。git reset -hardは作業ツリーをインデックスのように見せませんか?

要約

あなたがそれを言うときresetコマンドは停止し、特定の順序でこれら3本の木を上書き:ブランチヘッドを移動

  1. を指す(--softの場合はここで停止)
  2. 作業ディレクトリインデックス

のように見えるしてください(--hardない限り、ここで停止)指数はHEAD ように見える

  • を作り、私は理解の方法は、私はgit reset --hardをすれば、ということで、その後、私のインデックスの両方私の作業ディレクトリはとなり、正確にはのようになります。だから私は先に行って、これをしなかった:

    # make a git repo 
    mkdir mygitrepo 
    cd mygitrepo 
    git init 
    
    # init commit 
    touch old_file 
    git commit -a 
    
    # stage a file 
    touch staged 
    git add staged 
    
    # create file that is not staged 
    touch unstaged 
    

    は、これまでのところ、私のレポは、次のようになります。

    • HEAD
    • working dir old_file +は+ unstagedを上演上演old_file +
    • index
    • old_file

    git reset --hardを実行すると、m

    • HEAD

    old_file

  • working dir old_file
  • index
  • old_fileしかし、私は代わりに、これを取得します::yのレポはなるために

    • HEAD old_file
    • old_file
    • working dir old_file + unstaged
    • 私は明示的に git reset --hard targetのように、ターゲットの引数を渡して、そして私は同様の結果を得たことにより、同様の試験を行った

    :上演したファイルはすべてなくなっているが、unstagedファイルがまだgit reset --hard後に存在しています。

    git resetについて私が誤解していると説明してもらえますか?

    答えて

    1

    git cleanコマンドは、多くの場合、git reset --hardと一緒に実行された "Undoing Changes"

    で述べたように。
    リセットは追跡されたファイルにのみ影響するため、追跡されていないファイルを削除するには別のコマンドが必要です。

    これら2つのコマンドを組み合わせると、作業ディレクトリを特定のコミットの正確な状態に戻すことができます。インデックスと作業ツリーをリセットします

    --hardオプションは以下のように記載されています。
    への変更<commit>以降は、作業ツリー内のファイルが削除されます。


    このすでに2008
    Simply put by Linux Torvaldsに戻って議論されました:

    あなたが "git checkout -f" または "git reset --hard" をやって慣れている場合は、それらのチェックの両方(*)は無視されます。結局のところ、あなたは強制的な切り替えを求めました。

    (*小切手=汚れたファイルや人跡未踏のファイル)

    と少なくとも第2のケースでは、私が起こる考えるものは、Gitはそれはdoesnのファイルを削除しない ということです知っているので、の周りに "芝生"が残るでしょう。


    追加ファイルがが...そこにコミットされなかった場合でも、(ブランドの新しいされている)、まだgit reset --hardによって削除され、seen also in 2008として:

    私は実際に誤って百を削除しました昨日新しく追加されたファイルのうち これだけです。

    私の質問は、なぜ「git reset --hard新しく追跡追加されたファイルのための特別なケースを作ることができないのですか?
    git status」は、「新しいファイル」であることを知り、「git reset --hard」は地球の表面からそれらを拭くことが可能な最も有用なものではないことに気付くことができました。git reset --hardは(インデックスから削除)周り

    Junio C. Hamano stil arguesをこの新しいファイルを保つことに役立つだろう前に提案、git read-tree -m HEADまたはgit rm --cached <file list>として

    あなたが望む "reset --hard" へのパスは、パスがHEADではなく索引に存在しない場合は削除してください。その他の場合はです。
    そして、私の経験では、はるかに多いことが望ましいことです。

    なお、この例では、git fsck can still help recover those deleted new files(競合のマージからクラフツを取り除くなど)。

    +0

    追跡されたファイルでのみ動作することがわかりませんでした。ありがとう! –

    1

    Gitが常に従う重要なルールがあります(明示的に指示しない限り):未追跡のファイルには触れないでください。

    デフォルトの機能を使用すると、Gitは、追跡されていないファイルのデータが失われるような動作を実行しません。これは、追跡されていないファイルからの情報がGitによって決して復元されないためです:彼らはそれらを「知っていません」ので、どこにでもコンテンツを保存することはありません。だから、単にそれに触れることはありません。

    これは、追跡されていないファイルがあるブランチに、と同じパスのファイルが含まれていると、そのファイルにブランチに切り替えることができない理由です。これを行うと、untrustedファイルが上書きされ、そのブランチからのファイルに置き換えられますが、untrackedファイルは絶対に回復できません。だから、Gitは、最初に非トラッキングファイルの世話をしてくれるようにブランチを切り替えることはありません(名前を変更したり、Gitに追加したり、削除することもできます)。

    git resetを実行すると、インデックスにのみ影響します。 git reset --hardは、インデックスと作業ディレクトリに影響します。 Gitの場合、作業ディレクトリには追跡されたファイルのみが含まれます。そのため、git reset --hardは、未追跡のファイルや、.gitignoreのファイルを削除しません。 Gitはそれらについて「認識」していないので、それらには触れません。

    未処理のファイルを削除する場合は、それに責任があるコマンドが1つあります。git clean。このコマンドには、さまざまな異なるジョブを実行する異なる引数の組み合わせがあります。

    デフォルトの場合、git clean -fは、未修正のファイルを削除しますが、無視されたファイルはそのままです。無視されたファイルも削除したい場合は、git clean -x -fを使用できます。 git cleanには通常、常に-f(または--force)を指定する必要があります。これは、あなたがしていることを知っていることを確認するための追加のセキュリティメカニズムです。代わりに-nを使用してドライ運転を実行し、Gitが削除するファイルのみを表示することができます。これにより、問題を回避しやすくなります。

    +1

    gitの哲学に非常に有用な紹介、ありがとう! –

    関連する問題