文章目录
Git简介
Git实际上是一个分布式版本控制软件,可以使我们回退到任何修改过的版本。
集中式vs分布式
集中式
版本库集中存放在中央服务器,使用时需要先从中央服务器取得最新版本,最后需要将修改后的版本提交至中央服务器。缺点是需要联网,可能速度比较慢
分布式
没有中央服务器,每个人的电脑上有一个版本库。这样就不需要联网了,当需要多人修改同一个文件时,只需要将各自的修改推送给对方。其实,分布式版本控制系统通常也有一台充当中央服务器的电脑,只是方便交换。
Git安装
Linux
输入git
查看是否已经安装
在Ubuntu
上可以使用如下命令直接安装
sudo apt-get install git
Windows
在官网直接下载即可,之后使用Git Base
进行用户设置
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"
这是为我们创建标识信息,因为在进行版本推送的时候,需要自报家门,知道是谁推送,是谁在修改。
git config
命令的--global
参数,表示这台机器上的所有Git
仓库都是用这个配置,当然也可以针对不同仓库使用不同的用户名和Email地址。
创建版本库
版本库就是一个仓库,是一个目录。这里面的所有文件都能被Git
管理。
通过git init
将一个目录变为Git
可管理的仓库。这其实就是在当前文件夹重创建了一个.git
文件夹,这个文件夹就是用来管理版本库的,不要手动修改。
所有的版本控制系统,只能跟踪文本文件的改动,比如.txt
文件。版本控制系统可以明确知道我们在文本文件中进行和怎么样的修改。而图片,视频这种二进制文件,版本控制系统则不能跟踪其变化,只能知道有改动,但不知道具体改了什么。
- 注意:
Word
文件是二进制格式的,因此版本控制系统也无法进行跟踪
将文件添加到版本库
我们创建一个readme.txt
文件,内容如下
Day1:Git learn
This is a readme
第一步,使用git add
将文件添加到仓库(git add .
代表添加所有文件)
$ git add readme.txt
- 命令执行完后将不会有任何指示,这代表
add
成功
第二步,使用git commit
把文件提交到仓库
$ git commit -m "first commit"
-
commit
之后将会提示本次提交对文件做了哪些修改1 file changed, 2 insertions(+)
create mode 100644 readme.txt
-m
后面输入的是本次提交的说明,可以输入任意内容,用于说明本次提交的意义。
git commit
是原子性的,要么一次全部成功,要么全部失败。提供git add
命令使得我们可以分阶段提交,可以多次add
之后再决定commit
。
工作区管理
文件修改
我们修改readme.txt
,其内容变为
Day1:Git learn
This is a readme
One change
现在运行git status
查看当前库的状态
git status
可以让我们掌握仓库当前的状态
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
输出结果告诉我们readme.txt
被修改,但未提交。
如果我们想要查看修改的内容,可以使用git diff
git diff
顾名思义就是查看difference
$ git diff
diff --git a/readme.txt b/readme.txt
index db8c883..47508c9 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,2 +1,3 @@
Day1:Git learn
-This is a readme
\ No newline at end of file
+This is a readme
+One change
\ No newline at end of file
这显示我们删除了哪些内容,增加了哪些内容
之后我们可以再提交,和上面一样,先git add
再git commit
就可以了。
使用git status
可以查看工作区状态,使用git diff
可以查看修改内容
版本回退
Git
保存的是文件的一些快照,每一次commit
就是对当前库进行一次拍照,这些快照是被保存下来的,我们可以取出一张照片,将当前的库恢复到前面任意一次commit
。
使用git log
可以查看历史commit
,历史记录由按时间由近到远排列,每条记录由 commit id
(版本号),用户,时间和说明信息构成
Git
内部有个指向当前版本的HEAD
指针,进行版本的变更实际上就是将HEAD
指针指向不同版本,并且进行了工作区更新
$ git log
commit a39403bd2eddf8c67bcc307324c8a58b28f36049 (HEAD -> master)
Author: nsy <[email protected]>
Date: Thu Jul 28 15:09:10 2022 +0800
add one change
commit 3ab2b08042cc38adc3c5826172fdba826966e53f
Author: nsy <[email protected]>
Date: Thu Jul 28 14:50:36 2022 +0800
This is first commit
如果认为输出信息太多,可以使用git log --pretty=oneline
,这将使每个commit
记录输出为一行
$ git log --pretty=oneline
a39403bd2eddf8c67bcc307324c8a58b28f36049 (HEAD -> master) add one change
3ab2b08042cc38adc3c5826172fdba826966e53f This is first commit
在Git
中HEAD
表示当前版本,就是最新提交的版本。上一个版本就是HEAD^
,上上个版本就是HEAD^^
。当^的数量过多时(比如100),我们可以通过HEAD~100
来表示。
当回退时我们使用git reset
命令
git reset
和git --hard reset
,前者只是对暂存区起效果,后者是对暂存区和工作区都起效果
$ git reset --hard HEAD^
HEAD is now at 3ab2b08 This is first commit
这样,我们就回退到了上一个版本。
如果我们还想回到刚刚的版本怎么办?回退到旧的版本之后还能回去么?
- 我们只要找到刚刚那个版本的
commit id
就可以了。
我们可以使用git reflog
来查询每一次命令
$ git reflog
3ab2b08 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
a39403b HEAD@{1}: reset: moving to a39403b
3ab2b08 (HEAD -> master) HEAD@{2}: reset: moving to HEAD^
a39403b HEAD@{3}: reset: moving to a39403b
3ab2b08 (HEAD -> master) HEAD@{4}: reset: moving to HEAD^
a39403b HEAD@{5}: commit: add one change
3ab2b08 (HEAD -> master) HEAD@{6}: commit (initial): This is first commit
我们可以看到,刚刚那个版本commit
的id
是a39403b
,这样我们就可以使用git reset
命令回到刚刚的版本了
git reser --hard a39403b
HEAD is now at a39403b add one change
工作区和暂存区
工作区
电脑里能看到的目录,比如一个文件夹就是一个工作区
版本库
工作区中有一个目录.git
,这个不是工作区,而是Git
的版本库。
Git
的版本库中存了很多东西,最重要的就是stage
(暂存区),还有Git
为我们自动创建的一个分支master
,以及一个指向master
的指针HEAD
我们向版本库中添加文件是分两步进行的
- 使用
git add
将文件修改添加到暂存区 - 使用
git commit
提交更改,就是将暂存区的所有内容提交到当前分支。因为Git
自动为我们创建了一个分支,所以我们提交的时候,其实就是提交到分支master
管理修改
Git
跟踪并管理的是修改,而不是文件
源文件如下
Day1:Git learn
This is a readme
One change
我们做第一次修改
Day1:Git learn
This is a readme
First change
然后执行 git add
,并检查状态
$ git add readme.txt
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: readme.txt
之后我们再次更改文件内容
Day1:Git learn
This is a readme
First change
Second change
然后检查工作区状态
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: readme.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: readme.txt
- 我们发现,有一个已经
add
的readme.txt
,有一个没有还没有被add
的readme.txt
,这就证明Git
跟踪的是修改,而不是文件 - 如果我们想将第二次修改也添加到暂存区,可以再次执行
git add
,然后再用git commit
将两次修改同时提交
撤销修改
我们在 readme.txt
的最后一行添加"Want to use checkout"
$ cat readme.txt
Day1:Git learn
This is a readme
First change
Second change
Want to use checkout
使用git checkout -- file
可以使文件回到最近一次git commit
或 git add
时的状态
$ git checkout -- readme.txt
- 若文件自修改后还没有被放到暂存区,则撤销修改就回到和版本库一样的状态(回复到最近一次
git commit
的状态) - 如果已经添加到暂存区又进行修改,那么撤销修改就回到刚添加到暂存区后的状态(回复到最近一次
git add
的状态)
如果我们进行了一些不想要的修改,且已经使用 git add
添加到暂存区,但是还没有提交。这时,我们可以通过git reset HEAD <file>
来将暂存区的修改撤销掉
$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: readme.txt
$ git reset HEAD readme.txt
Unstaged changes after reset:
M readme.txt
$ git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
- 这时我们就将
add
操作撤销了,然后再使用git checkout
就能恢复
git reset
既可以回退版本,也可以撤销暂存区的修改
删除文件
我们删除文件在Git
看来也是修改操作。一般情况下,我们删除文件是直接在工作区(文件夹中)进行删除,这时候版本库和就和工作区不一样了。我们有两种选择
-
将版本库中的该文件也删除,使用
git rm
命令,之后进行提交$ git rm readme.txt $ git commit -m "remove readme.txt"
-
如果是误删,可以利用版本库来恢复工作区中的文件(其实就是将文件回复到最后一次
commit
之后)$ git checkout -- test.txt