67173


gitコマンドは、「.git」フォルダ内だけを操作すると思ったのですが、そうではないのですか？  
ファイル削除されることはありますか？

環境  
Windows  
Git Bash

* * *

作業履歴  
まだ一度もコミットしていない状態です。リモートリポジトリはこれから作成する予定でした。

[code]

    $ git add -A
    warning: adding embedded git repository: example.com
    hint: You've added another git repository inside your current repository.
    hint: Clones of the outer repository will not contain the contents of
    hint: the embedded repository and will not know how to obtain it.
    hint: If you meant to add a submodule, use:
    hint:
    hint:   git submodule add <url> example.com
    hint:
    hint: If you added this path by mistake, you can remove it from the
    hint: index with:
    hint:
    hint:   git rm --cached example.com
    hint:
    hint: See "git help submodule" for more information.
    
[/code]

中に別のgitリポジトリがあると表示されたので、そのリポジトリを一旦削除後、再度「$ git add -A」したかったのですが、  
(一旦元へ戻そうと思い)下記コマンドを打ったりしている内に、いつの間にかファイルが(意図せず)削除されてしまいました。

[code]

    $ git reset HEAD
    fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
    Use '--' to separate paths from revisions, like this:
    'git <command> [<revision>...] -- [<file>...]'
    
    $ git reset --hard
    warning: unable to rmdir 'example.com': Directory not empty
    
[/code]

この場合どうすれば良かったのですか？  
「.git」フォルダを手動で削除して、再度「$ git add -A」？


CC BY-SA 4.0
2020-05-31T06:18:28.533
67157
2020-06-01T00:23:20.887
2020-05-31T06:30:23.143
3060
7886
question
git git-bash
gitコマンドでファイル削除されることはありますか？


よくある説明として、 git が管理しているディレクトリ構造は、 「Working Tree」「Index」「Commit」があるかな、と思っています。

「Working Tree」 --(add)--> Index --(commit)--> Commit

というふうにファイル・ディレクトリは管理されていきます。

さて、この git が管理しているのは「Working
Tree」「Index」「Commit」と言いましたが、それが保持されているのは物理的なファイルです。

  * Working Tree -- `.git` ディレクトリ以外の全て
  * Index/Commit -- `.git` ディレクトリ内部にて管理

そして、 git はバージョン管理ツールなので、 Working Tree
に対しても普通にファイルの作成・削除・置換を行います。これができないと、「古いバージョンを Working Tree に
checkout」などができないからです。

`git reset --hard` は、指定されたコミット(コミットへの参照が省略された場合には、 HEAD すなわち current branch
の先頭)の内容を Working Tree へ反映するコマンドです。(その実、もうちょっと多くのことをやっていて、 Index
を指定されてコミットのそれへと一致させる効果もあります。)


CC BY-SA 4.0
2020-05-31T06:44:04.690
67159
2020-05-31T06:44:04.690
754
67157
answer


`git reset` は任意のコミットの状態に戻すコマンドです。例えばファイルを追加した後にそれより以前のコミットに戻せば、当然ファイルは削除されます。

今回、あなたはファイルを作成した後に「一度もコミットしないまま」`git reset --hard`
を実行しているので、リポジトリに登録されていない(コミットされていない)ファイルが消えた形です。

`.git/` というディレクトリが含まれているとリポジトリとして認識するので、無関係なサブディレクトリは事前に退避 (削除や移動) しておいてから
`git add -A` すればよかったのだと思います。


CC BY-SA 4.0
2020-05-31T07:21:32.063
67160
2020-05-31T07:21:32.063
3060
67157
answer


`git reset
--hard`は"gitが管理していないファイル"には手を付けないのですけれど、"gitが管理しているファイルに加えられた変更"や"gitで作業途中の状態"をリセットします。

[code]

    % mkdir project
    % cd project
    % git init
    Initialized empty Git repository in /Users/hoge/project/.git/
    % echo a > a
    % echo b > b
    % ls
    a  b
    % git status
    On branch master
    
    No commits yet
    
    Untracked files:
      (use "git add <file>..." to include in what will be committed)
        a
        b
    
    nothing added to commit but untracked files present (use "git add" to track)
    % git reset --hard
    % ls
    a  b
    
[/code]

ファイル a も b も、Untracked files なので`git reset --hard`してもファイルは消えません。

ですが質問者さんに起こったことはこうではなくて、

[code]

    % mkdir project
    % cd project
    % git init
    Initialized empty Git repository in /Users/hogehoge/project/.git/
    % echo a > a
    % echo b > b
    % ls
    a  b
    % git add -A
    % git status
    On branch master
    
    No commits yet
    
    Changes to be committed:
      (use "git rm --cached <file>..." to unstage)
        new file:   a
        new file:   b
    
    % git reset --hard
    % ls
    %
    
[/code]

と想像します。

`git -A`したことで、ファイルaもbも、`Changes to be committed`に入っています。  
「新しいファイルを作成したという履歴」で「次に`git commmit`すれば記録される予定の差分」の扱いになっています。  
これを`git reset --hard`すると「新しいファイルを作成したという履歴」が **無かったこと** になってファイルが消えています。

(正確ではないかもしれませんがこんなところかと)

* * *

ちなみに質問者さんの手元で起こったと想像する手順は以下の通り

[code]

    % mkdir project
    % cd project
    % git init
    Initialized empty Git repository in /Users/hogehoge/project/.git/
    % mkdir sub
    % cd sub
    % echo a > subfile
    % git init
    Initialized empty Git repository in /Users/hogehoge/project/sub/.git/
    % git add subfile
    % git commit -am "first commit of sub"
    [master (root-commit) d8db7a7] first commit of sub
     1 file changed, 1 insertion(+)
     create mode 100644 subfile
    % cd ..
    % echo a > a
    % echo b > b
    % ls
    a  b  sub/
    % git add -A
    warning: adding embedded git repository: sub
    hint: You've added another git repository inside your current repository.
    hint: Clones of the outer repository will not contain the contents of
    hint: the embedded repository and will not know how to obtain it.
    hint: If you meant to add a submodule, use:
    hint:
    hint:   git submodule add <url> sub
    hint:
    hint: If you added this path by mistake, you can remove it from the
    hint: index with:
    hint:
    hint:   git rm --cached sub
    hint:
    hint: See "git help submodule" for more information.
    % git status
    On branch master
    
    No commits yet
    
    Changes to be committed:
      (use "git rm --cached <file>..." to unstage)
        new file:   a
        new file:   b
        new file:   sub
    
    % git reset --hard
    warning: unable to rmdir 'sub': Directory not empty
    % ls
    sub/
    
[/code]


CC BY-SA 4.0
2020-06-01T00:23:20.887
67173
2020-06-01T00:23:20.887
12274
67157
answer