Git三部曲
git add * | git add . git commit -m "注释" git push origin name(一般就是git push origin master)
在使用Git过程中最常用的就是这三个命令,其具体什么功能下面会详细介绍。
GitHub是什么?
GitHub是一个面向开源及私有软件项目的托管平台,因为只支持Git作为唯一的版本库格式进行托管,故名GitHub。
通俗的讲,可以说是一个开源的云盘,放在互联网上的SVN。
GitHub如何使用?
创建账号这种说明就无需多说,大家都是搞互联网的,别说不会注册账号?
将自己电脑里的项目上传至自己的GitHub社区首先需要下载Git,就像网盘一样,需要一个客户端。
在Git下载里下载自己电脑对应版本的Git。如需安装教程请点这里。
1、配置(本地仓库)用户名和邮箱
因为Git是分布式版本控制系统,所以需要填写用户名和邮箱作为一个标识。
注:git config --global 参数,有了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然你也可以对某个仓库指定的不同的用户名和邮箱。
配置(全局)用户名: git config --global user.name "your name"
配置(全局)邮箱: git config --global user.email "your email"
2、配置SHH Key
由于你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以需要配置一下。如果没有配置SHH,你的本地项目就不能提交到你的GitHub的远程仓库中进行管理。
第一步:创建SSH Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果有的话,直接跳过如下命令,如果没有的话,打开命令行,输入如下命令:
ssh-keygen -t rsa –C “你的邮箱地址”,由于我本地之前运行过一次,所以本地有,如下所示:
id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
现在你已经生成了一个SHH Key,来验证一下是否配置成功,在Git Bash里输入:
ssh -T git@github.com 出现如下提示说明配置成功,你可以将本地项目提交到远程仓库了。
3、创建版本库
版本库又名仓库,英文名Repository,你可以简单的理解一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改,删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻还可以将文件“还原”。
首先创建一个远程仓库,因为我们使用GitHub的最终目的就是使用远程仓库来管理我们的本地仓库(项目)。
远程仓库的创建非常简单,只需要在你的GitHub首页点击New Repository按钮即可。
接下来创建你的本地仓库,创建本地仓库有两种方法:一种是“无中生有”,另一种是“同化”。
无中生有
当你通过桌面快捷方式或者任务栏菜单打开Git Bash时,它默认会在你的用户目录的根目录,你可以通过pwd查看当前目录。
此时我们来创建一个名为gitTest的本地仓库。
这时你的用户目录的根目录会多出一个gitTest文件夹。进入刚刚创建的文件夹。
注:在Git Bash中输入命令时按下tab键会进行自动补齐,若是有相似命令或文件名,会进行提示。
随后将这个文件夹变成本地仓库。
此时gitTest文件夹就变成了一个版本库,内部会有一个隐藏文件夹.git。这个文件夹是用来管理版本库的,切不可随意更改!
同化
通过Git Bash输入命令或通过鼠标右键Git Bash Here进入一个已存在的文件夹,使用git init使其变成一个版本库。
4、管理本地仓库
添加&提交(add&commit)
现在我们的gitTest内什么都没有,我们先来创建一个文本文件(Git Bash不能创建文件)并在其内写入内容“This is a readme.txt”,然后将它提交到缓冲区。
什么提示都没有,说明命令执行成功了。
接下来使用git commit -m "注释"将其提交到仓库。
我们已经将readme.txt提交了,接下来查看还有没有文件没有被提交的。
这里提示没有未提交的文件,我们将readme.txt内容进行更改后再执行git status看看有什么结果。
这里提示readme.txt被更改且未被提交。我们来看看哪里被更改了。
这里看到,readme.txt文件新加了一行内容"My name is readme.txt"
注:首先要明确下,所有的版本控制系统,只能跟踪文本文件的改动,比如txt文件,网页,所有程序的代码等,Git也不列外,版本控制系统可以告诉你每次的改动,但是图片,视频这些二进制文件,虽能也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是知道图片从1kb变成2kb,但是到底改了啥,版本控制也不知道。
接下来我们将更改后的文件进行提交,步骤同样是先add后commit。
注:add命令可以add单独文件或者git add * 添加所有文件。commit必须有注释,不然会报错。
工作区和暂存区
工作区:就是你在电脑上看到的目录,比如目录下gitTest里的文件(.git隐藏目录版本库除外)。或者以后需要再新建的目录文件等等都属于工作区范畴。
版本库(Repository):工作区有一个隐藏目录.git,这个不属于工作区,这是版本库。其中版本库里面存了很多东西,其中最重要的就是stage(暂存区),还有Git为我们自动创建了第一个分支master,以及指向master的一个指针HEAD。
我们前面说过使用Git提交文件到版本库有两步:
第一步:是使用 git add 把文件添加进去,实际上就是把文件添加到暂存区。
第二步:使用git commit提交更改,实际上就是把暂存区的所有内容提交到当前分支上。
分支(Fork)
分支可以理解为版本,不同的分支对应不同的版本。把Git看做树的话,分支就是不同的树枝,各个分支相互独立。
在远程仓库GitHub上,当你看到别人好的代码想要拿过来研究的时候,只需要点击Fork按钮,你就会获得一份一模一样的克隆代码。
而此时你对你Fork来的代码做任何修改都不会影响到“母体”。
注:这里可以看到我的几个项目前面的图标不同,前两个是从我的本地仓库提交过来的,其他的是我Fork别人的项目。
注:Fork别人的项目过来加入自己东西固然方便,但是当作者进行更新时,你的代码版本依然停留在Fork时的版本,不能享受到最新的功能,为解决这个问题后面将介绍分支的合并与冲突。
在本地仓库也是一样,项目刚刚创建时,默认只有一个分支master,你可以创建多个分支,对项目进行不同版本的管理,各分支的更改互不影响。
接下来我们先查看本地仓库的分支,然后新建一个dev分支并切换过去。
git checkout -b name 创建并切换分支,相当于以下两条命令
git branch name 创建一个分支
git checkout name 切换到一个分支
git branch 查看所有分支,当前分支前面会有星号并且标绿色
版本回退
我对readme.txt文件做了几次更改,现在来查看一下历史记录。在此之前先查看readme.txt的文件内容。
git log命令显示从最近到最远的显示日志,如果嫌上面显示的信息太多的话,我们可以这样:
现在我想使用版本回退操作,我想把当前的版本回退到上一个版本,可以使用git reset --hard HEAD~N即可,未回退之前的readme.txt内容如下:
现在我向后回退一个版本,即“删除”内容为“33333”的版本并查看文件内容。
现在我想把3333版本恢复回来,该如何做呢?Git既然叫做版本控制器,而且每步操作都对应一个版本号,那么只要找到333的版本号就可以了。
现在找到了操作3333的版本号,根据版本号就可以将其恢复回来。
撤销修改
我现在在readme.txt文件内加入一行内容。
我在add文件之前先cat查看了一下,发现有一行错误代码,我需要把代码恢复成没有写这行错误代码之前的状态。有两种方法:
第一:如果我知道要删掉哪些内容的话,直接手动更改那些需要更改的文件,然后add添加到暂存区,最后commit掉。
第二:我可以按以前的方法直接恢复到上一个版本。使用 git reset --hard HEAD~1。
但是现在我不想使用上面的两种方法,我想直接想使用撤销命令该如何操作呢?首先在做撤销之前,我们可以先用 git status 查看下当前的状态。
可以发现,Git会告诉你,git checkout -- file 可以丢弃工作区的修改。
可以看到错误代码被删掉了。
删除文件
首先我们先在我们的工作区新建一个a.txt文件,然后将其提交到版本库中。
现在我想要把a.txt文件删除掉,有两种方法:
第一种:直接在工作区将文件删除
第二种:使用 rm a.txt 命令可以将文件删除
但是这个命令只是删除了工作区的文件,之前已经将文件提交到版本库了,版本库内的文件怎么删除呢?看图片演示~
那么有时候我们发现要删除的文件搞错了,怎么把文件找回来呢?我们先把readme.txt删掉。
这里我们看到提示,可以使用git checkout -- file进行文件恢复,我们来演示一下。
那如果是rm之后有进行add操作,这样还能恢复吗?
这里我们看到提示,可以使用git reset HEAD file进行恢复,我们来试一下。
可以看到,虽然执行了这行命令,也没有报错,但为什么文件没有被恢复呢?
还记得前面讲过的工作区和暂存区吗?rm操作是将工作区内的文件删除,add是将工作区内的操作提交到暂存区。
如果仅仅是rm但是并没有add,那么使用git checkout -- file就可以将工作区内的文件恢复。
如果已经add了,将操作提交到了暂存区,git reset HEAD file命令可以将暂存区的操作回退,然后再使用git checkout -- file命令就可以恢复工作区的文件。
可以理解为git checkout -- file是用来抵消rm的,git reset HEAD file是用来抵消add的。
注:git reset HEAD file对应撤销对暂存区内file的修改,git checkout -- file对应撤销对工作区内file的修改。修改不止于删除文件,还可以撤销对文件内容的修改。
推送至远程仓库
之前的所有操作都是在本地进行操作的,也就是本地仓库。之前说过,我们的最终目的就是通过远程仓库来管理我们的项目,并且在团队开发过程中,你只在自己的电脑上进行更改,其他人也看不到。所以将我们的本地仓库推送到远程仓库上,团队内所有人都可以随时Fork,随时将自己的工作进度推送上去。
推送至远程仓库有两种方法,一种是使用HTTPS进行推送,另一种是使用SSH进行推送。那具体怎么操作把本地仓库推送到远程上呢?
HTTPS方法
首先我们先在GitHub上新建一个远程仓库(前面讲过怎么做),名字与本地仓库相同。
新建一个远程仓库之后的界面如上图所示,将里面的http地址拷贝备用。
可以看到我连续输入了两行命令。
第一行的意思是将本地仓库与远程仓库以HTTPS方式进行关联,不然Git不知道你要把本地仓库推送到哪个远程仓库去。
第二行的意思是将本地仓库推送到远程仓库。git push的用法不只有这一句命令,详情可参考git push的常见用法。
随后我们查看远程仓库的内容,已经和本地仓库内容一致了!
使用HTTPS方式与远程仓库进行关联时,有一个不方便的地方就是每次push的时候,都需要输入github的账号和密码。
为解决这个问题,我们可以使用SSH方式与远程仓库进行关联。
SSH方法
首先先查看当前远程关联信息,使用git remote -v可以查看。
可以看到当前的项目是以HTTPS方法与远程仓库进行关联的。
还记得前面讲过的配置SHH Key吗?没有SSH Key是没有办法进行SHH关联的。
使用SSH方法与远程仓库进行关联,要么在新建关联时就使用SSH地址,或者后期也可以从HTTPS转换成SSH。这里演示如何从HTTPS转成SSH。
首先在一个已有项目内拷贝SSH地址。
然后删除现有项目的远程连接,命令是:git remote remove origin。然后通过SHH地址与远程仓库进行关联,命令是:git remote add origin 复制的ssh地址。
克隆远程仓库至本地
当你在GitHub上发现一个很酷的项目,想要down到自己本地上研究的时候应该怎么做呢?
刚刚我们在创建远程仓库的时候让大家拷贝备用的http地址,这个地址是每个在GitHub上的项目都会有的,我们就是通过这个地址来克隆远程仓库的。
接下来我在GitHub上随便找一个项目,并记录他的http地址然后将它克隆到本地。
这样本地就有了一份项目,在团队项目开发时,若是有同事将他的代码push到远程,你就需要更新你的本地代码,这个时候就不需要再clone了,只需要git pull就可以了,这里就不做演示了。
分支的合并与冲突
前面已经介绍了分支是什么,并且已经创建了一个dev分支。我说过分支之间是独立的,分支内的更改是互不影响的,每个本地仓库在创建时都有一个默认分支master,这个是主分支,在团队开发时一般不在主分支上开发,一般是在子分支开发完成后再向主分支合并,然后将主分支推送到远程仓库里。到目前为止我们只向GitHub推送了本地的master分支,所以远程仓库里也只有一个master分支。现在我们在本地切换到dev分支并将其推送到GitHub上。
由于远程仓库没有dev分支,所以在第一次推送本地dev分支的时候要顺带着新建一个远程的dev分支。现在可以看到远程仓库里有两个分支了。
现在回到本地仓库,一起来看看分支的合并是怎么回事。
首先我们先分别看看两个分支里readme.txt的内容。
两个分支的内容竟然不一样,这是为什么呢?因为我的dev分支是在111222333内容添加之间就创建的,所以这些内容dev分支上并没有,这正是说明分支之间的更改是互不影响的。之前也说过,分支可以理解为版本,那么也就是说master的版本比dev的版本更新。那么我们尝试把master合并到dev上看看有什么效果。
合并说完了,冲突又是什么意思呢?现在两个分支的内容完全一样了,我们分别在两个分支内向readme.txt内加入不同的内容,如:master内写入mastermaster,dev内写入devdevdev,然后再将dev合并到master上。
怎么解决冲突呢?很简单,既然看到哪里不一样了,只需要把不同的地方改成相同的就可以了。
这种情况一般出现在团队开发过程中两个人同时修改了一处地方且修改内容不同,这时候只要团队协调好用谁的代码就可以了。
一般来说我们不推荐直接在主分支master上工作,而是使用子分支进行开发,当认为项目已经开发完成可以上线时,再将子分支合并到主分支上。
当项目出现bug时怎么用分支管理来解决呢?你当然会说,直接新建一个bug分支,改好再合并到主分支就行了。但是如果你手头的工作没有完成,不能切换分支呢?比如我在开发中接到一个bug的时候,我们可以创建一个bug分支来修复它,但是,当前的dev分支上的工作还没有提交。并不是我不想提交,而是工作进行到一半时候,我们还无法提交,比如我这个dev分支要2天完成,但是我bug需要5个小时内完成。怎么办呢?还好,Git还提供了一个stash功能,可以把当前工作现场 ”隐藏起来”,等以后恢复现场后继续工作。
随后我们就可以创建bug分支进行修复了,这里演示一下创建和删除分支(修复完bug记得合并哦!)。
至此bug已经修复完了,让我们回到我们的工作上,把dev找回来。这里有两种方法可以恢复dev分支。
1、git stash apply恢复,恢复后,stash内容并不删除,你需要使用命令git stash drop来删除。
2、另一种方式是使用git stash pop,恢复的同时把stash内容也删除了。
什么意思呢?就是说之前的隐藏工作相当于备份了一份你当前的工作在别的地方,你恢复的时候,使用git stash apply是从备份处将工作复制一份回来,git stash pop是从备份处剪切回来。
团队开发
在团队开发模式下,大家都是在子分支下进行开发,然后向远程仓库的主分支进行推送,当有同事比你早推送时,远程仓库的版本就比你的更新,你再进行推送时会提示错误,这时只需要你将远程仓库pull到本地和你的本地仓库进行合并,合并成功后你再push就行了;如果合并出现冲突,那就是你和同事同时修改了同一处并且内容不一致,这时候就按照前面讲过的解决冲突的方法解决完冲突提交到本地仓库后再push就行了。
Git基本常用命令
mkdir directory 新建目录
pwd 显示当前目录路径
git init 把当前目录变成版本库
git add file 把文件添加到暂存区
git add * | git add . 把当前目录下全部文件添加到暂存区
git commit -m "注释" 提交文件到版本库
git status 查看仓库状态
git diff file 查看文件修改了哪些内容
git log 查看日志(历史记录)
git reset --hard HEAD~N 回退N个版本
cat file 查看文件内容
git reflog 查看历史记录的版本号
git checkout -- file 撤销文件在工作区的操作
git checkout name 切换分支
git checkout -b name 创建并切换到分支上
git branch 查看所有分支(当前分支会标星号且为绿色)
git branch name 创建分支
git branch -d name 删除分支
git merge name 在当前分支上合并目标分支
git rm file 删除文件
git remote add origin https://xxxx 关联一个远程仓库
git remote 查看远程库信息
git remote -v 查看远程库详细信息
git remote remove name 移除远程连接
git push -u origin master 把当前master分支推送到远程库上(第一次使用-u,之后不需要)
git clone https://xxxx 克隆远程库
git stash 隐藏当前工作
git stash list 查看隐藏信息
git stash apply 恢复隐藏工作,但是内容不删除
git stash drop 删除内容
git stash pop 恢复工作同时删除内容