一個奇怪的git問題,求大家幫忙分析一下?
比如我現在在工作區新建一個文件叫test.html,然後git status:
git檢測到這個新添加的文件,提示通過add加入暫存區。下面執行:
git reset --hard
貌似沒有執行什麼,再看git status:
還是剛添加文件時的git status提示,新添加的test.html沒有被刪除。現在執行:
git add dist/test.html
在查看git status狀態:
新添加的test.html放入暫存區,下面執行:
git reset --hard
再看git status,工作區和暫存區全部乾淨了,新添加的test.html也沒有了。
總結下兩次操作的區別:同樣是新建了一個test.html文件
- 第一種是直接git reset --hard,新建test.html文件在工作區被保留
- 第二種是先add這個新建test.html文件,被添加到暫存區,然後git reset --hard,工作區的test.html文件也被刪除了。
如果git reset --hard是拿上次提交的記錄來覆蓋工作區和暫存區的話,那麼第一種情況時,test.html就應該被刪除。如果是git reset --hard不對沒有被追蹤的文件進行處理的話,第二種情況下,test.html在工作區不會被刪除。
自己已經暈了,等git來解答,我覺著這很可能是git的一個bug。
首先這不是Git的Bug
請先熟悉這幅圖:git add 實際上已經把文件提交到了Staged區域git status命令實際上已經明確提示了:如果想把Staged區域的文件撤銷,需要使用git reset HEAD &
命令
而git reset --hard HEAD命令,引用GitBook里的話:
這條命令會把你工作目錄中所有未提交的內容清空(當然這不包括未置於版控制下的文件 untracked files).
以上
如清風所言,第一,請先熟悉這幾張圖。第二,關於git add的本質。git add命令在git里是一個典型的多功能命令,在不同場景下有不同的功能:
1.開始跟蹤新文件,直接添加到暫存區
2.把已跟蹤,修改後的文件添入暫存區
3.合併時把有衝突的文件標記為已解決狀態
擴展:這也正是git commit -a和分別執行git add/git commit的區別。(比如新添加的圖片,由於還處於未跟蹤狀態,git commit -a並不會把圖片也commit)。
第三,關於git reset --hard 的本質。本質:暫存區的該文件會被master分支的該文件所替換,回到最近一次git commit的狀態。工作區不變。
第四,就題主的疑問
「第一種是直接git reset --hard,新建test.html文件在工作區被保留」
憑空新建的test.html屬於untracked(未跟蹤)文件,沒有git add,一直還是處於工作區且未跟蹤狀態。根據git reset --hard的本質(暫存區的該文件會被master分支的該文件所替換,回到最近一次git commit的狀態。工作區不變。),test.html不會受到影響。
這不是bug
第一種情況你的檔案是 untracked
即然是 untracked,那麼 git 就不會去管你的檔案,要刪要存你自己看著辦。第二種情況你把檔案交給 git 做管理(git add),所以執行 git reset 之後 git 幫你回覆到先前的狀態(沒有檔案)首先,這不是 git 的 bug。
`git add` 操作是把文件加到 git 的 `index` 中,這個時候 git 會為其創建一個 blob 對象,保存到 `.git/objects` 目錄下,通過 `git ls-files` 可以看到 git 為該文件做好與物理文件的映射。
`git reset --hard` 操作的是 git 對象資料庫與其 `index`,它影響不了任何未加入版本控制的文件。如果你要刪除這些文件,可以用 `git clean -f`,這個命令不操作任何 git 對象和 `index`,它僅僅是把 `untracked files` 列出來,然後執行系統命令 `rm -f` 而已。
從下面的截圖,你可以看得更清楚:
1 Treat git as a data structure
2 If test.html is not in the data structure, all the command have no effect.3 If test.html is in the data structure, all the command will work.So this command (git reset --hard) only work after git add test.htmlAgain, please read the official documents.如果git reset --hard是拿上次提交的記錄來覆蓋工作區和暫存區的話,那麼第一種情況時,test.html就應該被刪除。
你這個推斷是錯誤的,
謝邀
這並不是git的bug因為題主沒有正確的理解git stage 可以仔細看看他全部的文檔(我已經看了很多遍)Git - Recording Changes to the Repository希望題主學習順利並可以從中掌握更多git的相關知識推薦閱讀:
※在使用git的過程中 為什麼要是使用命令行?
※.Net控制Git.exe進程交互遇到的問題?
※為什麼我在git上提交代碼都會重複提交別人更新的代碼?
TAG:Git |