git
创建版本库
- 选择一个合适的地方,创建一个空目录:
$ mkdir learngit |
- 通过
git init
命令把这个目录变成Git可以管理的仓库:
$ git init |
在文件夹目录下面会出现一个 .git 的目录,这个目录的作用是Git来跟踪版本管理库的,对于该文件夹下面的文件修改要慎重,盲目修改可能会导致版本库出现问题。
如果你没有看到.git目录,那是因为这个目录默认是隐藏的,用ls -ah命令就可以看见。
也不一定必须在空目录下创建Git仓库,选择一个已经有东西的目录也是可以的。
将文件提交到仓库的步骤
- 用命令
git add
告诉Git,把文件添加到仓库:
$ git add readme.txt |
执行上面的命令,没有任何显示,这就对了,Unix的哲学是“没有消息就是好消息”,说明添加成功。
- 用命令
git commit
告诉Git,把文件提交到仓库
$ git commit -m "wrote a readme file" |
git commit
命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。
git commit
命令执行成功后会告诉你,1 file changed:1个文件被改动(我们新添加的readme.txt文件);2 insertions:插入了两行内容(readme.txt有两行内容)。
为什么Git添加文件需要add,commit一共两步呢?因为commit可以一次提交很多文件,所以你可以多次add不同的文件,比如:
$ git add file1.txt |
版本回退
git status
git status 命令可以让我们时刻掌握仓库当前的状态
$ git status |
上面的命令输出告诉我们,readme.txt被修改过了,但还没有准备提交的修改。
git diff
git diff
顾名思义就是查看difference,显示的格式正是Unix通用的diff格式.
$ git diff readme.txt |
从上面的命令可以看出。我们在第一行中添加了一个单词 perfect
当知道了对readme.txt作了什么修改后,再把它提交到仓库就放心多了。
提交修改和提交新文件是一样的两步:
第一步是git add:
$ git add readme.txt |
命令在执行之后同样没有任何提示。不过我们可以通过 git status
命令来了解到当前仓库的存在。
$ git status |
提交后,我们再用git status命令看看仓库的当前状态:
$ git status |
Git告诉我们当前没有需要提交的修改,而且,工作目录是干净(working tree clean)的。
git log
git log
命令显示从最近到最远的提交日志,我们可以看到3次提交,最近的一次是append GPL
,上一次是add distributed
,最早的一次是wrote a readme file
。
加上–pretty=oneline参数: 可以减少输出信息。
$ git log --pretty=oneline |
git log 的退出方法: 输入字母Q即可退出.
git reset
git reset命令:把当前版本回退到上一个版本add distributed.
$ git reset --hard ba4ce482d04b |
git reflog
Git提供了一个命令git reflog用来记录你的每一次命令: 想恢复到新版本,可以通过git reflog
找到新版本的commit id
$ git reflog |
总结:
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id。
穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。
要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。
工作区和暂存区
工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区:
版本库(Repository)
工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit提交更改,实际上就是把暂存区的所有内容提交到当 前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master分支,所以,现在,git commit就是往master分支上提交更改。
现在测试一下:
- 先对readme.txt做个修改,比如加上一行内容:
Git is a distributed version control system. |
- 然后,在工作区新增一个LICENSE文本文件(内容随便写)。
先用git status查看一下状态:
$ git status |
Git非常清楚地告诉我们,readme.txt被修改了,而LICENSE还从来没有被添加过,所以它的状态是Untracked。
现在,使用两次命令git add,把readme.txt和LICENSE都添加后,用git status再查看一下:
$ git status |
现在,暂存区的状态就变成这样了:
所以,git add命令实际上就是把要提交的所有修改放到暂存区(Stage),然后,执行git commit就可以一次性把暂存区的所有修改提交到分支。
$ git commit -m "understand how stage works" |
一旦提交后,如果你又没有对工作区做任何修改,那么工作区就是“干净”的:
$ git status |
现在版本库变成了这样,暂存区就没有任何内容了:
撤销修改
git checkout = git switch + git restore
git checkout -- file
可以撤销修改,丢弃在工作区的修存在两种情况。
-
一种是readme.txt自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;
-
一种是readme.txt已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态。
总之,就是让这个文件回到最近一次git commit或git add时的状态。
现在举例说明上述两种情况:
第一种情况:文件修改后还没有被放到暂存区
修改过的文件(添加了最后一行):
$ cat readme.txt |
git status
观察一下情况 (修改后)
$ git status |
现在让我们测试一下撤销修改的命令
$ git checkout -- readme.txt |
git status
观察一下情况(撤销后)
$ git status |
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
|
$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.
Git has a mutable index called stage.
Git tracks changes of files.
My stupid boss still prefers SVN.
|
git add readme.txt
|
$ git status
On branch master
Changes to be committed:
(use “git restore --staged
modified: readme.txt
可以看到,修改只是提交到了暂存区,还没有提交。 |
$ git reset HEAD readme.txt
Unstaged changes after reset:
M readme.txt
`git reset`命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。 |
$ git status
On branch master
Changes not staged for commit:
(use “git add
(use “git restore
modified: readme.txt
no changes added to commit (use “git add” and/or “git commit -a”)
现在暂存区是干净的,工作区有修改: |
$ git checkout – readme.txt
$ git status
On branch master
nothing to commit, working tree clean
使用`git status`查看,发现工作目录是干净的。 |
$ git commit -m “add test.txt”
[master 4b29612] add test.txt
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 test.txt
|
$ git status
On branch master
Changes not staged for commit:
(use “git add/rm
(use “git restore
deleted: test.txt
no changes added to commit (use “git add” and/or “git commit -a”)