[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): 第一次提交
```