手把手教你入门Git — Git使用指南(Linux)
系统:ubuntu 18.04 LTS
本文所有git命令操作实验具有连续性,git小白完全可以从头到尾跟着本文所有给出的命令走一遍,就会对git有一个初步的了解,应当能做到会用并且大致了解git的版本控制机制,遇到问题的话欢迎留言或私信博主。
git安装及配置
1 git安装
sudo apt-get install git
可通过git --version 命令查看,正常输出git版本号即安装成功。
2 配置用户名和邮箱名
git config --global user.name "Your Name"
git config --global user.email "email@example.com"
配置完后可以通过以下命令查看
git config user.name
git config user.email
3 配置SSH公钥
创建公钥文件,生成的公钥文件会保存在本机的~/.ssh目录下。
ssh-keygen -C 'example@example.com' -t rsa
然后三步询问直接回车即可(连按三次回车)。
创建完成后进~/.ssh目录,将公钥(即id_rsa.pub的内容)复制出来。
cd ~/.ssh
cat id_rsa.pub
如果进入该目录时提示No such file or directory,自己手动创建一个即可:mkdir ~/.ssh。
然后来到浏览器端进行操作,首先登录自己的github账号(没有的话自行注册一个即可),进入到自己的主页,依次点击settings->SSH and GPG keys->New SSH Key,进入到如下页面:

将刚才保存的id_rsa.pub文件内容复制到Key字段,Title自己起个名字,最好是能代表当前所配置的机器的名字。然后点Add SSH key,会要求输入当前github账号的密码,按要求输入就行了。
git本地操作
1 创建仓库并初始化
仓库(repository)也叫版本库,可以看做一个目录,这个目录里的所以文件都由Git进行管理,每个文件的修改、删除,Git都能跟踪。
-
创建一个目录
mkdir learnGit -
将我们新创建的目录初始化为git可以管理的仓库:
cd learnGit git init会输出
Initialized empty Git repository in /home/ps/JJ_Projects/learnGit/.git/,表示成功初始化git仓库。这时会发现该目录中多出了一个
.git目录,这就是git来跟踪管理版本库的。
2 添加文件
-
我们首先创建一个README文件,并写入一些内容:
touch README.txt vim README.txt # 写入 Learning Git: New File. cat README.txt # 查看文件内容 # 输出 Learning Git: New File. -
执行
git add命令,将文件添加的仓库。git add README.txt这条命令不会有输出,具体作用后文会分析,这里我们先走一遍新建文件的步骤。
-
执行
git commit命令,将文件提交的仓库。git commit -m "Submit a new file." # 双引号内是本次提交的注释,原则上可以随便写,但是尽量能表达出本次提交的改动。会输出:
[master (root-commit) 7e21c1f] Submit a new file.1 file changed, 1 insertion(+)create mode 100644 README.txt表示我们已经成功提交一个新文件。
3 修改文件
我们刚刚已经成功提交了一个新文件到我们的git仓库,接下来,我们来看一下怎样修改文件的内容。
-
修改文件内容
vim README.txt # 将其中内容替换为:Learning Git: Modify. -
查看仓库状态
此时,我们可以用
git status命令来查看一下仓库当前的状态:git status # 输出: On branch 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: README.txtno changes added to commit (use "git add" and/or "git commit -a")意思很明显:
README.txt文件提劲被修改过了,但是现在还没有改动需要git submit,因为要先git add。 -
查看文件改动
用
git diff查看文件有哪些改动:git diff # 输出: diff --git a/README.txt b/README.txt index 5107c06..e22e629 100644 --- a/README.txt +++ b/README.txt @@ -1 +1 @@ -Learning Git: New File. +Learning Git: Modify.即我们刚才进行的修改。
-
向上面一样,将修改添加到仓库:
git add README.txt同样没有任何输出,但是这次我们可以用
git status来查看一下仓库当前的状态:git status # 输出: On branch master Changes to be committed:(use "git reset HEAD <file>..." to unstage)modified: README.txt可以看到,已经有一个改动需要被commit了,可以推测add命令应该是将文件的改动放到了某个待提交的临时位置,后面会具体分析。
-
那下一步就是提交咯:
git commit -m "Modify a file." # 输出: [master a493237] Modify a file.1 file changed, 1 insertion(+), 1 deletion(-)文件修改提交成功,我们再查看一下仓库当前状态:
git status # 输出: On branch master nothing to commit, working tree clean我们刚刚把修改都提交了,所以现在没有东西要提交。
4 版本回退
使用git进行版本控制,重要的用途之一就是进行版本回退了,我们来看一下怎样操作。
-
我们先使用
git log命令来查看一下仓库的修改日志:git log # 输出: commit a493237884485d9b0d6c88d64d967293ef5a80b8 (HEAD -> master) Author: user <example@example.com> Date: Wed Aug 18 20:09:27 2021 +0800Modify a file.commit 7e21c1fa1ada0c6b6dce6bef93f0c8e325d716a2 Author: user <example@example.com> Date: Wed Aug 18 19:56:17 2021 +0800Submit a new file.显示出我们之前的两次修改操作。
我们还可以加上
--pretty=online参数:git log --pretty=oneline # 输出: a493237884485d9b0d6c88d64d967293ef5a80b8 (HEAD -> master) Modify a file. 7e21c1fa1ada0c6b6dce6bef93f0c8e325d716a2 Submit a new file. -
我们先查看一下当前README.txt文件中的内容:
cat README.txt # 输出: Learning Git: Modify. # 是我们上次修改文件后的内容。使用
git reset命令,将版本回退:git reset --hard HEAD^ # HEAD表示当前版本,HEAD^表示上一个版本,HEAD^^表示上上版本 输出: HEAD is now at 7e21c1f Submit a new file.在查看一下版本回退之后README.txt中的内容:
cat README.txt # 输出: Learning Git: New File.可以看到,回退到了我们修改文件之前的内容。
5 git的工作区和暂存区
在继续介绍git的本地操作之前,我们先来看一下git的版本管理究竟是怎样进行的。
概念
-
工作区(Working Directory),我们创建的learnGit 目录就是一个工作区。
-
版本库,仓库(Repository),工作区有个隐藏目录 .git ,这个不算工作区,而是 Git 的版本库。
-
版本库里面的 index(stage) 文件叫暂存区,还有Git为我们自动创建的第一个分支 master ,以及指向 master 的一个指针叫做 HEAD。
关系
前面我们提到过,如果我们想把文件添加到Git里面时,需要分两步:
第一步是用 git add 把文件添加进去,实际上就是把文件修改添加到暂存区。
第二步是用 git commit 提交更改,实际上就是把暂存区的所有内容提交到当前分支。(我们现在只有唯一一个分支 master,所以现在就是往 master 分支上提交更改)

6 管理修改
git做版本控制的关键优势在于:git跟踪管理的不是文件,而是修改。
我们做这样一个实验:
-
首先,在
README.txt中添加一行vim README.txt # 添加一行 cat README.txt # 输出: Learning Git: New File. test line 1. -
将此次修改
add并查看状态status:git add README.txt git status # 输出: On branch master Changes to be committed:(use "git reset HEAD <file>..." to unstage)modified: README.txtps@rong:~/JJ_Projects/learnGit$这时我们先不提交,而是再对
README.txt进行一次修改,按照我们之前的分析,现在我们的第一次修改应该是保存在暂存区。 -
再次修改文件
vim README.txt # 再添加一行 cat README.txt # 输出: Learning Git: New File. test line 1. test line 2. -
不对第二次修改进行
add,直接commit。现在的应该是第一次修改在暂存区,第二次修改在工作区没动。git commit -m "test" # 输出: [master 611366c] test1 file changed, 1 insertion(+)然后我们查看一下状态:
git status # 输出: On branch 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: README.txtno changes added to commit (use "git add" and/or "git commit -a")我们可以发现,第二次修改并没有被提交。
因为在工作区的第一次修改被放入暂存区,准备提交;而在工作区的第二次修改并没有被放入暂存区,所以,
git commit命令只负责把暂存区的修改提交了。 -
提交后,我们可以用
git diff HEAD -- readme.txt命令去查看工作区和版本库里面最新版本的区别:git diff HEAD -- README.txt # 输出: diff --git a/README.txt b/README.txt index be48ea2..0afce83 100644 --- a/README.txt +++ b/README.txt @@ -1,2 +1,3 @@Learning Git: New File.test line 1. +test line 2.
7 撤销修改
本地git的撤销修改操作有三种具体情况,分别是:
(1) 仅修改文件,没有add,此时修改仅在工作区。
(2) 修改文件后add过,但是没有commit ,此时修改保存在暂存区。
(3) 修改文件后,add并commit,此时修改已经提交到仓库。
接下来我们一个一个看。
-
仅修改文件,没有
add,此时修改仅在工作区我们上一个实验的第二次修改只存在工作区,并未
add,刚好符合第一种情况,这时的状态应该是这样的:git status # 输出: On branch 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: README.txtno changes added to commit (use "git add" and/or "git commit -a")其实
status的输出信息已经提示到我们了,此时使用checkout命令即可:git checkout -- README.txt然后我们查看一下文件内容和状态信息:
cat README.txt # 输出: Learning Git: New File. test line 1. git status On branch master nothing to commit, working tree clean完美撤销。
-
修改文件后
add过,但是没有commit,此时修改保存在暂存区我们再添加一行测试、
add,并查看此时状态:vim README.txt # 添加一行 git add README.txt git status # 输出: On branch master Changes to be committed:(use "git reset HEAD <file>..." to unstage)modified: README.txt还是可以从输出信息看到,可以使用
reset命令将放到暂存区的修改退回到工作区。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 checkout -- <file>..." to discard changes in working directory)modified: README.txtno changes added to commit (use "git add" and/or "git commit -a")从上面的状态输出可以看到,修改已经成功地退回到工作区了。
现在就转到了情况1,再用
checkout命令撤销就可以了。git checkout -- README.txt git status # 输出: On branch master nothing to commit, working tree clean -
改文件后,
add并commit,此时修改已经提交到仓库这时已经完车了修改的提交,只能进行版本回退了,上面4已经介绍,这里不再赘述。
8 删除文件与恢复
-
我们先准备一个待删除的文件
test.txt,并add、commit到仓库,这一套大家想必已经熟的不能再熟了,我们直接走一遍。touch test.txt vim test.txt # 添加内容 delete test git add test.txt git commit -m "delete test" # 输出: [master 08ffedc] delete test1 file changed, 1 insertion(+)create mode 100644 test.txt -
在工作区中直接删除
test.py:rm test.py这时有两种情况:
(1) 工作区中误删文件,需要恢复
(2) 确实要删除文件,应该把删除操作提交到仓库
-
工作区中误删文件,需要恢复
这种情况其实与上面的撤销修改情况1是一样的,要将工作区的动作撤销掉,而这在我们的仓库中还是存在的,所以还是要请出我们的
checkout命令就好了。git checkout -- test.txt ls # 输出: README.txt test.txt可以看到,我们刚刚在工作区
rm掉的test.txt文件已经回来了 -
确实要删除文件,应该把删除操作提交到仓库
我们先把刚刚恢复的
test.txt再从工作区删掉。rm test.txt既然我们确实要删掉该文件,就直接再用
git rm删除:git rm test.py # 输出: rm 'test.txt'再将删除操作提交到仓库:
git commit -m "delete test" # 输出: [master 9182ef7] delete test1 file changed, 1 deletion(-)delete mode 100644 test.txt就大功告成啦。
git远程操作
注意:远程仓库操作需要已经完成SSH公钥的配置。
新建远程仓库并关联本地仓库
- 我们先来到网页端进行操作,登录github之后,直接点绿色的小new,新建仓库。

-
网页端创建完仓库后回到本地命令行运行如下命令,添加远程仓库:
git remote add origin git@github.com:adenialzz/learngit.git注意改成自己的用户名,这条命令不会有输出。添加后,远程库的名字就是 origin ,这是Git默认的叫法。
-
然后,我们就可以使用
git push命令将本地仓库推到远程仓库。git push -u origin master # 输出: Counting objects: 10, done. Delta compression using up to 20 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (10/10), 816 bytes | 816.00 KiB/s, done. Total 10 (delta 1), reused 0 (delta 0) remote: Resolving deltas: 100% (1/1), done. remote: This repository moved. Please use the new location: remote: git@github.com:Adenialzz/learnGit.git To github.com:adenialzz/learngit.git* [new branch] master -> master Branch 'master' set up to track remote branch 'master' from 'origin'.因为远程库是空的,所以我们在第一次推送 master 分支时,要加上 -u 参数,Git不但会把本地的
master 分支内容推送的远程新的 master 分支,还会把本地的master 分支和远程的 master 分支关联起来,在以后的推送或者拉取时就可以简化命令。这时,我们再到网页端查看,就可以看到我们的本地仓库的全部内容已经推倒远程仓库(当然,这里只有一个文件,因为我们的
test.txt已经被删除掉了)。

将本地仓库推到远程
我们新建一个LICENSE.txt文件,提交到本地仓库,并推到远程,这些操作上面到介绍过了,这里简单过一遍,
touch LICENSE.txt
vim LICENSE.txt # 添加内容
git add LICENSE.txt
git commit -m "add LICENSE"
git push origin master
需要注意的是在第一次关联过仓库之后,再推到远程时,只需git push origin master,即可把本地 master 分支的最新修改推送至GitHub。现在,我们拥有了真正的分布式版本库。

将远程仓库拉到本地
这个应该是平时没有深入了解git之前最常用的命令了(^^),将别人的代码拉到本地。
-
点击上图的绿色的Code,将其中内容复制下来
-
在本地使用
clone命令进行拉取:git clone https://github.com/Adenialzz/learnGit.git
git卸载
先找到git的目录:通过which git命令,得到/usr/bin/git。
然后完全删除该目录,并卸载git:
sudo rm -r /usr/bin/git
sudo apt-get remove git
注意要完全卸载git,以上两步缺一不可。