Git简介和使用
一、什么是Git
Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。
二、Git 与 SVN 区别
Git不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。
Git 与 SVN 区别点:
1、Git是分布式的,SVN不是:这是Git和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别。
2、Git把内容按元数据方式存储,而SVN是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,.cvs等的文件夹里。
3、Git分支和SVN的分支不同:分支在SVN中一点不特别,就是版本库中的另外的一个目录。
4、Git没有一个全局的commit id,而SVN有。
5、Git的内容完整性要优于SVN:Git的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
总的来说:
SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,就郁闷了。
Git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
三、Git的安装
1、安装Git的windows客户端,这里使用msysgit,下载地址是https://git-for-windows.github.io 。安装完成后通过启动Git Bash打开Git命令行。
2、设置标识
因为Git是分布式版本控制系统,所以需要填写用户名和邮箱作为一个标识。
使用如下命令设置:
git config --global user.name "xxxx"
git config --global user.email "xxxx@xxxx.com"
如果用了 --global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。
如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 --global 选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。
3、查看配置信息
要检查已有的配置信息,可以使用 git config --list 命令:
$ git config --list
user.name=xxxx
user.email=xxxx@xxx.com
有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如 /etc/gitconfig 和 ~/.gitconfig),不过最终 Git 实际采用的是最后一个。
也可以直接查阅某个环境变量的设定,只要把特定的名字跟在后面即可,像这样:
$ git config user.name
四、Git的工作区、暂存区和版本库
工作区:就是在电脑里能看到的目录。
暂存区:英文叫stage, 或index。一般存放在 ".git"目录下 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
三个部分的状态转换关系:
图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage, index),标记为 "master" 的是 master 分支所代表的目录树。
图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。
当对工作区修改(或新增)的文件执行 "git add" 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
当执行 "git rm --cached <file>" 命令时,会直接从暂存区删除文件,工作区则不做出改变。
当执行 "git checkout ." 或者 "git checkout -- <file>" 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
当执行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
四、Git常用命令
1、创建仓库
命令:git init
Git 使用 git init 命令来初始化一个 Git 仓库,Git 的很多命令都需要在 Git 的仓库中运行,所以 git init 是使用 Git 的第一个命令。我们可以在任意一个目录文件夹下打开git bash命令行,输入git init即可完成。在执行完成 git init 命令后,Git 仓库会生成一个 .git 目录,该目录包含了资源的所有元数据,其他的项目目录保持不变。pwd 命令是用于显示当前的目录。
如下:
2、把文件添加到版本库中。
首先要明确下,所有的版本控制系统,只能跟踪文本文件的改动。版本控制系统可以告诉你每次的改动,但是图片,视频这些二进制文件,虽能也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是知道图片从1kb变成2kb,但是到底改了啥,版本控制也不知道。
示例:
1、在当前目录下创建一个文件test.txt,内容如下:
Hello world
第一步:使用命令 git add test.txt添加到暂存区里面去。如下:
这步命令完成后没有任何提示,就说明执行成功。(没有消息就是好消息)。
第二步:用命令 git commit -m "xxx"告诉Git,把文件提交到仓库。xxx是我们该次提交的描述。
提交完成后可以通过命令git status来查看是否还有文件未提交。
上面显示说明没有任何文件未提交。
这样我们就完成了一次文件提交。下面我们来看一下修改文件时会发生什么。
我们修改test.txt为如下内容:
Hello world
Hello git
修改完成后我们再使用git status命令查看:
可以看到git告诉我们 test.txt文件已被修改,但是修改未被提交。
我们可以通过git diff xxx命令来查看具体的修改内容。
知道了对test.txt文件做了什么修改后,我们可以放心的提交到仓库了,提交修改和提交文件是一样的2步(第一步是git add 第二步是:git commit)。
3、版本回退
现在我继续对test.txt文件进行修改,再增加一行内容为Hello Java.继续执行添加和提交的命令。现在我已经对test.txt文件做了三次修改了。现在可以使用命令 git log 来查看修改记录。演示如下所示:
git log命令显示从最近到最远的显示日志,我们可以看到最近三次提交,最近的一次是,"add hello java".上一次是"add hello git",第一次默认是"hello world".我们可以使用命令
git log --pretty=oneline 简化显示的信息。演示如下:
你看到的一大串类似b530250a45fb79b333fba8b05cb3ada38d755c7b的是commit id(commit id)。
现在使用版本回退操作,把当前的版本回退到上一个版本,可以使用如下2种命令,第一种是:git reset --hard HEAD^。 那么如果要回退到上上个版本只需把HEAD^ 改成 HEAD^^ 以此类推。那如果要回退到前100个版本的话,我们可以使用下面的简便命令操作:git reset --hard HEAD~100 即可。未回退之前的test.txt内容如下:
如果想回退到上一个版本的命令如下操作:git reset --hard HEAD^
可以看到,内容已经回退到上一个版本了。我们可以继续使用git log 来查看下历史记录信息,如下:
我们看到 add hello java 内容已经不见了,但是现在我想回退到最新的版本,也就是有“Hello Java”的test.txt,我们可以通过commit id回退,使用命令方法如下:
git reset --hard xxxxx
xxxx是commit id,找到我们需要恢复的commit id是b530250a45fb79b333fba8b05cb3ada38d755c7b。
于是就可以指定回到未来的某个版本:
如果你的命令窗口已经关闭,无法查看之前的commit id,可以通过git reflog查看我们的每一次命令。
可以看到对应“add hello java”的commit id是b530250。
4、Git的撤销修改和删除文件操作。
现在在test.txt文件里面增加一行 内容为Hello github1,我们先通过命令查看如下:
假如在未提交之前,发现添加的内容有误,所以得马上恢复以前的版本,现在我可以有如下几种方法可以做修改:
第一:如果我知道要删掉那些内容的话,直接手动更改去掉那些需要的文件,然后add添加到暂存区,最后commit提交。
第二:我可以按以前的方法直接恢复到上一个版本。使用 git reset –hard HEAD^
但是现在我不想使用上面的2种方法,我想直接想使用撤销命令该如何操作呢?可以通过
git checkout --xxx来实现。如下:
命令 git checkout --test.txt意思就是,把test.txt文件在工作区做的修改全部撤销,这里有2种情况,如下:
第一种:test.txt自动修改后,还没有放到暂存区,修改就回到和版本库一模一样的状态。
另外一种是test.txt已经放入暂存区了,接着又作了修改,撤销修改就回到添加暂存区后的状态。
5、删除文件
先在版本库testgit目录添加一个文件test_delete.txt,然后提交。
如上:一般情况下,可以直接在文件目录中把文件删了,或者使用如上rm命令:rm xxx.txt 。查看当前目录可以看到test_delete.txt已经不见了。如果想彻底从版本库中删掉了此文件的话,可以再执行commit命令提交。只要还没有commit,我们可以在版本库中恢复此文件。可以使用如下命令 git checkout -- xxxx,如下:
6、git关联github远程仓库
第一步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果有的话,直接跳过此如下命令,如果没有的话,打开命令行,输入如下命令:
ssh-keygen -t rsa -C "youremail@example.com"。你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可。完成后在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
第二步:在github远程仓库配置SSH key。
页面如下:
填写好Title后,在Key文本框里粘贴id_rsa.pub文件的内容即可。
7、添加远程仓库
首先,登录github上,然后在右上角找到“create a new repo”创建一个新的仓库。在Repository name填入testgit,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库:
git remote add origin git@github.com:xiaokangjack/testgit.git
如下:
git push origin master
把本地master分支的最新修改推送到github上了,现在就拥有了真正的分布式版本库了。
8、克隆远程仓库
一、什么是Git
Git是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。Git 与常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本库的方式,不必服务器端软件支持。
二、Git 与 SVN 区别
Git不仅仅是个版本控制系统,它也是个内容管理系统(CMS),工作管理系统等。
Git 与 SVN 区别点:
1、Git是分布式的,SVN不是:这是Git和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别。
2、Git把内容按元数据方式存储,而SVN是按文件:所有的资源控制系统都是把文件的元信息隐藏在一个类似.svn,.cvs等的文件夹里。
3、Git分支和SVN的分支不同:分支在SVN中一点不特别,就是版本库中的另外的一个目录。
4、Git没有一个全局的commit id,而SVN有。
5、Git的内容完整性要优于SVN:Git的内容存储使用的是SHA-1哈希算法。这能确保代码内容的完整性,确保在遇到磁盘故障和网络问题时降低对版本库的破坏。
总的来说:
SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以首先要从中央服务器哪里得到最新的版本,然后干活,干完后,需要把自己做完的活推送到中央服务器。集中式版本控制系统是必须联网才能工作,如果在局域网还可以,带宽够大,速度够快,如果在互联网下,如果网速慢的话,就郁闷了。
Git是分布式版本控制系统,那么它就没有中央服务器的,每个人的电脑就是一个完整的版本库,这样,工作的时候就不需要联网了,因为版本都是在自己的电脑上。既然每个人的电脑都有一个完整的版本库,那多个人如何协作呢?比如说自己在电脑上改了文件A,其他人也在电脑上改了文件A,这时,你们两之间只需把各自的修改推送给对方,就可以互相看到对方的修改了。
三、Git的安装
1、安装Git的windows客户端,这里使用msysgit,下载地址是https://git-for-windows.github.io 。安装完成后通过启动Git Bash打开Git命令行。
2、设置标识
因为Git是分布式版本控制系统,所以需要填写用户名和邮箱作为一个标识。
使用如下命令设置:
git config --global user.name "xxxx"
git config --global user.email "xxxx@xxxx.com"
如果用了 --global 选项,那么更改的配置文件就是位于你用户主目录下的那个,以后你所有的项目都会默认使用这里配置的用户信息。
如果要在某个特定的项目中使用其他名字或者电邮,只要去掉 --global 选项重新配置即可,新的设定保存在当前项目的 .git/config 文件里。
3、查看配置信息
要检查已有的配置信息,可以使用 git config --list 命令:
$ git config --list
user.name=xxxx
user.email=xxxx@xxx.com
有时候会看到重复的变量名,那就说明它们来自不同的配置文件(比如 /etc/gitconfig 和 ~/.gitconfig),不过最终 Git 实际采用的是最后一个。
也可以直接查阅某个环境变量的设定,只要把特定的名字跟在后面即可,像这样:
$ git config user.name
四、Git的工作区、暂存区和版本库
工作区:就是在电脑里能看到的目录。
暂存区:英文叫stage, 或index。一般存放在 ".git"目录下 下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
三个部分的状态转换关系:
图中左侧为工作区,右侧为版本库。在版本库中标记为 "index" 的区域是暂存区(stage, index),标记为 "master" 的是 master 分支所代表的目录树。
图中我们可以看出此时 "HEAD" 实际是指向 master 分支的一个"游标"。所以图示的命令中出现 HEAD 的地方可以用 master 来替换。
图中的 objects 标识的区域为 Git 的对象库,实际位于 ".git/objects" 目录下,里面包含了创建的各种对象及内容。
当对工作区修改(或新增)的文件执行 "git add" 命令时,暂存区的目录树被更新,同时工作区修改(或新增)的文件内容被写入到对象库中的一个新的对象中,而该对象的ID被记录在暂存区的文件索引中。
当执行提交操作(git commit)时,暂存区的目录树写到版本库(对象库)中,master 分支会做相应的更新。即 master 指向的目录树就是提交时暂存区的目录树。
当执行 "git reset HEAD" 命令时,暂存区的目录树会被重写,被 master 分支指向的目录树所替换,但是工作区不受影响。
当执行 "git rm --cached <file>" 命令时,会直接从暂存区删除文件,工作区则不做出改变。
当执行 "git checkout ." 或者 "git checkout -- <file>" 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中未添加到暂存区的改动。
当执行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令时,会用 HEAD 指向的 master 分支中的全部或者部分文件替换暂存区和以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中未提交的改动,也会清除暂存区中未提交的改动。
四、Git常用命令
1、创建仓库
命令:git init
Git 使用 git init 命令来初始化一个 Git 仓库,Git 的很多命令都需要在 Git 的仓库中运行,所以 git init 是使用 Git 的第一个命令。我们可以在任意一个目录文件夹下打开git bash命令行,输入git init即可完成。在执行完成 git init 命令后,Git 仓库会生成一个 .git 目录,该目录包含了资源的所有元数据,其他的项目目录保持不变。pwd 命令是用于显示当前的目录。
如下:
2、把文件添加到版本库中。
首先要明确下,所有的版本控制系统,只能跟踪文本文件的改动。版本控制系统可以告诉你每次的改动,但是图片,视频这些二进制文件,虽能也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是知道图片从1kb变成2kb,但是到底改了啥,版本控制也不知道。
示例:
1、在当前目录下创建一个文件test.txt,内容如下:
Hello world
第一步:使用命令 git add test.txt添加到暂存区里面去。如下:
这步命令完成后没有任何提示,就说明执行成功。(没有消息就是好消息)。
第二步:用命令 git commit -m "xxx"告诉Git,把文件提交到仓库。xxx是我们该次提交的描述。
提交完成后可以通过命令git status来查看是否还有文件未提交。
上面显示说明没有任何文件未提交。
这样我们就完成了一次文件提交。下面我们来看一下修改文件时会发生什么。
我们修改test.txt为如下内容:
Hello world
Hello git
修改完成后我们再使用git status命令查看:
可以看到git告诉我们 test.txt文件已被修改,但是修改未被提交。
我们可以通过git diff xxx命令来查看具体的修改内容。
知道了对test.txt文件做了什么修改后,我们可以放心的提交到仓库了,提交修改和提交文件是一样的2步(第一步是git add 第二步是:git commit)。
3、版本回退
现在我继续对test.txt文件进行修改,再增加一行内容为Hello Java.继续执行添加和提交的命令。现在我已经对test.txt文件做了三次修改了。现在可以使用命令 git log 来查看修改记录。演示如下所示:
git log命令显示从最近到最远的显示日志,我们可以看到最近三次提交,最近的一次是,"add hello java".上一次是"add hello git",第一次默认是"hello world".我们可以使用命令
git log --pretty=oneline 简化显示的信息。演示如下:
你看到的一大串类似b530250a45fb79b333fba8b05cb3ada38d755c7b的是commit id(commit id)。
现在使用版本回退操作,把当前的版本回退到上一个版本,可以使用如下2种命令,第一种是:git reset --hard HEAD^。 那么如果要回退到上上个版本只需把HEAD^ 改成 HEAD^^ 以此类推。那如果要回退到前100个版本的话,我们可以使用下面的简便命令操作:git reset --hard HEAD~100 即可。未回退之前的test.txt内容如下:
如果想回退到上一个版本的命令如下操作:git reset --hard HEAD^
可以看到,内容已经回退到上一个版本了。我们可以继续使用git log 来查看下历史记录信息,如下:
我们看到 add hello java 内容已经不见了,但是现在我想回退到最新的版本,也就是有“Hello Java”的test.txt,我们可以通过commit id回退,使用命令方法如下:
git reset --hard xxxxx
xxxx是commit id,找到我们需要恢复的commit id是b530250a45fb79b333fba8b05cb3ada38d755c7b。
于是就可以指定回到未来的某个版本:
git reset --hard b530250
如果你的命令窗口已经关闭,无法查看之前的commit id,可以通过git reflog查看我们的每一次命令。
可以看到对应“add hello java”的commit id是b530250。
4、Git的撤销修改和删除文件操作。
现在在test.txt文件里面增加一行 内容为Hello github1,我们先通过命令查看如下:
假如在未提交之前,发现添加的内容有误,所以得马上恢复以前的版本,现在我可以有如下几种方法可以做修改:
第一:如果我知道要删掉那些内容的话,直接手动更改去掉那些需要的文件,然后add添加到暂存区,最后commit提交。
第二:我可以按以前的方法直接恢复到上一个版本。使用 git reset –hard HEAD^
但是现在我不想使用上面的2种方法,我想直接想使用撤销命令该如何操作呢?可以通过
git checkout --xxx来实现。如下:
命令 git checkout --test.txt意思就是,把test.txt文件在工作区做的修改全部撤销,这里有2种情况,如下:
第一种:test.txt自动修改后,还没有放到暂存区,修改就回到和版本库一模一样的状态。
另外一种是test.txt已经放入暂存区了,接着又作了修改,撤销修改就回到添加暂存区后的状态。
5、删除文件
先在版本库testgit目录添加一个文件test_delete.txt,然后提交。
如上:一般情况下,可以直接在文件目录中把文件删了,或者使用如上rm命令:rm xxx.txt 。查看当前目录可以看到test_delete.txt已经不见了。如果想彻底从版本库中删掉了此文件的话,可以再执行commit命令提交。只要还没有commit,我们可以在版本库中恢复此文件。可以使用如下命令 git checkout -- xxxx,如下:
6、git关联github远程仓库
第一步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果有的话,直接跳过此如下命令,如果没有的话,打开命令行,输入如下命令:
ssh-keygen -t rsa -C "youremail@example.com"。你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可。完成后在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
第二步:在github远程仓库配置SSH key。
页面如下:
填写好Title后,在Key文本框里粘贴id_rsa.pub文件的内容即可。
7、添加远程仓库
首先,登录github上,然后在右上角找到“create a new repo”创建一个新的仓库。在Repository name填入testgit,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库:
目前,在GitHub上的这个testgit仓库还是空的,GitHub告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。
git remote add origin git@github.com:xiaokangjack/testgit.git
如下:
把本地库的内容推送到远程,使用 git push命令,实际上是把当前分支master推送到远程。由于远程库是空的,我们第一次推送master分支时,加上了 –u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。推送成功后,可以立刻在github页面中看到远程库的内容已经和本地一模一样了。如下:
git push origin master
把本地master分支的最新修改推送到github上了,现在就拥有了真正的分布式版本库了。
8、克隆远程仓库
先在github上创建一个远程仓库名为test_clone,并自动生成一个readme.md文件。下面来将这个远程仓库克隆到本地。
使用命令git clone克隆一个本地库了。命令为
git clone git@github.com:xiaokangjack/xxx.git。如下所示: