> 本文由云+社区发表
> 作者:工程师小熊
摘要:上一集我们一起入门学习了git的基本概念和git常用的操作,包括提交和同步代码、使用分支、出现代码冲突的解决办法、紧急保存现场和恢复现场的操作。学会以后已经足够我们使用Git参加协作开发了,但是在开发的过程中难免会出错,本文主要介绍版本控制的过程中出错了的场景,以及Git开发的一些技巧,让我们用的更流畅。
上集回顾:
- Git的基本概念
- 一个人使用Git时的代码版本控制--(提交、拉代码、分支操作)
- 多人合作时的代码版本控制--(合并冲突、暂存代码)
本文核心:
- 后悔药-各种后悔操作(撤消commit,回滚,回退远程仓库等)
- 哎呀,提交的时候漏了文件
- tag操作
- git忽略不想提交的文件
# 后悔药
## 撤消当前commit
如果你发现刚刚的操作一不小心commit了,所幸你还没有推送到远程仓库,你可以用`reset`命令来撤消你的这次提交。
`reset`命令的作用:重置HEAD(当前分支的版本顶端)到另外一个commit。
> 我们的撤消当前提交的时候往往不希望我们此次提交的代码发生任何丢失,只是撤消掉commit的操作,以便我们继续修改文件。如果我们是想直接不要了这次commit的全部内容的任何修改我们将在下一小节讨论。
来,我们先说一句蠢话来diss老板
```js
$ touch to_boss.txt
$ echo 'my boss is a bad guy!' > to_boss.txt
$ git add to_boss.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: to_boss.txt
$ git commit -m "[+]骂了我的boss"
[master 3d113a7] [+]骂了我的boss
1 file changed, 1 insertion(+)
create mode 100644 to_boss.txt
```
- 创建to_boss.txt文件,并向其写入了`my boss is a bad guy!`
- `add`然后`status`查看新文件已经加入跟踪
- `commit`提交了这次的修改
好了,刚刚我们“不小心”diss了我们的老板,要是被发现就完了,所幸还没有`push`,要快点撤消这些提交,再换成一些好话才行。
我们使用以下命令:
```js
$ git reset --soft head^
$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: to_boss.txt
$ cat to_boss.txt
my boss is a bad guy!
$ echo 'my boss is a good boy!'
my boss is a good boy!
$ echo 'my boss is a good boy!' > to_boss.txt
$ cat to_boss.txt
my boss is a good boy!
$ git add to_boss.txt
$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: to_boss.txt
$ git commit -m "[*]夸了我的boss"
[master 8be46aa] [*]夸了我的boss
1 file changed, 1 insertion(+)
create mode 100644 to_boss.txt
```
- `git reset --soft head^`撤消了本次提交,将工作区恢复到了提交前但是已经`add`的状态
- 将`to_boss.txt`的内容改成了`my boss is a good boy!`
- `add`然后`commit`提交
好了,有惊无险,这就是撤消commit的操作。另一种情况是如果你想撤消commit的时候支持舍弃这次全部的修改就把`git reset --soft head^`改成`git reset --hard head^`,这样你本地修改就彻底丢掉了(慎用),如果真用了想找回来怎么办?见救命的后悔药。
当然了,你只要开心不加`soft`或`hard`参数也是安全的(相当于使用了`--mixed`参数),只不过是撤消以后你的本次修改就会回到`add`之前的状态,你可以重新检视然后再做修改和`commit`。
## 回退远程仓库
要是我们做的更过分一点,直接把这次`commit`直接给`push`怎么办?要是被发现就全完了,我们来看看github上的远程仓库。
![img](https://ask.qcloudimg.com/http-save/3097464/1yvi70klfr.png?imageView2/2/w/1620)upload successful
完了,真的提交了(我刚刚push的)让我们冷静下来,用撤消当前commit的方法先撤消本地的`commit`,这次我们来试试用`hard`参数来撤消
```js
$ git reset --hard head^
HEAD is now at 3f22a06 [+]add file time.txt
$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
nothing to commit, working tree clean
$ git push origin master --force
Total 0 (delta 0), reused 0 (delta 0)
To github.com:pzqu/git_test.git
+ 3d113a7...3f22a06 master -> master (forced update)
```
- 使用`git reset --hard head^`回滚到上一个`commit`
- 使用`git status`查看现在的工作区情况,提示`Your branch is behind 'origin/master' by 1 commit`,代表成功表了上一次的提示状态,`nothing to commit, working tree clean`代表这次的修改全没了,清理的算是一个彻底。如果还想找回来怎么办,我们还真是有办法让你找回来的,见救命的后悔药。
- `git push origin master --force` 命令强制提交到远程仓库(注意,如果是在团队合作的情况下,不到迫不得已不要给命令加--force参数) 让我们看看`github`
![img](https://ask.qcloudimg.com/http-save/3097464/p691jg1e1w.png?imageView2/2/w/1620)upload successful
真的撤消了远程仓库,长舒一口气。
## 暂存区(Stage)到工作区(Working Directory)
如果我们刚刚执行了`git reset --soft`或者`add`等的操作,把一些东西加到了我们的暂存区,比如日志文件,我们就要把他们从暂存区拿出来。
```js
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: mysql.log
$ git reset -- mysql.log
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
mysql.log
nothing added to commit but untracked files present (use "git add" to track)
```
- `status`查看暂存区,里面有一个mysql.log被放进去了
- `git reset -- mysql.log`把`mysql.log`取出来
- `status`可以看到真的取出来了 然后如果不要想这个文件的话再rm掉就好啦,但是如果这些文件每次自动生成都要用这种方式取出暂存区真的好累,我们可以用 git忽略不想提交的文件
## 回滚文件到某个提交
当我们想要把某个文件任意的回滚到某次提交上,而不改变其他文件的状态我们要怎么做呢?
我们有两种情况,一种是,只是想在工作区有修改的文件,直接丢弃掉他现在的修改;第二种是想把这个文件回滚到以前的某一次提交。我们先来说第一种:
### 取消文件在工作区的修改
```js
$ cat time.txt
10:41
$ echo 18:51 > time.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: time.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ cat time.txt
18:51
$ git checkout -- time.txt
$ cat time.txt
10:41
```
- 更新`time.txt`的内容,可以`status`看到他发生了变化
- `git checkout -- time.txt` , 取消这次在工作区的修改,如果他已经被`add`加到了暂存区,那么这个命令就没有用了,他的意思是取消本次在工作区的修改,去上一次保存的地方。如果没有`add`就回到和版本库一样的状态;如果已经加到了暂存区,又做了修改,那么就回加到暂存区后的状态将文件回滚到任意的版本我们这里说的把文件回滚到以前的某个版本的状态,完整的含义是保持其他文件的内容不变,改变这个文件到以前的某个版本,然后修改到自己满意的样子和做下一次的提交。
核心命令
```js
git checkout [<options>] [<branch>] -- <file>...
```
我们还是用`time.txt`这个文件来做试验,先搞三个版本出来,在这里我已经搞好了,来看看:
版本1,time.txt内容00:50
```js
commit 35b66ed8e3ae2c63cc4ebf323831e3b917d2b1d4 (HEAD -> master, origin/master, origin/HEAD)
Author: pzqu <pzqu@example.com>
Date: Sun Dec 23 00:51:54 2018 +0800
[*]update time to 00:50
```
版本2,time.txt内容18:51
```js
commit 856a74084bbf9b678467b2615b6c1f6bd686ecff
Author: pzqu <pzqu@example.com>
Date: Sat Dec 22 19:39:19 2018 +0800
[*]update time to 18:51
```
版本3,time.txt内容10:41
```js
commit 3f22a0639f8d79bd4e329442f181342465dbf0b6
Author: pzqu <pzqu@example.com>
Date: Tue Dec 18 10:42:29 2018 +0800
[+]add file time.txt
```
现在的是版本1,我们把版本3检出试试。
```js
$ git checkout 3f22a0639f8d -- time.txt
$ cat time.txt
10:41
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: time.txt
```
- 使用`checkout`+`commit id`+`-- filename`的组合,横跨版本2把历史版本3的`time.txt`搞出来了
- 查看状态,time.txt被改变了
我们来把time.txt恢复到版本1,同样的方法,因为版本1是上一次提交我们可以省略掉版本号
```js
$ git checkout -- time.txt
$ cat time.txt
00:50
```
看到了吧!只要用`git checkout commit_id -- filename`的组合,想搞出哪个文件历史版本就搞出哪个。
到了这里,你可能会很懵比,`reset`和`checkout`命令真的好像啊!都可以用来做撤消
- `checkout`语义上是把什么东西取出来,所以此命令用于从历史提交(或者暂存区域)中拷贝文件到工作目录,也可用于切换分支。
- `reset`语义上是重新设置,所以此命令把当前分支指向另一个位置,并且有选择的变动工作目录和索引。也用来在从历史仓库中复制文件到索引,而不动工作目录。
还想不通可以给我发邮件:pzqu@qq.com
## 救命的后悔药
来到这里我已经很清楚的你的现况了,你的代码丢了现在一定非常的着急,不要慌,总是有办法找回他们的。但是前提是要保证你的项目根目录下.git文件夹是完整的,要是手动删除了里面的一些东西那就真完了。还要保证一点,你的代码以前是有过git追踪的,最少`add`过
### 找回你丢失的历史记录
Git提供了一个命令`git reflog`用来记录你的每一次命令,贴个图吧直观点:
![img](https://ask.qcloudimg.com/http-save/3097464/74n0a6vtv9.png?imageView2/2/w/1620)upload successful
- 有没有发现,`git reflog`里的全部都是和改变目录树有关的,比如`commit rebase reset merge`,也就是说一定要有改变目录树的操作才恢复的回来
- 像add这种操作就不能恢复了吗?那肯定不是,只是要用更麻烦点的方式来恢复
- `git log`是一样的,也可以看到所有分支的历史提交,不一样的是看不到已经被删除的 `commit` 记录和 `reset rebase merge` 的操作 我们可以看到`git reflog`前面的就是`commit id`,现在我们就可以用之前介绍过的方法来回滚版本了,撤消当前commit
```js
$ git reset --hard 856a740
HEAD is now at 856a740 [*]update time to 18:51
$ git log -1
commit 856a74084bbf9b678467b2615b6c1f6bd686ecff (HEAD -> master)
Author: pzqu <pzqu@example.com>
Date: Sat Dec 22 19:39:19 2018 +0800
[*]update time to 18:51
$ git reset --hard 35b66ed
HEAD is now at 35b66ed [*]update time to 00:50
$ git log -2
commit 35b66ed8e3ae2c63cc4ebf323831e3b917d2b1d4 (HEAD -> master, origin/master, origin/HEAD)
Author: pzqu <pzqu@example.com>
Date: Sun Dec 23 00:51:54 2018 +0800
[*]update time to 00:50
commit 856a74084bbf9b678467b2615b6c1f6bd686ecff
Author: pzqu <pzqu@example.com>
Date: Sat Dec 22 19:39:19 2018 +0800
[*]update time to 18:51
```
- 根据`git reflog`返回的结果,用`git reset --hard commit_id`回退到`856a740`这个版本
- `git log -1`看近一行的日志,可以看到目前就在这了
- 再根据`git reflog`的结果,用`git reset --hard 35b66ed`跑到这次提交
- `git log -2`看到两次提交的日志,我们就这么再穿梭过来了,就是这么爽 但是我们如果只是想把此提交给找回来,恢复他,那还是不要用`reset`的方式,可以用`cherry-pick`或者`merge`来做合并
### 找回忘记提交的历史记录
你之前没有commit过的文件,被删除掉了,或者被`reset --hard`的时候搞没了,这种情况可以说是相当的难搞了,所幸你以前做过`add`的操作把他放到过暂存区,那我们来试试找回来,先来创建一个灾难现场
```js
$ echo 'my lose message' > lose_file.txt
$ git add lose_file.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: lose_file.txt
$ git reset --hard 35b66ed8
HEAD is now at 35b66ed [*]update time to 00:50
$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
$ ls
README.md need_stash.txt share_file.txt time.txt
```
- 创建一个叫`lose_file.txt`的文件并写入内容`my lose message`,并把他加到暂存区
- 用`git reset --hard 35b66ed8`用丢弃一切修改的方式来使现在的工作区恢复到`35b66ed8`版本,因为还没提交所以也就是恢复到当前的(`head`)版本。
- 我们用`status`和`ls`再看,这个叫`lose_file.txt`的文件真的没了,完蛋了,第一反应用刚刚学到的命令`git reflow`会发现根本就不好使
核心命令:`git fsck --lost-found`,他会通过一些神奇的方式把历史操作过的文件以某种算法算出来加到`.git/lost-found`文件夹里
```js
$ git fsck --lost-found
Checking object directories: 100% (256/256), done.
Checking objects: 100% (3/3), done.
dangling blob 7f5965523d2b9e850b39eb46e8e0f7c5755f6719
dangling commit fdbb19cf4c5177003ea6610afd35cda117a41109
dangling commit 8be46aa83f0fe90317b0c6b9c201ad994f8caeaf
dangling blob 11400c1d56142615deba941a7577d18f830f4d85
dangling tree 3bd4c055afedc51df0326def49cf85af15994323
dangling commit 3d113a773771c09b7c3bf34b9e974a697e04210a
dangling commit bfdc065df8adc44c8b69fa6826e75c5991e6cad0
dangling tree c96ff73cb25b57ac49666a3e1e45e0abb8913296
dangling blob d6d03143986adf15c806df227389947cf46bc6de
dangling commit 7aa21bc382cdebe6371278d1af1041028b8a2b09
```
这里涉及到git的一些低层的知识,我们可以看到这里有`blob、commit、tree`类型的数据,还有`tag`等类型的。他们是什么含义呢?
![img](https://ask.qcloudimg.com/http-save/3097464/6jwwut9so1.png?imageView2/2/w/1620)upload successful
- `blob`组件并不会对文件信息进行存储,而是对文件的内容进行记录
- `commit`组件在每次提交之后都会生成,当我们进行`commit`之后,首先会创建一个`commit`组件,之后把所有的文件信息创建一个`tree`组件,所以哪个`blob`代表什么文件都可以在`tree` 里找到 我们来看看怎么恢复刚刚不见了的`lose_file.txt`文件,在上面执行完`git fsck --lost-found`命令,返回的第一行`blob`我们看看他的内容
```js
git show 7f5965523d2b9e850b39eb46e8e0f7c5755f6719
my lose message
git show 7f5965523d2b9e850b39eb46e8e0f7c5755f6719 > lose_file.txt
$ ls
README.md lose_file.txt need_stash.txt share_file.txt time.txt
```
- 看到没有,就是我们丢失的文件内容,这样就找回来了! 我们再来看看`commit tree`的内容$ git cat-file -p fdbb19cf4c5177003ea6610afd35cda117a41109 tree 673f696143eb74ac5e82a46ca61438b2b2d3bbf4 parent e278392ccbf4361f27dc338c854c8a03daab8c49 parent 7b54a8ae74be7192586568c6e36dc5a813ff47cf author pzqu <pzqu@example.com> 1544951197 +0800 committer pzqu <pzqu@example.com> 1544951197 +0800 Merge branch 'master' of github.com:pzqu/git_test $ git ls-tree 3bd4c055afedc51df0326def49cf85af15994323 100644 blob c44be63b27a3ef835a0386a62ed168c91e680e87 share_file.txt
- 用`git cat-file -p`可以看到commit的内容,可以选择把这个commit合并到我们的分支里,还是`reset merge rebase cherry-pick`这些命令来合`commit`
- `git ls-tree`列出tree下面的文件名和`id`的记录信息,然后就可以根据这些来恢复文件了
后记:
如果你发现执行`git fsck --lost-found`的输出找不到你想要的,那么在执行完`git fsck --lost-found`后会出现一堆文件 在 .git/lost-found 文件夹里,我们不管他。可以用以下命令来输出近期修改的文件
```js
$ find .git/objects -type f | xargs ls -lt | sed 3q
-r--r--r-- 1 pzqu staff 32 12 23 12:19 .git/objects/7f/5965523d2b9e850b39eb46e8e0f7c5755f6719
-r--r--r-- 1 pzqu staff 15 12 23 01:51 .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
-r--r--r-- 1 pzqu staff 162 12 23 00:51 .git/objects/35/b66ed8e3ae2c63cc4ebf323831e3b917d2b1d4
$ git cat-file -t 7f5965523d2b9e850b39eb46e8e0f7c5755f6719
blob
$ git cat-file -p 7f5965523d2b9e850b39eb46e8e0f7c5755f6719
my lose message
$ git cat-file -t b2484b5ab58c5cb6ecd92dacc09b41b78e9b0001
tree
$ git cat-file -p b2484b5ab58c5cb6ecd92dacc09b41b78e9b0001
100644 blob f9894f4195f4854cfc3e3c55960200adebbc3ac5 README.md
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 need_stash.txt
100644 blob 83f50ec84c00f5935da8089bac192171cfda8621 share_file.txt
100644 blob f0664bd6a49e268d3db47c508b08d865bc25f7bb time.txt
```
- 这里用`find .git/objects -type f | xargs ls -lt | sed 3q`返回了近3个修改的文件,想要更多就改`3q`这个数值,比如你想输出100个就用`100q`
- `git cat-file -t 7f5965523d2b9e850b39eb46e8e0f7c5755f6719` 就能看见文件类型 把最后一个/去掉 复制从objects/ 后面的所有东西放在-t后面
- `git cat-file -p id`就能看见文件内容,是不是很爽
# 漏提交
有时候会碰到我们已经commit但是有修改忘记了提交,想把他们放在刚刚的`commit`里面,这种时候怎么做呢?
```js
$ git log --name-status --pretty=oneline -1
35b66ed8e3ae2c63cc4ebf323831e3b917d2b1d4 (HEAD -> master, origin/master, origin/HEAD) [*]update time to 00:50
M time.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: lose_file.txt
new file: test_amend.txt
$ git commit --amend --no-edit
[master 31cc277] [*]update time to 00:50
Date: Sun Dec 23 00:51:54 2018 +0800
3 files changed, 2 insertions(+), 1 deletion(-)
create mode 100644 lose_file.txt
create mode 100644 test_amend.txt
$ git log --name-status --pretty=oneline -1
31cc2774f0668b5b7c049a404284b19e9b40dc5d (HEAD -> master) [*]update time to 00:50
A lose_file.txt
A test_amend.txt
M time.txt
```
- 查看文件提交日志只有`time.txt`
- stage里还有新的修改在
- 使用`git commit --amend --no-edit`合并到上一个提交里,如果不加`--no-edit`参数的话,会提示你来修改commit提示信息(这个命令也可以用在重复编辑`commit message`)。
- 查看日志,合并提交成功!
# tag标签
## 创建一个tag
标签是一个类似于快照的东西,常常用于测试和发布版本。所以我们常常把`tag`名以版本号来命名,比如:v1.0beat1这样
我们怎么创建标签呢?首先先切换到想打标签的分支,然后直接打就可以了。
```js
$ git branch
dev/pzqu
master
* release_v1.0
$ git tag -a release_v1.0 -m "release v1.0"
$ git tag release_v1.1
$ git tag
release_v1.0
release_v1.1
$ git push --tags
Counting objects: 2, done.
Writing objects: 100% (2/2), 158 bytes | 158.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To github.com:pzqu/git_test.git
* [new tag] release_v1.0 -> release_v1.0
* [new tag] release_v1.1 -> release_v1.1
```
- 切换到想打`tag`的分支
- 创建名为`release_v1.0`带有信息`release v1.0`的`tag`
- 创建的不带有`tag`的提交信息的`release_v1.1`
- `git tag`查看`tag`
- 推送本地全部`tag`
也可以推送单个tag
```js
$ git push origin release_v1.1
Total 0 (delta 0), reused 0 (delta 0)
To github.com:pzqu/git_test.git
* [new tag] release_v1.1 -> release_v1.1
```
我们来删除tag
```js
$ git tag -d release_v1.0
Deleted tag 'release_v1.0' (was eb5d177)
$ git push origin :refs/tags/release_v1.0
To github.com:pzqu/git_test.git
- [deleted] release_v1.0
$ git tag
release_v1.1
```
- 本地删除名为`release_v1.0`的`tag`
- 远程删除名为`release_v1.0`的`tag`
## 对历史提交打tag
先看看当前的log
```js
31cc277 (HEAD -> release_v1.0, tag: release_v1.1, origin/release_v1.0, master) [*]update time to 00:50
856a740 [*]update time to 18:51
3f22a06 [+]add file time.txt
4558a25 (origin/dev/pzqu, dev/pzqu) [*]test stash
d9e018e [*]merge master to dev/pzqu
```
比方说要对`[*]update time to 18:51`这次提交打标签,它对应的commit id是`856a740`,敲入命令:
```js
$ git tag v.9 856a740
$ git log --pretty=oneline --abbrev-commit
31cc277 (HEAD -> release_v1.0, tag: release_v1.1, origin/release_v1.0, master) [*]update time to 00:50
856a740 (tag: v0.9) [*]update time to 18:51
```
- 成功打上
# git忽略不想提交的文件
我们有两种情况,一种是我们根本就不想这些文件出现在git库里比如日志文件;另一种是git远程仓库里有这些文件,就像通用的配置文件,我们必须要在本地修改配置来适应运行环境,这种情况下我们不想每次提交的时候都去跟踪这些文件。
## 忽略自动生成的垃圾文件、中间文件、敏感信息文件
忽略文件的原则是:
1. 忽略操作系统自动生成的文件,比如缩略图等;
2. 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
3. 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
我们要怎么做呢?
> 在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件。$ echo "*.log" > .gitignore$ touch test.log$ touch test2.log$ ls -a . .git README.md need_stash.txt test.log test_amend.txt .. .gitignore lose_file.txt share_file.txt test2.log time.txt$ git status On branch release_v1.0 nothing to commit, working tree clean* 创建并写入忽略规则`*.log`忽略全部以`.log`为后缀的文件 * 创建了`test.log`和`test2.log` * `status`查看,真是工作区是`clean`,新创建的文件没有被跟踪
## 忽略远程存在,本地不想与远程同步的文件
### 添加跟踪忽略
核心命令:
```js
git update-index —assume-unchanged 文件名
```
![img](https://ask.qcloudimg.com/http-save/3097464/q2hvhh77cu.png?imageView2/2/w/1620)upload successful
- 创建`time.txt`文件并写入`10:41`,提交到远程仓库
- 使用命令`git update-index —assume-unchanged`加`time.txt`加到忽略名单里
- 修改`time.txt`的内容为`10:43`
- `status`查看确实没有被跟踪 看远程仓库
![img](https://ask.qcloudimg.com/http-save/3097464/llwhkmq7gp.png?imageView2/2/w/1620)upload successful
### 取消跟踪忽略
核心命令:
```js
git update-index —no-assume-unchanged 文件名
```
![img](https://ask.qcloudimg.com/http-save/3097464/tq670y5w1y.png?imageView2/2/w/1620)upload successful
- `pull`同步远程仓库,真的没有更新刚刚被添加跟踪忽略的文件
- `git update-index —no-assume-unchanged`取消跟踪忽略
- `status`查看,出现文件的跟踪
### 查看跟踪记录
如果忘记了哪些文件被自己本地跟踪
![img](https://ask.qcloudimg.com/http-save/3097464/flvrwc2aez.png?imageView2/2/w/1620)upload successful
- 使用命令`git update-index —assume-unchanged`加`time.txt`加到忽略名单里
- 使用`git ls-files -v| grep '^h\ '`命令可以看到小写h代表本地不跟踪的文件
# 小结
学完本文章,你将学会
- 撤消commit,回滚暂存区,回滚工作区、回退远程仓库
- 两种方法找回不小心丢失的文件
- 提交的时候漏了文件,修改commit的提交信息
- tag操作,创建、创建有描述信息的tag、删除tag、删除远程tag、推送本地单个tag和全部tag
- git忽略自动生成的垃圾文件、中间文件、敏感信息文件;忽略远程存在,本地不想与远程同步的文件并恢复跟踪和查看哪些文件被跟踪
# 注意事项
理论上,git日常用到的命令是 diff show fetch rebase pull push checkout commit status 等,这些命令都不会导致代码丢失,假如害怕代码丢失,可以预先commit一次,再进行修改,但切记
> 不可使用自己不熟悉的命令 任何命令,不要加上-f的强制参数,否则可能导致代码丢失
建议多使用命令行,不要使用图形界面操作
# 下集
# 引用
[git官网](https://git-scm.com/docs)
[廖雪峰的官方网站-git篇](https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000)
[hexo博客部署到vps](https://ihaoming.top/archives/c9c37af.html#more)
[关于git reset --hard这个命令的惨痛教训](https://www.cnblogs.com/hope-markup/p/6683522.html)
[Git 基础再学习之:git checkout -- file](https://www.cnblogs.com/Calvino/p/5930656.html)
[如何理解git checkout -- file和git reset HEAD -- file](https://www.cnblogs.com/instona/p/4243009.html)
**此文已由腾讯云+社区在各渠道发布**
**获取更多新鲜技术干货,可以关注我们[腾讯云技术社区-云加社区官方号及知乎机构号](https://www.zhihu.com/org/teng-xun-yun-ji-zhu-she-qu/activities)**
有疑问加站长微信联系(非本文作者)