Git的学习与心得

Git的学习与使用

Git简介

很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了。

Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那Linux的代码是如何管理的呢?

事实是,在2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码!

你也许会想,为什么Linus不把Linux代码放到版本控制系统里呢?不是有CVS、SVN这些免费的版本控制系统吗?因为Linus坚定地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。

不过,到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。

安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。

Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:

Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?大家可以体会一下。

Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了,它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。

历史就是这么偶然,如果不是当年BitMover公司威胁Linux社区,可能现在我们就没有免费而超级好用的Git了。

Git的安装

Git安装可以参考文档https://www.liaoxuefeng.com/wiki/896043488029600/896067074338496

下载好git之后,我们就可以通过命令来查看git的版本

git --version

Git的初始化

当我们首次使用Git的时候,需要设置我们的名字和Email地址。表明我们的身份,当我们参与团队合作项目的时候,别人也可以通过我们的名字和Email与我们联系。

git config --global user.name "Your name"								//设置你的名字
git config --global user.email "Your email address"			//设置你的邮箱

然你你可以使用如下命令来查看

git config user.name
git config user.email

Git本地库示意图

场景一:Git本地版本库的基本用法

Git本地版本库

WorkSpace:就是你的本地工作区啦
Stage:待提交区(暂存区)
Local Repo:本地仓库

在本地仓库,我们首先在工作区修改,然后提交到暂存区,最后提交到本地版本库。大体的命令代码如下

Git本地仓库创建

Git创建版本库有两种方法。第一种是在本地创建版本库,或者是clone远端的版本库从而在本地建立一个版本库

git init  # 在本地建立一个版本库
git clone https://github.com/YOUR_NAME/REPO_NAME.git # 通过clone远端的版本库从而在本地创建一个版本库

这里我们先讲解本地创建版本库,我们使用VSCode来做演示,我们先建立了一个Test文件夹作为演示的文件夹

在建立版本库的时候,可以直接使用VSCode自带的工具建立本地版本库,也可以使用命令行来建立。

  1. 使用VSCode

  1. 使用命令行
git init

这样我们就成功的建立了一个本地仓库

Git仓库状态的查看

要随时掌握工作区的状态,使用git status命令。

如果git status告诉你有文件被修改过,用git diff可以查看修改内容。

git status 是我们最最常用的命令,要学会看这个命令带给我们的提示。然后要学会使用 git diff。

git status # 查看工作区状态
git diff # 查看修改内容

我们执行一下git status命令

可以看到,由于刚刚创建仓库,我们没有任何的提交

下面试一下Git diff,查看工作区和暂存区的不同,创建一个Test.txt文件,并输入


Hello World


提交到暂存区(命令稍后说明) git add Test.txt

本地修改,在Test.txt加入 Hello Java


Hello World
Hello Java


调用命令git diff

可以看到改变

如果想查看某个具体的文件

git log <filename>

也可以根据具体版本号比较文件

git diff [本地库中历史版本] [文件名]

向Git仓库添加文件

首先我们编写一个README.md文件

  1. 第一步,使用命令添加到暂存区
git add <filename>  ## 添加filename文件到暂存区
git add .   				## 将工作区所有修改的文件加入暂存区

我们将README.md添加到暂存区

git add READMD.md

似乎没有任何提示,说明添加成功

  1. 第二步,将暂存区文件添加到本地仓库
git commit <filename> -m "message"  ## 添加filename文件到仓库
git commit  -m "message"   		  	## 将暂存区有修改的文件加入仓库

添加成功后会有提示

Git版本回退

  1. git日志

首先我们必须要知道我们提交了几次,可以通过查看git日志的方法来查看

git log

可以发现我们有三次提交,需要注意的是,看到一串黄色的字符串是代表commit_id(版本号),使用Hash计算

  1. 回退版本,现在我们想要回退到上一个版本

首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本,也就是最新的提交9598409...(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

img

现在,想要回到上一个版本,我们可以使用如下的命令

git reset --hard HEAD^
git reset --hard HEAD~1
git reset --hard Hash值

就被还原了

--hard 参数 

+ 在本地库移动 HEAD 指针 
+ 重置暂存区 
+ 重置工作区

reset 其他参数解释

--soft 参数  仅仅在本地库移动 HEAD 指针
--mixed 参数 ① 在本地库移动 HEAD 指针 ② 重置暂存区

现在让我们看看git log

只有两次的记录了,我们想回到最新的版本怎么办?

如果你还记得上面的最新版本的Hash值9598409...,可以使用git reset --hard 9598409...回去,但是如果你第二天起来想回到最新版本怎么办,忘记了哈希值。不要急,也有办法

git reflog

可以查看当前HEAD之后的版本

即我们可以查看2之后的3这个版本

最上面那行代表我们现在HEAD位置,下面三行的第二行即HEAD,那个9598490 即我们未来的版本,知道了版本号我们使用

git reset --hard 9598490回去就行

管理修改,撤销修改,删除修改

  1. 管理修改

在一个阳光明媚的早晨,你决定使用git进行版本控制管理

你首先在OMG.txt写下了


Hello


你添加了它,git add OMG.txt,

你又修改了这个文件


Hello

Oh my god,Trump tested positive for COVID-19


并且你使用git commit -m "This is a interesting thing"提交到了版本库

你会发现第二次修改没有经过暂存区就提交了

我们回顾一下操作过程:

第一次修改 -> git add -> 第二次修改 -> git commit

Git管理的是修改,当你用git add命令后,在工作区的第一次修改被放入暂存区,准备提交,但是,在工作区的第二次修改并没有放入暂存区,所以,git commit只负责把暂存区的修改提交了,也就是第一次的修改被提交了,第二次的修改不会被提交。

小插曲:如果使用git commit -a -m "Message"则跳过工作区到暂存区步骤直接进入仓库,

或者直接指定文件名git commit <filename> -m "Message"

  1. 撤销修改

自然你是不会犯错误的,只会有小小的失误,某天你加班到了凌晨两点

你写下了


Trump is stupid


你意识到了这句话的不妥,于是你想纠正他

现在你还没提交文件到暂存区

我们可以查看一下git status

你可以选择①手动删除这行话②使用git restore <文件>来丢弃工作区的改动,现在撤销修改就回到了和版本库一样的状态

PS:①选择手动修改比较好,万一你的其他修改也没了呢②git checkout -- <filename>也是可以的

现在你把文件提交到了暂存区

你同样需要查看一下git status

按照它的提示进行,就能将文件从暂存区回到工作区,按照上面方法修改git restore --staged OMG.txt

如果你把文件提交到了版本库

没有问题,使用版本回退就可以了。但是如果你提交自己的版本到了远程版本库,那就。。真的很难修改了(提交一个新的版本)

  1. 删除文件

我把刚才建的Test.txt在本地删除了

查看git status

如果要删除的话就git add <filename> or git rm <filename>添加到暂存区然后使用git commit来确认删除

否则就使用git restore <filename>来恢复文件把。

如果已经添加到暂存区了,就先把文件从暂存区撤回工作区,git restore --staged <filename>然后恢复

如果添加到了暂存区并且git commit提交了怎么回退?

版本回退

场景二:Git远程版本库的基本使用

创建一个新的远程库

首先我们去GitHub创建一个新的仓库

现在,远程库已经准备好了,我们把它clone下来

git clone https://github.com/XXX/XXX.git

当然这是我自己的,不过克隆下来是一个空仓库,克隆下来默认远程库的别名叫做orign

现在我们可以使用命令查看当前远程库别名了

git remote # 查看当前远程库地址别名
git remote -v # 查看当前所有远程地址别名

这时候我们就可以在本地仓库进行修改,删除等一系列操作了,我们添加一个README.md然后把本地仓库推送到远程库

不要忘记先要添加到本地的暂存区->本地仓库,然后推送到远程库git add,git commit

推送到远程库可以使用命令

git push [远程别名(默认是orign)] [当前分支名(默认是master)]

在推送过程中会要求输入GitHub账号密码,根据提示来就可以,这里不再展示,下面是推送完效果

如果想要下载远程库的最新代码,只需要使用命令

git pull

就会下载最新的代码

另外,讲解一些fetch和merge和pull

关联已有的本地仓库

如果我们已经有了一个本地仓库,想推送到远程仓库怎么办呢,我们首先在远程创建一个仓库,创建的仓库名最好和本地仓库相同,然后我们可以使用命令

git remote add [别名] [远程地址]

来和远程仓库关联

这里不用先Clone,可以直接到本地目录下输入指令

git remote add orign https://github.com/XXX/XXX.git

然后使用git push orign master就成功推送过去了

小总结

如果本地已有仓库,就使用git remote add 来将本地仓库推送到远程同步

如果本地没有仓库,新建了一个远程仓库,可以使用git clone <远程地址>来创建本地仓库并和远程仓库同步

上面步骤完成后,使用git push来推送,可以使用git pull来接收最新的远程版本库

场景三:团队项目中的分叉合并

在项目中,我们每个人开发都拥有自己的分支,然后在自己的分支上进行对代码的添加修改。

每个人在自己的分支上进行对代码的操作,最后合并到主分支上

  1. 首先,我们需要克隆或者同步最新的代码库到自己的电脑上
git clone https://DOMAIN_NAME/YOUR_NAME/REPO_NAME.git
git pull
  1. 我们需要创建一个分支,并且在这个分支上操作
git branch <分支名> # 创建分支
git branch # 查看分支
git branch -v # 查看更详细的分支信息
  1. 我们切换到自己的分支进行操作
git checkout <分支名>

  1. 最后我们需要合并分支
第一步:切换到接受修改的分支(被合并,增加新内容)上 git checkout [被合并分支名]
第二步:执行 merge 命令 git merge [有新内容分支名]
这里我们执行在mster上合并mybranch1分支指令
git checkout master # 切换到主分支上
git merge mybranch1 # 合并分支

如果我们想要体现自己的时间线,而不是master分支的时间线,我们需要执行如下指令git merge --no-ff mybranch1

结果如下

可以看到体现了我们自己的时间线

  1. 分支的解决冲突

有时候我们的分支和master冲突了,比如你在分支的README.md修改了一段,而maser被别人修改了一段,恰恰修改了同一部分,这时候就需要手动解决冲突了。

①这里我的master的README.md有如下部分


Hello World

edit by master


②而mybranch1的README.md有如下部分


Hello World

edit by master


合并分支的时候就会产生冲突

这时候我们的README.md会标示出冲突的部分

我们需要手动修改,修改到满意为止

然后调用git add .git commit -m "Message"来提交

冲突解决了

冲突的解决 
 第一步:编辑文件,删除特殊符号 
 第二步:把文件修改到满意的程度,保存退出 
 第三步:git add [文件名] 
 第四步:git commit -m "日志信息" 
		 注意:此时 commit 一定不能带具体文件名

场景四:Git Rebase

在上一个场景我们看到了,我们先在自己的分支上进行开发,然后合并到主分支上,如果我们在自己的分支上进行提交,如下图

合并完成之后我们会发现版本图是这样的

太不合理了,我们命名可以把A->B->C合成一个到我们的master上。

这就需要用到命令

git rebase -i (id 号码的父亲)

指的是以哪个版本作为奠基,合并其他版本,合并完后只留下奠基的版本

我们先建立自己的分支,然后分别提交三次版本ABC

接着我们准备把这三次版本奠基,只留下A版本,合并B和C版本,输入git rebase -i HEAD^^^

跳出这个界面

可以看到下面提示有变基的不同方法,我们使用s,融合到前一个提交

保存退出,退出后如果有冲突的话,我们需要根据提示处理冲突

解决完毕冲突后运行

git rebase --continue

不要忘记上面的步骤完了使用git addgit commit提交到版本库呦

再使用git log查看

只剩下了A版本,然后和主版本合并就可以了

另外,在变基过程中,随时可以用以下命令终止

git rebase --abort

场景五:Fork + Pull request

前面的场景三四都是基于大家是同一个开发团队,现在,如果你不是团队的人,但是像为开源项目增加代码或者修改bug,你应该怎么做呢?

就需要使用

Fork+ Pull request的协作开发工作流程。

  1. 先 fork(分叉) 别人的仓库,相当于拷贝一份;
  2. 做一些 bug fix或其他的代码贡献;
  3. 发起 Pull request 给原仓库;
  4. 原仓库的所有者 review Pull request,如果没有问题的话,就会 merge Pull request 到原仓库中。

我们首先进入别人的版本库点击fork按钮,然后回到自己的地方对其进行修改

修改完了以后我们可以点击Pull requests进行提交,然后

最后合并代码


这篇文章的写成参考了大量的资料

1.https://mp.weixin.qq.com/s/Km5KuXPETvG0wCGHrvj9Vg

2.http://www.ruanyifeng.com/blog/2014/06/git_remote.html

3.https://www.yuque.com/liweiwei1419/yby7qi/ocpind

4.https://blog.csdn.net/weixin_33127753/article/details/88870257

其他命令

  1. git revert

revert 的含义

revert 能做的事情:revert 可以取消一个 commit。

如果我们很好地能够做到一个 commit 做一件事情,以后想要取消的时候,就会变得非常容易。

revert 还有一个使用场景:

刚刚 push 的时候,如果反悔了,可以使用一个 revert 的操作去撤销它。

  1. git blame <filename>

# 显示指定文件是什么人在什么时间修改过

  1. git log补充

    git log --pretty=oneline

简洁方式显示git log

另外,如果git log过多,可以显示

(1)git log --graph(以图表形式查看分支)

显示字符界面的提交关系图,不同的分支使用不同的颜色来表示。

小技巧:可以使用 git config --global alias.glog “log

--graph” 起一个别名。

然后以后再使用的时候,就可以用 git glog。

(2)git log --stat

说明:--stat 表示查看每次提交文件变更的统计。这条命令可以帮助我们查看每一次提交具体的文件变化。

(3)git log -l --pretty=raw

我们会看到 SHA1 哈希值。--pretty=raw 显示每个提交对象的 parent 属性。

暂时没有发现有什么不同的地方。

(4)git log --pretty=oneline

更常用的一种写法是:

(5)git log --graph --oneline

(6)git log -5 --pretty --oneline

显示过去五次提交

(7)git log -p [file]

显示指定文件相关每一次diff

另外,如果git log一页显示不了

b->向上翻页

空格->向下翻页

q->退出

posted @ 2020-10-03 10:36  且听水吟吟、  阅读(312)  评论(0编辑  收藏  举报