我写的这篇文章,主要是记录自己的学习过程,也希望帮助读者少踩坑(比如不同版本可能命令不兼容等)。本文面向git零基础初学者,建议读者按照文中命令自己全部操作一遍(注意运行环境)。
我的运行环境:win10 + VMware + ubuntu 18.04 + git 2.33.0(所有命令均在root用户下执行)
本文参考资料:
[1] 廖雪峰 Git教程
[2] 博客园 一个小时学会Git
[3] Git中文官方文档
资料在精不在多,以上3个资料足以详细解释git的各项命令,建议把这些资料都看一下。从时效性来说,[1]和[2]中的有些命令是老版本的,而[3]的官方文档能看到最新的命令使用方法;从趣味性和易懂性来说,则[1]和[2]更容易让人理解和掌握。当然,本文综合了时效性和易懂性,保证使用新版本的命令,并尽量清楚地表述各个命令的作用。
未经允许,本文禁止转载! 作者:nefu_ljw (本文所有参考资料均在对应位置标明,如有侵权,请联系我删除)
0. Git 安装 & 更新
安装git。
apt install git
查看git版本。
git --version
若版本低于2.23,请更新git。(git 2.23版本新增了switch
、restore
命令,后文会用到)
add-apt-repository ppa:git-core/ppa #adding a Launchpad PPA(Personal Package Archive) repository
apt update
apt install git
1. 基本概念:工作区、暂存区、版本库、远程仓库
- 工作区(Workspace):本地存放文件的地方。Git会知道这里的文件变更,如添加/修改/删除文件。
- 暂存区(Stage/Index):临时存放文件变更信息,事实上它是一个名为
index
的文件。 - 版本库(Repository):工作区有一个隐藏目录
.git
,它是Git的版本库,为了与远程仓库区分,将其明确称为本地版本库(Local Repository)。其中有一个HEAD
指向当前版本库版本。 - 远程仓库(Remote Directory):托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换。
参考: 一个小时学会Git - 工作区域
Directory:使用Git管理的一个目录,也就是一个仓库,包含我们的工作空间和Git的管理空间。
Workspace:需要通过Git进行版本控制的目录和文件,这些目录和文件组成了工作空间。
.git:存放Git管理信息的目录,初始化仓库的时候自动创建。
Index/Stage:暂存区,或者叫待提交更新区,在提交进入repo之前,我们可以把所有的更新放在暂存区。
Local Repo:本地仓库,一个存放在本地的版本库;HEAD只指向当前的开发分支(branch)。
Stash:隐藏,是一个工作状态保存栈,用于保存/恢复Workspace中的临时状态。
2. Git文件操作
在本章,介绍操作git本地仓库的一些常用命令。
2.1 创建仓库(git init)
创建本地仓库的方法有两种:一种是本地创建全新仓库,另一种是克隆远程仓库(请见第4章)。
本地创建全新仓库,初始化一个版本库:
git init
2.2 提交变更(git add, git commit)
下面介绍提交变更到本地版本库的基本流程。
准备工作:先新建一个目录learngit,并创建README.md文件,随便写入一句话。
mkdir learngit
cd learngit
touch README.md
echo "# Hello, git!" >> README.md
添加文件变更到版本库,分两步:
- 使用命令
git add <file>
,可多次使用,添加多个文件。 - 使用命令
git commit -m <message>
,文件从暂存区提交到版本库;<message>
表示提交的信息。
git init #初始化一个git的本地仓库
git add README.md #将工作区README.md文件的变更移动到暂存区
git commit -m "add README.md" #将暂存区提交到本地仓库
2.3 管理变更(git add/rm, git restore)
理解:Git跟踪并管理的是变更,而不是文件。
-
撤销工作区变更(撤销对工作区文件的添加/修改/删除):
git restore <filename>
或git checkout -- <filename>
。 -
撤销暂存区变更(撤销git add/rm):
git restore --staged <filename>
或git reset HEAD <filename>
。
2.23版本的git,考虑到reset
, checkout
存在多种用法对新手来说不易学习,故引入新命令git restore
方便操作。
示例:变更工作区文件后(比如修改/删除文件),使用git restore
撤销工作区/暂存区的变更。
echo "after git add" >> README.md #在工作区修改README.md,用git status可以看到被修改,但这一变更未加到暂存区
git add README.md #变更被加到暂存区
git restore --staged README.md #撤销暂存区的变更(README.md的修改),注意,此时工作区文件还是没有变
git restore README.md #撤销工作区的变更,即工作区README.md文件被还原成修改前
git rm README.md #在工作区删除README.md,并且这一变更被加到暂存区
git restore --staged README.md #撤销暂存区的变更(README.md的删除),注意,此时工作区文件还是没有变
git restore README.md #撤销工作区的变更,即工作区README.md文件被还原成删除前
git rm README.md
等价于以下两句:
rm README.md #在工作区中删除README.md,但这一变更没有被加到暂存区
git add README.md #将对README.md的变更加到暂存区
2.4 版本回退(git reset)
Git允许我们在版本的历史之间穿梭,实际上就是移动HEAD指向的位置(HEAD指向的版本就是当前版本)。
用git log
可以查看提交历史,即历史每次提交的<commit_id>,以便确定要回退到哪个版本。
用git reflog
可以查看命令历史,即所有分支的所有操作记录(包括commit
, reset
, checkout
, merge
等操作)。
指定版本到<commit_id>:
git reset --hard <commit_id> #当前分支和HEAD均指向<commit_id>
回退到当前HEAD的上一个commit,撤销暂存区变更(撤销commit和add):
git reset --hard HEAD~1 #HEAD~1表示上一个commit版本,如果是往上两个版本就是HEAD~2;当前版本就是HEAD
回退到当前HEAD的上一个commit,不撤销暂存区变更(撤销commit):
git reset --soft HEAD~1
2.5 查看命令(git status, git log, git reflog, git diff)
git status
查看git仓库中,工作区、暂存区、版本库的当前状态。git log
查看提交历史。可加选项:--oneline
每行显示一个commit。例如显示9af21bf add README.md
,那么<commit_id>前几个字符就是9af21bf
。--all
显示所有分支的提交历史,否则只显示当前分支的提交历史。--graph
显示分支合并,以横线形式连接曾有过合并的各个提交。
git reflog
查看命令历史。git diff
查看工作区和暂存区差异。git diff --cached
查看暂存区和版本库差异。git diff -- HEAD~1
查看工作区和版本库的差异。HEAD~1
可以改