Git是目前世界上最先进的分布式版本控制系统(没有之一)。
Git是Linus发明的,在2002年之前,Linus都是手工合并Linux的更新代码(依赖diff)。而对于当时的CVS和SVN这些集中式的工具,有一些缺点:需要联网以及是速度较慢。而速度快的则需要收费。不符合开源的精神。后来Linus花了2周用C写了一个分布式版本管理控制系统。就是Git。Git后来迅速火起来了,2008年Github上线,为开源项目提供免费的Git存储。
CVS、SVN是集中式版本控制系统的代表。而Git是分布式版本控制系统的代表。他们的区别在于:
1、集中式的版本库是存在服务器中,分布式的版本库存在服务器以及每个人的电脑中。引出的是集中式版本库的服务器挂掉,就会造成很大的影响。而分布式挂掉之后,公共的版本库可以从任何一个人的版本库上传,即可恢复。
2、集中式版本库需要联网,对网速比较依赖。而分布式基本不需要网,只有在push和pull才会使用网络。
Git有三个区,叫工作区,暂存区和版本库。
工作区(working Directory):简单的理解你在电脑里能看到的目录。
暂存区(stage):Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master,以及指向master的一个指针叫HEAD。
版本库(Repository):工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
要完成一次完整的提交,我们需要git add->git commit才可以,就像我们去购物一样,先把东西放到购物车,在去结账是一样的。
Linux下:
对于Debian类系统。可以使用
apt install git -y
而对于类红帽系统,可以使用
yum install git -y 来安装。
Window下可以到官网去下载安装包,无脑安装。
安装结束后需要对自己的email和name进行设置。
git config --global user.name “shaobin”
git config --global user.email "shaobin@163.com"
首先说版本库是什么?
版本库可以理解为是被Git管理的一个目录。每个文件的修改,删除。Git都可以跟踪到,可以知道在什么时候,更改了什么。但只限于文本文件,对于图片,视频的更改是无法识别在哪里更改了的。
创建版本库很简单,有两种方法。
第一种方法是初始化一个。第二种方法是从远端获取一个。
这边先重点介绍第一个方法,第二种方法后面会提及。
首先,创建一个文件夹。然后使用git init初始化它就ok了。
化成命令来说:
$ mkdir gitpratice $ cd gitpratice $ git init 结果: Initialized empty Git repository in /root/gitpratice/.git/瞬间Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),可以发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。
git的回滚是使用git reset和revert这个命令进行版本切换。
首先,可以先看现在的历史:
[root@localhost gitpratice]# git log --pretty=oneline b29e9bf31a3ae58e977d700559989ca347708227 add a.py acd81f23a86dc2f6e349e12dd891bcce51d8ab7d second time d6d54d1f0e10f8518deb66ccb9c35603179f1c85 create a readme如何选中一个想回退的版本。
如果选中second time版本,使用reset命令来做:
[root@localhost gitpratice]# git reset --hard acd81f HEAD is now at acd81f2 second time返回上一个版本:
git reset --hard HEAD^
HEAd^:指的是上一个版本
HEAd^^:指的是上上一个版本
HEAd~100:指的是上一百个版本
git reset --mixed:此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本,只保留源码,回退commit和add信息
git reset --soft:回退到某个版本,只回退了commit的信息。如果还要提交,直接commit即可
git reset --hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容,慎用!
思路还是一样的,首先看历史的操作,这个不能看历史的版本,因为历史版本已经是不能看见将来的版本。
因此要使用git reflog命令看历史版本操作。
git reflog acd81f2 HEAD@{0}: reset: moving to acd81f b29e9bf HEAD@{1}: commit: add a.py acd81f2 HEAD@{2}: reset: moving to acd81f2 d6d54d1 HEAD@{3}: reset: moving to HEAD^ acd81f2 HEAD@{4}: reset: moving to HEAD^ 36d662b HEAD@{5}: reset: moving to 36d662b d6d54d1 HEAD@{6}: reset: moving to HEAD^ acd81f2 HEAD@{7}: reset: moving to HEAD^ 36d662b HEAD@{8}: reset: moving to 36d662b acd81f2 HEAD@{9}: reset: moving to acd81 36d662b HEAD@{10}: commit: third time acd81f2 HEAD@{11}: commit: second time d6d54d1 HEAD@{12}: reset: moving to HEAD^ 6914e5e HEAD@{13}: commit: add a line d6d54d1 HEAD@{14}: commit (initial): create a readme选中一个时间节点,继续使用git reset 命令来进行版本切换。
上面说的回滚都是回滚整个工作区。如果想回滚单个文件。思路还是一样的。先看单个文件的历史记录,在reset,然后要比回滚整个仓库多加commit才可以。
git log filename git reset asdfad filename git commit -m "reset filename"移动或重命名文件、目录或符号链接
git mv已经commit到仓库的文件,如果在工作区删除了,可以有两条路选:
1、我是故意删的。
如果是想要删的话,需要把git库的也一并删除掉。
git rm filename git commit -m "rm filename"2、我是误删了
如果是误删,我们可以从版本库恢复过来
git checkout filename撤销已经add上去的文件,重新修改
git checkout -- filename查看git add之后和上一个版本的commit的改变
git diff --cached创建dev分支,并且转过去dev
git checkout -b dev带星号的是现在的分支
切换到test分支,前提是有git分支
git checkout test当前分支合并dev分支。
git merge dev当然,合并并不是经常成功,有很多时候是失败的,比如两个分支的一个文件commit之后,相对于之前的commit并不一致。
[root@localhost gitpratice]# git merge ops Auto-merging a.py CONFLICT (content): Merge conflict in a.py Automatic merge failed; fix conflicts and then commit the result.我们就需要手动修改这个发生冲突的文件。
1 iadsf 2 <<<<<<< HEAD 3 master change 4 ======= 5 ops change 6 >>>>>>> ops <<<<<<< HEAD ======= >>>>>>> ops 是标识每个分支的不一致的地方进行修改,然后commit就可以成功
下面是我们的分支的情况。
[root@localhost gitpratice]# git log --graph --pretty=oneline * 4f2f09a93a86bf74eb40e3def732743f07d2615d CONFLICT FIXED |\ | * 39f09ad138b5f264c61df39049e5837b13d9b8d5 ops change * | 985ff3c21f9c9d856acc0e29c14a4f1b9a52b1ee master commit in a,py |/ * 4f8bd5ca45acfd579ee69ef6952ca7dc54a03f2c branch test * 2713ac81fd490402d30d6a8a8c6cd3adf2a405b0 add del.py用到远程仓库就涉及到push和pull命令
可以有两种方式和远程仓库通信,一个是通过ssh,一个是通过https。
通过ssh方式会步骤比较多一点,个人偏爱https。
但是https每次push和pull都需要登陆认证。
ssh在初始化的时候,需要将公钥放在远程仓库的配置项里面。
至于怎么生成公钥,可以去码云或者Github看,有详细的教程。
这样可以免去每次push和pull都要打一长串。
git remote add origin git@github.com:nick/learngit.gitorigin就是这个仓库的的别名
当然也可以换成其他。
git tag v??来做。
比如创建v1.0标签。
git tag v1.0如果过去忘记给tag就commit了。也可以现在给以前版本tag。
首先看历史。然后找到要打标签的一项的id
git log --pretty=oneline [--abbrev-commit] 3fb1975 Merge branch 'master' 509f8e0 Initial commit 1b98315 add git tag v0.9 509f8e0比如,发现标错了,要去掉v0.9这个标签
git -d v0.9