[TOC]
------
### 查看倉庫狀態
> 首先在沒有操作的情況下看一下倉庫的整個狀態
```shell
[root@supman git]# git status
# 位于分支 master
#
# 初始提交
#
無文件要提交(創建/拷貝文件并使用 "git add" 建立跟蹤)
```
> 然后在目錄下新建一個文件查看一下狀態
```shell
[root@supman git]# touch first.txt
[root@supman git]# git status
# 位于分支 master
#
# 初始提交
#
# 未跟蹤的文件:
# (使用 "git add <file>..." 以包含要提交的內容)
#
# first.txt
提交為空,但是存在尚未跟蹤的文件(使用 "git add" 建立跟蹤)
```
### 追蹤一個文件
> 從以上可以看出一個文件現在是處于什么狀態
>
> 那么我們現在按照提示使用 `git add`命令對這個文件進行追蹤一下
```shell
[root@supman git]# git add first.txt
[root@supman git]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的變更:
# (使用 "git rm --cached <file>..." 撤出暫存區)
#
# 新文件: first.txt
#
```
> `git`又給提示了!`git rm --cached <file>`可以撤出暫存區也就是取消跟蹤,那么我們為您就操作一下看一下這條命令的作用是什么唄。(暫存區是git的三大區域之一,后面會有統一的講解)
```shell
[root@supman git]# git rm --cached first.txt
rm 'first.txt'
[root@supman git]# git status
# 位于分支 master
#
# 初始提交
#
# 未跟蹤的文件:
# (使用 "git add <file>..." 以包含要提交的內容)
#
# first.txt
提交為空,但是存在尚未跟蹤的文件(使用 "git add" 建立跟蹤)
```
> 從上面的執行結果清楚的看到`git rm --cached xxx`就是將使用`git add`命令跟蹤的文件恢復到未跟蹤狀態
>
> 除了一個一個地操作文件還可以批量的操作一下。
```shell
[root@supman git]# touch second.txt
[root@supman git]# git status
# 位于分支 master
#
# 初始提交
#
# 未跟蹤的文件:
# (使用 "git add <file>..." 以包含要提交的內容)
#
# first.txt
# second.txt
提交為空,但是存在尚未跟蹤的文件(使用 "git add" 建立跟蹤)
[root@supman git]# git add .
[root@supman git]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的變更:
# (使用 "git rm --cached <file>..." 撤出暫存區)
#
# 新文件: first.txt
# 新文件: second.txt
#
[root@supman git]# git rm -r --cached *.txt
rm 'first.txt'
rm 'second.txt'
[root@supman git]# git status
# 位于分支 master
#
# 初始提交
#
# 未跟蹤的文件:
# (使用 "git add <file>..." 以包含要提交的內容)
#
# first.txt
# second.txt
提交為空,但是存在尚未跟蹤的文件(使用 "git add" 建立跟蹤)
```
> 當一個文件改動后追蹤的文件會是什么樣的狀態呢?
```shell
[root@supman git]# git add .
[root@supman git]# echo "你好" > first.txt
[root@supman git]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的變更:
# (使用 "git rm --cached <file>..." 撤出暫存區)
#
# 新文件: first.txt
# 新文件: second.txt
#
# 尚未暫存以備提交的變更:
# (使用 "git add <file>..." 更新要提交的內容)
# (使用 "git checkout -- <file>..." 丟棄工作區的改動)
#
# 修改: first.txt
#
```
> `git`給了我們三個選項
>
> 1. 撤出暫存區 - 這樣的話在提交文件的時候就不會提交`first.txt`這個文件。
>
> 2. 更新要提交的內容 - 就是將暫存區的`first.txt`更新到最新狀態。
>
> 3. 丟棄工作區的改動 - 就是把本地的`first.txt`更新到沒有改動之前的狀態(工作區也是三大區域之一)。
>
> ```shell
> [root@supman git]# git checkout -- first.txt
> [root@supman git]# ls
> first.txt second.txt
> [root@supman git]# cat first.txt
> ```
>
> 操作一下這個命令,發現`first.txt`里面并沒有內容,就是恢復到了修改之前的內容了。
>
> 除了上面的`git rm --cached`還有一條與其相似的命令,也能撤銷跟蹤 `git reset --`
```shell
[root@supman git]# git add .
[root@supman git]# git status
# 位于分支 master
#
# 初始提交
#
# 要提交的變更:
# (使用 "git rm --cached <file>..." 撤出暫存區)
#
# 新文件: first.txt
# 新文件: second.txt
#
[root@supman git]# git reset --
[root@supman git]# git status
# 位于分支 master
#
# 初始提交
#
# 未跟蹤的文件:
# (使用 "git add <file>..." 以包含要提交的內容)
#
# first.txt
# second.txt
提交為空,但是存在尚未跟蹤的文件(使用 "git add" 建立跟蹤)
```
> 使用`git diff`命令比較暫存區和工作區的文件
```shell
[root@supman git]# git diff
diff --git a/first.txt b/first.txt
index e69de29..3b18e51 100644
--- a/first.txt
+++ b/first.txt
@@ -0,0 +1 @@
+hello world
```
### 做一個新的版本
> 在學習新增一個版本前我們學習一下怎樣查看版本信息
>
> 使用`git log`命令查看版本區提交的歷史紀錄(版本區也是`git`三大區域之一)
```
[root@supman git]# git log
fatal: bad default revision 'HEAD'
```
> 上面顯示我們為您還沒有提交過版本....
>
> 那么我們就來提交幾次吧。。。提交使用的命令是 `git commit`
```shell
[root@supman git]# git commit -m "第一次提交"
[master(根提交) e58e53e] 第一次提交 2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 first.txt
create mode 100644 second.txt
[root@supman git]# git logcommit e58e53ea4a19021ac7640aac6994831b7fcf1b85
Author: yong.yuan <1218639030@qq.com>
Date: Sat Sep 4 17:14:15 2021 +0800
第一次提交
```
> 然后我們為您再次提交一下
>
> 此時`git`提示我們版本去的信息和暫存區的信息一模一樣無法提交
```shell
[root@supman git]# git commit -m "第二次提交"
# 位于分支 master# 尚未暫存以備提交的變更:
# (使用 "git add <file>..." 更新要提交的內容)
# (使用 "git checkout -- <file>..." 丟棄工作區的改動)
# 修改: first.txt
#
修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
```
> 后面我們修改一下某個文件,再次提交一下查看
```shell
[root@supman git]# git add second.txt
[root@supman git]# git commit -m "第二次提交"
[master c55da94] 第二次提交 1 file changed, 1 insertion(+)
[root@supman git]# git log
commit c55da94d57a4e7f1a076483d09afd182ad10bd5d
Author: yong.yuan <1218639030@qq.com>
Date: Sat Sep 4 17:19:31 2021 +0800
第二次提交
commit e58e53ea4a19021ac7640aac6994831b7fcf1b85
Author: yong.yuan <1218639030@qq.com>
Date: Sat Sep 4 17:14:15 2021 +0800
第一次提交
```
> 全部提交上去以后,我們再看一下本地狀態
```shell
[root@supman git]# git status
# 位于分支 master
# 您的分支領先 'origin/master' 共 1 個提交。
# (使用 "git push" 來發布您的本地提交)
#
無文件要提交,干凈的工作區
```
> 關于查看提交歷史記錄的命令,有些常用的選項介紹一下:
>
> - `git log [分支名]` 查看某分支的提交歷史,不寫分支名查看當前所在分支
> - `git log --oneline` 一行顯示提交歷史
> - `git log -n` 其中 n 是數字,查看最近 n 個提交
> - `git log --author [貢獻者名字]` 查看指定貢獻者的提交記錄
> - `git log --graph` 圖示法顯示提交歷史
> - `git log --reverse` 顯示正序提交歷史
### 版本撤回
> 首先我們為您先將兩個文件修改一下提交
```shell
[root@supman git]# echo "hello 哈哈" > first.txt
[root@supman git]# git add first.txt
[root@supman git]# git commit -m "修改first.txt"
[master fda1d98] 修改first.txt
1 file changed, 1 insertion(+), 1 deletion(-)
[root@supman git]# echo "你好 哈哈" > second.txt
[root@supman git]# git add second.txt
[root@supman git]# git commit -m "修改sencond.txt"
[master d967d87] 修改sencond.txt
1 file changed, 1 insertion(+), 1 deletion(-)
[root@supman git]# git log -2
commit d967d8730ca0e5a9d97a04a2ce448fbf9e280d4c
Author: yong.yuan <1218639030@qq.com>
Date: Mon Sep 6 19:47:05 2021 +0800
修改sencond.txt
commit fda1d98c0b5fdbcaf06f0edffac9a63004a6365d
Author: yong.yuan <1218639030@qq.com>
Date: Mon Sep 6 19:44:31 2021 +0800
修改first.txt
```
> 我們可以用用`git reset --soft HEAD^`撤回到上一個版本,也可以用`git reset --soft HEAD^2`退回到兩個版本之前
```shell
[root@supman git]# git reset --soft HEAD^
[root@supman git]# git log -2
commit fda1d98c0b5fdbcaf06f0edffac9a63004a6365d
Author: yong.yuan <1218639030@qq.com>
Date: Mon Sep 6 19:44:31 2021 +0800
修改first.txt
commit 1c0724081fa7505b34e9d269dae43d06babc9851
Author: yong.yuan <1218639030@qq.com>
Date: Mon Sep 6 19:27:15 2021 +0800
第次二提交
```
> 我們現在看一下被撤回的`second.txt`文件,發現就是我們提交前的文件信息,也就是說`git reset --soft`只是將文件從**版本區**拖到了**暫存區**但是文件內容并沒有改變。
```shell
[root@supman git]# cat second.txt
你好 哈哈
```
> 跟這類似的還有一種更*硬*的選擇`git reset --hard` 而查看一下文件發現這并不是剛剛提交上去的文件內容如果,按照`--soft`的邏輯應該是 **hello 哈哈** 才對,但是現在是將工作區(本地)的`first.txt`變成了版本區最近版本的內容。還有一個是`git reset --mixed`介于`hard`和`soft`之間,使用這個命令會使跟蹤的文件和版本區文件全都辦成上一個版本,但是本地文件也就是工作區的文件內容不變。
```shell
[root@supman git]# git reset --hard HEAD^
HEAD 現在位于 1c07240 第二次提交
[root@supman git]# cat first.txt
hello world
```
### 推送到遠程服務器
> 使用`git push -u origin master`命令后輸入賬號密碼就可以將`commit`在版本區的文件推送到遠程倉庫。
```shell
[root@supman git]# git push -u origin master
Username for 'https://gitee.com': codeyuany
Password for 'https://codeyuany@gitee.com':
Counting objects: 9, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (9/9), 769 bytes | 0 bytes/s, done.
Total 9 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.1]
To https://gitee.com/codeyuany/git.git
* [new branch] master -> master
分支 master 設置為跟蹤來自 origin 的遠程分支 master
```
> 使用`git branch`可以查看當前分支
```shell
[root@supman git]# git branch
* master
```
> 使用`git branch -avv`命令可以查看一些分支的基本信息,下面對應的消息分別為 *本地分支* *版本號* *遠程分時* *提交日志*
```shell
[root@supman git]# git branch -avv
* master 1c07240 [origin/master] 第二次提交
remotes/origin/master 1c07240 第二次提交
```
> 當我們使用`git --reset`不斷回退,出現遠程倉庫中的版本新于本地要提交的版本該怎么辦呢?
```shell
[root@supman git]# git push
Username for 'https://gitee.com': codeyuany
Password for 'https://codeyuany@gitee.com':
To https://gitee.com/codeyuany/git.git
! [rejected] master -> master (non-fast-forward)
error: 無法推送一些引用到 'https://gitee.com/codeyuany/git.git'
提示:更新被拒絕,因為您當前分支的最新提交落后于其對應的遠程分支。
提示:再次推送前,先與遠程變更合并(如 'git pull')。詳見
提示:'git push --help' 中的 'Note about fast-forwards' 小節。
```
> 1. 現在有兩種辦法一種是`git pull`將倉庫上的新版本拉取下來使本地也變成新版本。
> 2. 而是強制提交`git push --force`使本地的舊版本直接覆蓋掉遠程倉庫中的新版本。
>
> 一般情況下除了你非常確定的時候才使用第二種方法,比如說一段代碼你就發現之前版本是正確的,當前版本有問題。
>
> 第一種方法是常用方法,往往在提交文件時也要先使用`git pull`命令把本地版本更新,比如說當你同事在你提交之前對A文件做了一些改動并且已經提交到了遠程倉庫,你改動了B文件,然后提交時肯定要先將人家修改的A文件先`pull`下來再提交,否則的話你直接上`--force`不久把人家的代碼直接給強制覆蓋了嗎?注意這一點,小心讓同事拿刀砍你。
> 使用`git reflog`命令可以查看所有本地倉庫(版本區)的改動,包括`pull`、`reset`、`commit`
```
[root@supman git]# git reflog
f058de8 HEAD@{0}: pull: Fast-forward
1c07240 HEAD@{1}: pull: Fast-forward
a36b4ed HEAD@{2}: reset: moving to HEAD^
1c07240 HEAD@{3}: reset: moving to HEAD^
fda1d98 HEAD@{4}: reset: moving to HEAD^
d967d87 HEAD@{5}: commit: 修改sencond.txt
fda1d98 HEAD@{6}: commit: 修改first.txt
a36b4ed HEAD@{7}: commit: 第一次提交
c55da94 HEAD@{8}: commit: 第二次提交
e58e53e HEAD@{9}: commit (initial): 第一次提交
```
> 可以根據`reflog`的這些信息將本地倉庫切換到任意一個版本,切換的方式可以是版本號切換如:`git reset --hard d967d87` 也可以利用`HEAD`來切換如:`git reset --hard HEAD@{1}`
```shell
[root@supman git]# git reset --hard d967d87
HEAD 現在位于 d967d87 修改sencond.txt
[root@supman git]# git reflog
d967d87 HEAD@{0}: reset: moving to d967d87
f058de8 HEAD@{1}: pull: Fast-forward
1c07240 HEAD@{2}: pull: Fast-forward
a36b4ed HEAD@{3}: reset: moving to HEAD^
1c07240 HEAD@{4}: reset: moving to HEAD^
fda1d98 HEAD@{5}: reset: moving to HEAD^
d967d87 HEAD@{6}: commit: 修改sencond.txt
fda1d98 HEAD@{7}: commit: 修改first.txt
a36b4ed HEAD@{8}: commit: 第一次提交
c55da94 HEAD@{9}: commit: 第二次提交
e58e53e HEAD@{10}: commit (initial): 第一次提交
[root@supman git]# git reset --hard HEAD@{1}
HEAD 現在位于 f058de8 update second.txt.
[root@supman git]# git reflog
f058de8 HEAD@{0}: reset: moving to HEAD@{1}
d967d87 HEAD@{1}: reset: moving to d967d87
f058de8 HEAD@{2}: pull: Fast-forward
1c07240 HEAD@{3}: pull: Fast-forward
a36b4ed HEAD@{4}: reset: moving to HEAD^
1c07240 HEAD@{5}: reset: moving to HEAD^
fda1d98 HEAD@{6}: reset: moving to HEAD^
d967d87 HEAD@{7}: commit: 修改sencond.txt
fda1d98 HEAD@{8}: commit: 修改first.txt
a36b4ed HEAD@{9}: commit: 第一次提交
c55da94 HEAD@{10}: commit: 第二次提交
e58e53e HEAD@{11}: commit (initial): 第一次提交
```