基本概念
首先理解Git 工作區、暫存區和版本庫概念:
- 工作區:就是你在電腦裏能看到的目錄。
- 暫存區:英文叫stage或index。一般存放在".git目錄"下的index文件(.git/index)中,所以我們把暫存區有時也叫作索引(index)。暫存區屬於版本庫的一部分。
- 版本庫:工作區有一個隱藏目錄.git,這個不算工作區,而是Git的版本庫。Git爲我們自動創建了第一個分支master,以及指向master的一個指針叫HEAD。
下面這個圖展示了工作區、版本庫中的暫存區和版本庫之間的關係:
文件狀態
Git管理的文件有下面四種狀態:
- Untracked: 未跟蹤。此文件在文件夾中, 但並沒有加入到git庫, 不參與版本控制. 通過
git add
狀態變爲Staged. - Staged: 暫存狀態。執行
git commit
則將修改同步到庫中, 這時庫中的文件和本地文件又變爲一致,文件爲Unmodify狀態. 執行git reset HEAD filename
取消暫存, 文件狀態爲Modified。 - Unmodify: 文件已經入庫, 未修改。 即版本庫中的文件快照內容與文件夾中完全一致. 這種類型的文件有兩種去處, 如果它被修改,
而變爲Modified. 另外如果使用git rm
就移出版本庫並被刪除。 - Modified: 文件已修改, 僅僅是修改, 並沒有進行其他的操作。 這個文件也有兩個去處, 通過
git add
可進入暫存staged狀態, 使用git checkout
則丟棄修改過, 返回到unmodify狀態, 這個git checkout
即從庫中取出文件, 覆蓋當前修改
文件操作
一、狀態查看
查看工作區和暫存區的狀態的命令:
#查看所有文件狀態
git status
#查看指定文件狀態
git status [filename]
剛剛創建倉庫後,查看倉庫的狀態:
根據描述可以知道,在倉庫中,我們處在master分支下,暫時沒有已經提交的文件,也沒有可以提交的文件。還提示我們使用git add
命令創建或複製一個文件在倉庫中,以使用git的追蹤文件的功能,
二、添加
首先明確一下,所有的版本控制系統,其實只能跟蹤文本文件的改動,比如TXT文件,網頁,所有的程序代碼等等,Git也不例外。版本控制系統可以告訴你每次的改動,比如在第5行加了一個單詞“Linux”,在第8行刪了一個單詞“Windows”。而圖片、視頻這些二進制文件,雖然也能由版本控制系統管理,但沒法跟蹤文件的變化,只能把二進制文件每次改動串起來,也就是隻知道圖片從100KB改成了120KB,但到底改了啥,版本控制系統不知道,也沒法知道。
值得一提的是,Microsoft的Word格式是二進制格式,因此,版本控制系統是沒法跟蹤Word文件的改動的。
1.命令
將工作區的文件添加到暫存區的命令:
#添加指定文件到暫存區
git add [file name1][file name2]..
#添加當前目錄的所有文件到暫存區
git add
#添加指定目錄(包括子目錄)到暫存區
git add [dir]
2.創建文件
爲了使用git add命令,首先使用vim創建一個test.txt文本文件,內容爲隨便編輯了三行字母。此時查看倉庫的狀態:
這時的狀態是untracked,可以看到提示我們當前倉庫中有一個名爲test.txt
文件沒有被git跟蹤。
3.添加文件到暫存區
按照提示將這個新建的文本文件添加到暫存區中:
這裏的倉庫狀態又改變了,改爲staged狀態,提示我們可以將test.txt
文件保存到本地倉庫。
此時我們還可以使用以下命令將文件從暫存區中移出:
#直接從暫存區刪除文件
git rm --cached <file>...
三、提交
1.命令
將暫存區的內容提交到本地庫的命令:
git commit -m "commit message" [file name]
# 提交暫存區的指定文件到倉庫區
$ git commit [file1] [file2] ... -m "commit message"
# 提交工作區自上次commit之後的變化,直接到倉庫區,跳過了add,對新文件無效
$ git commit -a
# 提交時顯示所有diff信息
$ git commit -v
# 使用一次新的commit,替代上一次提交
# 如果代碼沒有任何新變化,則用來改寫上一次commit的提交信息
$ git commit --amend -m "commit message"
# 重做上一次commit,幷包括指定文件的新變化
$ git commit --amend [file1] [file2] ...
這裏的commit message
爲備註信息,我們要在這裏說明自己改了什麼地方。當我們需要寫很多備註信息時,可以不使用-m 參數就會跳到vim編輯器再輸入備註信息。
因爲commit命令不指定文件時可以一次提交多個暫存區中的文件,所以我們可以先多次add不同的文件。
2.具體使用
將test.txt
提交到本地倉庫,提交成功後可以看到一些文件信息:
當我們對文件進行修改後再查看倉庫的狀態:
test.txt的狀態改爲modified,這裏提示我們test.txt
文件被修改了,還沒有保存到本地庫。可以使用git add <file>
命令來更新,這命令會再提交一次文件,或者使用git restore <file>
來撤銷工作區中的修改。
這裏使用commit
命令提交test.txt
文件來保存
這裏可以看到版本號更改了,這是爲了我們以後進行版本回退做準備的。
四、重寫暫存區
#如果已經用add 命令把文件加入stage了,就先需要從stage中撤銷
git reset HEAD <file>...
當執行 git reset HEAD
命令時,暫存區的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,但是工作區不受影響。
例子:將添加到暫存區的t1.txt必重寫暫存區的方式移出暫存區
五、刪除所有未跟蹤文件
刪除所有未跟蹤文件的命令是:
#移除所有未跟蹤文件
#一般會加上參數-df,-d表示包含目錄,-f表示強制清除。
git clean [options]
其他一些刪除文件的命令:
#只從暫存區中刪除,保留物理文件
git rm --cached readme.txt
#不但從暫存區中刪除,同時刪除物理文件
git rm readme.txt
#linux自帶的命令,只刪除工作區中的物理文件
rm readme.txt
六、檢出
如果倉庫中暫存區中已經保存了文件,當我們修改出錯了,就可以直接使用git checkout
命令來撤銷修改。另外我們還可以直接使用版本庫中文件覆蓋暫存區和工作區等。檢出的相關命令:
$ git checkout branch
#檢出branch分支。更新HEAD以指向branch分支,以及用branch 指向的樹更新暫存區和工作區。
$ git checkout
#會用暫存區全部或指定的文件替換工作區的文件。
$ git checkout HEAD
#會用 HEAD 指向的 master 分支中的全部或者部分文件替換暫存區和以及工作區中的文件。
#這個命令也是極具危險性的,因爲不但會清除工作區中未提交的改動,也會清除暫存區中未提交的改 動。
$ git checkout -- filename
#用暫存區中filename文件來覆蓋工作區中的filename文件。
#相當於取消自上次執行git add filename以來(如果執行過)的本地修改。
$ git checkout branch -- filename
#維持HEAD的指向不變。用branch所指向的提交中filename替換暫存區和工作區中相應的文件。
#注意會將暫存區和工作區中的filename文件直接覆蓋。
$ git checkout -- . 或寫作 git checkout .
#注意git checkout 命令後的參數爲一個點(“.”)。
#這條命令最危險!會取消所有本地的 #修改(相對於暫存區)。
#相當於用暫存區的所有文件直接覆蓋本地文件,不給用戶任何確認的機會!
$ git checkout commit_id -- file_name
#如果不加commit_id,那麼git checkout -- file_name 表示恢復文件到本地版本庫中最新的狀態。
用暫存區的文件覆蓋工作區的指定文件,示例:
七、查看文件修改後的差異
查看文件修改後的差異的相關命令
#將工作區中的文件和本地庫歷史記錄比較
git diff [本地庫中歷史版本][文件名]
#不加文件名,將工作區中的所有文件和暫存區進行比較
git diff
#將工作區中的文件和暫存區進行比較
git diff [文件名]
#比較暫存區的文件與之前已經提交過的文件
git diff --cached
這裏的— a表示修改之前的文件,+++ b修改後的文件。紅色的表示刪除的,綠色的表示增加的。
參考:
一個小時學會Git