【VCS】【Git】Git快速入门

【VCS】【Git】Git快速入门

本篇博客意在让新手快速入门,达到Git日常使用需求。后续会另开几篇博客来探讨细节。

1 Git的安装

这部分网站上资料非常多,根据自己的系统查找资料并下载安装包安装即可。

2 初次使用Git之前的配置

2.1 配置用户名和邮箱

git config --global user.name "user_name"
git config --global user.email "email_address"

2.2 查看配置

git config --list

3 理论基础

3.1 为什么要掌握Git命令

可能有很多小伙伴习惯了Windows的操作模式,对命令行相对抵触。而且市面上确实有诸如TortoiseGit、SourceTree等Git图形化工具,使用体验也还尚可。但正所谓“Git的设计让使用者觉得自己比想象中的笨”,Git拥有太多强大的功能,而图形化工具中只封装了其中的一部分,还是命令行的功能全面。其次,很多老鸟回望来路,都认为Git的学习确实需要自底向上的过程。掌握了命令行,使用图形化工具如探囊取物。反之则不知其所以然,倘若后面遇到问题,就要抓瞎咯。

3.2 这么多差异版本,是如何保存的

3.2.1 SVN记录原理

SVN记录的是每一次版本变动的内容。换句话说,SVN只保存差异。
在这里插入图片描述

图1 SVN保存示意

3.2.2 Git记录原理

Git记录的则是将每个版本独立保存。譬如说File1有5个版本,那就有5个对应的拷贝。这种方式看似更浪费空间,但在分支管理上带来了很多便利。
在这里插入图片描述

图2 Git保存示意

3.3 工作区、暂存区和Git仓库

在这里插入图片描述

图3 Git工作区、暂存区、仓库关系示意

3.3.1 工作区

就是我们存放代码的地方,看得见摸得着。

3.3.2 暂存区

实际上是一个文件,其中保存我们的改动。

3.3.3 Git仓库

最终存放我们所有版本数据的位置。HEAD指针指向的就是我们最新提交的版本。

3.4 Git的工作流程

  • 在工作目录中增删、修改文件;
  • 将需要进行版本管理的文件放入暂存区;
  • 将暂存区的文件提交到Git仓库。

3.5 Git管理的文件状态

  • 已修改(modified);
  • 已暂存(staged);
  • 已提交(committed)。

4 建仓、拉代码、添加到暂存区、提交

4.1 建仓

4.1.1 建立全新项目(空白目录)

在新建的空目录中执行以下命令,即可建仓:

git init

建仓之后,可以看到在空白目录中新增了一个.git目录。这个目录就是用来跟踪版本迭代的。

4.1.2 已有项目代码建仓

进入项目代码根目录后,执行git init即可。

4.2 从服务器拉代码

4.2.1 默认方式

git clone git@192.168.199.118:hisi/v35x_560.git  # git clone 仓库地址

这种方式默认拉取远端的master分支

4.2.2 拉取指定分支

git clone -b dev git@192.168.199.118:hisi/v35x_560.git

我们可以通过增加-b branch_name选项来指定clone的分支

4.2.3 拉取所有分支

验证后补充

4.3 将文件添加到暂存区

新建一个Readme.txt,内含部分描述信息(这是在工作区发生的)。然后将其添加到暂存区:

git add Readme.txt

如果我们修改了很多文件,逐一add过于繁琐。此时可以通过如下命令,把工作区的修改一并加入暂存区:

git add -u

4.4 将暂存区中的修改提交到Git仓库

输入以下命令,将修改提交到Git仓库:

git commit -m "log"

我们还可以将略过添加暂存区的步骤,直接将文件提交到Git仓库:

git commit -am "log"

5 查看工作状态和历史提交

5.1 查看状态

我们可以使用以下命令来查看当前的状态:

git status

5.2 更新暂存区状态

某个文件已经加入暂存区,但我们又在工作区对其进行了修改,此时可以再次执行git add,更新暂存区中的状态。

5.3 还原工作区修改

如果我们在工作区修改了某个文件,但这些修改不想要了,那么可以执行以下命令,来还原工作区中的文件:

git checkout -- file_name

这里要注意,如果暂存区中有此文件,则会用暂存区的版本来覆盖工作区。如果暂存区中没有此文件,则会以Git仓库中的版本来覆盖工作区中的版本。如果想还原成Git仓库的版本,则可以先用git reset HEAD file_name将其从暂存区中移出,然后再使用git checkout – file_name,从而使工作区中的文件还原为Git仓库中的状态。

5.4 查看历史提交

我们可以使用git log来查看历史提交。commit ID是根据sha1算出来的。为什么不像SVN那样,从1开始排序?因为Git是分布式的,这样会引发冲突。

5.5 git log的常用选项

  • –decorate:显示每个commit的引用(如:分支、tag等)
  • –oneline:单行显示(简化版log);
  • –graph:以图形化方式查看commit;
  • –all:查看所有分支的commit。

6 回到过去

在这里插入图片描述

图4 Git工作区、暂存区、仓库状态切换示意

6.1 reset命令——用Git仓库中的版本覆盖暂存区

6.1.1 用Git仓库中HEAD所指版本覆盖暂存区(指定文件)

git reset HEAD file_name

6.1.2 用Git仓库中HEAD所指版本覆盖暂存区(所有文件)

git reset HEAD

6.1.3 如何使用Git仓库中的其他版本覆盖暂存区

首先,假设我们在工作区的所有修改都add并且commit了,可以用下图来表示当前状态:
在这里插入图片描述

图5 Git commit状态示意

接下来,使用reset命令来回滚快照:

git reset HEAD~    # ~表示HEAD所指版本的前一个版本,~~等以此类推。如果~太多不便表示,可以在~后加数字来指定

回滚之后的状态如下:
在这里插入图片描述

图6 Git reset状态示意

注意,reset命令实际包含了两个动作:

  • 移动HEAD的指向,可以将其指向之前的快照(HEAD指针的位置发生了改变,所以看log时,看不到最后一次提交的信息。要用git reflog才能看到所有log)。
  • 用HEAD移动后指向的快照覆盖暂存区。

6.2 reset命令的选项

6.2.1 --mixed

git reset --mixed HEAD~    # --mixed 是默认选项,不写也会自动加上

移动HEAD的指向,可以将其指向之前的快照。并用HEAD移动后指向的快照覆盖暂存区。

6.2.2 --soft

git reset --soft HEAD~

使用–soft选项,只移动HEAD的指向,使其指向之前的快照,但并不覆盖暂存区中的内容。
这种用法通常用于撤销错误的commit。

6.2.3 --hard

git reset --hard HEAD~6

移动HEAD的指向,使其指向之前的快照。并用HEAD移动后指向的快照来覆盖暂存区中的内容。此外,还会将暂存区中的文件还原到工作区(也是HEAD所指的Git仓库版本的状态)。

6.3 使用快照ID来执行reset

数HEAD毕竟麻烦,我们也可以使用快照ID来指定reset到哪个版本(不用全部ID,足够识别就行了)。

6.4 回滚个别文件

git reset commit_ID file_name

回滚个别文件时,HEAD指针就不移动了。

6.5 reset还可以往前滚

git reset commit_ID    # 视情况使用 --hard

7 版本对比

7.1 比较工作区和暂存区的差异

git diff

7.2 比较两个历史快照

git diff commit_ID1 commit_ID2

7.3 比较工作区和Git仓库中的快照

git diff commit_ID    # 快照 ID 用 HEAD 这种方式也可以

7.4 比较暂存区和Git仓库快照

git diff --cached/--staged [快照ID]    # 如果不指定快照ID,则默认和仓库中最新commit比较

7.5 diff功能概览图

在这里插入图片描述

图7 Git diff示意

8 常用的小技巧

8.1 修改最后一次提交

情景一:代码已经commit到仓库,突然想起还有两个文件没有add。

情景二:代码已经commit到仓库,突然想起log写得不全面。

执行带–amend选项的commit命令,Git就会“更正”最近的一次提交。

git commit --amend    # 在接下来的界面中可修改 log
git commit --amend -m "new log"    # 直接提交新 log

8.2 删除文件

git rm file_name

此命令删除的只是工作区和暂存区的文件,也就是取消跟踪,下次提交时,不纳入版本控制。已经提交到Git仓库的文件是不会删除的,需要移动HEAD指针来切掉。

如果误删除,可以使用git checkout – file_name的方式来恢复。

如果某个文件在工作区和暂存区的内容不一致,git rm执行时会报错。我们可以用git rm -f file_name来操作,这会同时把工作区和暂存区的文件删除。

如果需要只删除暂存区的文件,保存工作区的文件,则可以执行git rm --cached file_name。

8.3 重命名文件

git mv old_name new_name

9 分支与分支管理

9.1 什么是分支?为什么要有分支?

在这里插入图片描述

图8 Git分支示意

9.2 创建分支

git branch branch_name
git checkout -b branch_name    # 创建 branch_name 分支,并切换到此分支

9.3 切换分支

git checkout branch_name

9.4 查看分支

git branch -v    # 查看本地分支
git branch -r    # 查看远程分支
git branch -a    # 查看本地分支和远程分支

9.5 合并分支

git merge branch_name    # 将 branch_name 分支合并到当前分支

如果merge时提示conflict,则需要手动解决冲突。Git会在冲突的文件中加入一些提示。

9.6 删除分支

git branch -d branch_name

删除分支后再查看log,会发现虽然这些分支没有了,但在这些分支上提交的快照依然存在。

9.7 匿名分支

git checkout commit_ID

此时是分离头指针状态。由于我们使用了checkout命令,但并未创建新的分支,所以Git创建了一个匿名分支。既然是匿名分支,如果我们切换到其他分支,匿名分支中的所有操作都会被丢弃。所以我们可以用匿名分支来做些实验,反正没有什么影响。如果想保留匿名分支的操作,可以根据Git提示来操作,为其新建一个正式的分支。

10 将本地修改推到服务器端

前面说过,Git是分布式的VCS工具。我们本地有自己的仓库,服务器端有服务器端的仓库。为了确保其他人clone的代码中能包含我们的修改,就要把我们本地的修改推到服务器端。

我们通过git push命令,将本地修改推送到服务器端:

git push <远程主机名> <本地分支名>:<远程分支名>

通常用origin来表示远程主机名。

10.1 省略远程分支名

表示将本地分支推送到与之存在追踪关系的远程分支(通常同名)。如果该远程分支不存在,则会新建。

# origin: 远程主机名
# master: 本地分支名 
git push origin master

10.2 省略本地分支名

表示删除远程分支。这一操作等同于推送一个空的本地分支到远程分支。

# origin         : 远程主机名
# refs/for/master: 远程分支名
git push origin :dev

10.3 同时省略本地分支名和远程分支名

如果当前分支与远程分支存在追踪关系,则本地分支和远程分支都可以省略,将当前分支推送到origin主机的对应分支。

git push origin

10.4 同时省略远程主机名、本地分支名和远程分支名

如果当前分支只有一个远程分支,那么主机名都可以省略:

git push

10.5 push提示reject的处理方式

如果我们本地的代码不是服务器上最新版本,push代码时会被拒绝。此时我们要先更新本地代码,再push到服务器。

git reset --hard               # 将本地代码恢复到最新commit状态
git pull --rebase              # 将服务器更新合并到本地

11 更新本地代码

前文说到,Git是分布式的VCS,很多人都会向服务器端push修改。接下来看看,我们如何将服务器上的更新同步到本地。

11.1 本地只有 master 分支,且未做修改

此时的本地代码处于clean状态,所以可以直接使用git pull来更新。

11.2 本地只有master分支,且有修改

如果修改需要保留,要先将修改push到服务器端,然后再使用git pull来更新。

如果修改无需保留,可以使用git reset --hard将代码恢复到clean状态,然后再使用git pull来更新。

11.3 本地在自有分支上修改

由于我们在自己的分支(假定分支名为mybranch)上修改,master处于clean状态。此时要分四步处理:

  • 切换到master分支:git checkout master。
  • 更新master分支:git pull。
  • 切换到mybranch分支:git checkout mybranch。
  • 把master分支合并到mybranch分支:git merge master。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值