一、初识Git
Git是一种版本控制工具,github用的就是Git系统来管理它们的网站。
1.1 分布式管理系统
除了Git,还有Svn等版本控制系统,它们的区别在于一个是分布式一个是集中式。Svn是集中式,Git是分布式。
他们的区别在于:集中式的版本控制系统每次在写代码时都需要从服务器中拉取一份下来,并且如果服务器丢失了,那么所有的就都丢失了,你本机客户端仅保存当前的版本信息,换句话说,集中式就是把代码放在一个服务器上集中管理,你的所有回滚等操作都需要服务器的支持。
在分布式管理系统中,每个人的电脑都是服务器,当你从主仓库拉取一份代码下来后,你的电脑就是服务器,无需担心主仓库被删或者找不到的情况,你可以自由在本地回滚,提交,当你想把自己的代码提交到主仓库时,只需要合并推送到主仓库就可以了,同时你可以把自己的代码新建一份仓库分享给其它人。
像集中式它们都有一个主版本号,所有的版本迭代都以这个版本号为主,而分布式因为每个客户端都是服务器,Git没有固定的版本号,但是有一个由哈希算法算出的id,用来回滚用的,同时也有一个master仓库,这个仓库是一切分支仓库的主仓库,我们可以推送提交到master并合并到主仓库上,主仓库的版本号会迭代一次,我们客户端上的Git版本号无论迭代多少次,都跟master无关,只有合并时,master才会迭代一次。
1.2 Git的安装与配置
关于Git安装,可参考的文章很多。简单来说,从官网上下载软件,然后进行安装即可。Git功能有很多,用的较多的是Git Bash,其界面示例:
Git在安装后,也可以在环境变量中配置,此时可以通过查看Git版本的方式来查看Git是否安装成功。所用的命令是:git -version
,示例:
软件安装后,需要用一些命令来配置一下环境,用到的命令是:git config --global
。
一般来说,初次使用Git需要设置你的用户名以及邮箱,这将作为当前机器Git的标识。如果你用它来下载远程仓库一些需要登录权限的仓库会要求登录,git默认使用配置邮箱以及用户名登入。
配置用户名的命令是:
git config --global user.name "用户名"
user代表用户,.name代表配置用户的名称。
配置邮箱的命令是:
git config --global user.email "邮箱"
user代表用户,email代表配置用户的邮箱。
二、Git理论
2.1 四个工作区域
Git有四个工作区域:工作区域(Working Directory)、暂存区(Stage\Index)、本地仓库(Repository)、远程仓库(Remote Directory)。图示:
- workspace
工作区,就是平时存放项目代码的地方。 - Index/Stage
暂存区,用于临时存放你的改动,事实上只是一个文件,保存即将提交到文件列表信息。 - Repository
仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本。 - Remote
远程仓库,托管代码的服务器,可以简单的认为是你项目组中一台电脑用于远程数据交换。
2.2 提交代码的简易流程
Git的工作流程一般分为以下几步:
- 1、在工作目录中添加、修改、删除文件(modified);
- 2、将需要进行版本管理的文件放入暂存区(staged);
- 3、将暂存区域的文件提交git仓库(committed);
- 4、将本地git仓库修改推送到远程仓库。
可以看出,Git所管理的文件有三种状态:已修改(modified)、已暂存(staged)、已提交(committed)。
2.3 Git所管理文件的四种状态
版本控制就是对文件的版本控制,要对文件进行修改、提交等操作,首先要知道文件当前在什么状态,不然可能会提交了现在还不想提交的文件,或者要提交的文件没提交上。
Git不关心文件两个版本之间的具体差别,而是关心文件的整体是否有改变,若文件被改变,在添加提交时就生成文件新版本的快照,而判断文件整体是否改变的方式就是用SHA-1算法计算文件的校验和。
四种状态的切换:
- Untracked(未被跟踪的)
此文件在文件夹中但并没有加入到Git库,不参与版本控制,通过git add
命令,状态变为Staged。 - Unmodify(文件已经入库)
未修改,即版本库中的文件快照内容与文件夹中完全一致,这种类型的文件有两种去处:
- 如果被修改,而变成Modefied;
- 如果使用
git rm
命令,移除版本库,则成为Untracked文件。
- Modified(文件已修改)
仅仅是修改,并没有进行其他操作,这个文件也有两个去处:
- 通过
git add
命令,可进入暂存Staged状态;- 使用
git checkout
命令,则丢弃修改内容,返回Unmodifiy状态。这个git checkout,即从库中去除文件,覆盖当前修改。
- Staged(暂存状态)
执行git commit
命令则将修改同步到库中,这时库中的文件和本地文件又变为一致,文件为Unmodify状态,执行git reset HEAD filename
命令取消暂存,文件状态为Modified。
三、Git命令
3.1 基础命令
git init
该命令的作用:在本地新建一个repo(版本库)。
进入一个项目目录,执行git init
,会初始化一个repo,并在当前文件夹下创建一个.git
文件夹。
git add*
该命令的作用:将文件添加到暂存区。
git add .
命令的作用:将工作空间下所有文件添加到暂存区(new,modifyed)。建议如果一个目录是新建的,该目录下的文件都需要添加到版本库时,使用该命令,否则使用git add filename
命令逐个添加文件。
git add
命令后还可以加一些参数,示例(不常用):
git add -A
:将工作空间下所有文件添加到暂存区(new,modifyed,delete);
git add -u
:将工作空间下所有文件添加到暂存区(modifyed,delete)。
git commit*
该命令的作用:将文件提交到本地仓库。
常用的方式:git commit -m <commit message>
,作用是将暂存区的文件提交到版本库。
还有一个不常用的方式:git commit -am <commit message>
,作用是跳过git add命令,直接将工作区所有已跟踪的文件提交到版本库,未跟踪的(untracked)文件不能使用该命令。
git commit -m "the commit message"
:编写本次提交信息。
git commit --amend
:修改最近一次的提交信息。
git status*
该命令的作用:查看本地仓库中文件的状态。
该命令后面可以加目录,不加的话代表当前目录。此时能看到的文件状态有:新增、修改和删除。
git log*
该命令的作用:查看当前当前分支代码的提交历史。
该命令后面常常配合一些参数使用。如:
git log --oneline
:每条log只显示一行。
git log branchname
:显示特定分支的log。
git log --author=[author name]
:显示指定作者的提交log。
git log filename
:查看某个文件的提交log。
git config
该命令的作用:查看或修改全局配置信息。
常用的命令:
git config --global user.name zhangsan
:配置用户名。
git config --global user.email 123@qq.com
:配置邮箱。
git config --list
:查看全局配置信息。
git stash
该命令的作用:暂存本地修改内容(用于不想提交修改的内容,想切换分支的场景)。
常用的命令:
git stash list
:查看暂存的历史记录。
git stash apple --index
:恢复之前暂存的某个记录。
git stash drop --index
:删除某个暂存记录。
git rm*
该命令的作用:删除本地仓库中的文件。
比如要删除一个文件,并提交到远程分支,所用命令为:
git rm filename
:删除本地仓库中的文件。
git commit -m 'remove filename'
:编写提交信息。
git push origin master
:将本地改动提交到远程(本例子中是master)分支。
git diff*
该命令的作用:比较本地工作空间和staged区的差异。
如果不加参数使用该命令,表示比较的是工作目录中当前文件和暂存区域快照之间的差异,也就是修改之后还没有暂存起来的变化内容。
git diff commitid
:查看当前仓库代码和某次提交时代码的差异。
git diff filename
:查看某个文件的(还没提交到本地仓库)修改。
git clean
该命令的作用:从工作目录中移除没有追踪的文件。
通常的用法是:git clean -df
。-d 表示同时移除目录,-f 表示 force,因为在git的配置文件中,配置了clean.requireForce=true。如果不加-f,clean将会拒绝执行。
3.2 撤销命令
git checkout --filename*
该命令的作用:拉取暂存区的文件并将其替换工作区的文件(即回退未提交的修改)。
git reset*
该命令的作用:对本地代码库的文件进行内容回退。
git reset HEAD
:来把不小心add进去的文件从staged状态取出来,可以单独针对某一个文件操作,即:git reset HEAD - - filename
,这个- -也可以不加。
相比之下,更常用的命令是:git reset --option commitid
:option有三种:
hard:硬回滚,简单理解为回退本地提交和修改的未提交的所有内容,和最新提交的代码保持一致。
mixed(或不使用参数):覆盖暂存区,但不覆盖工作区。
soft:软回滚,不进行暂存区和工作区的覆盖。
- 硬回滚的常见使用
git reset --hard HEAD
:回退到当前版本。
git reset --hard HEAD^
:回退到上一个版本。
git reset --hard commitid
:回退到指定版本。 - 回退范围
按改动范围排序:soft (commit) < mixed (commit + add) < hard (commit + add + local working)。
git revert*
该命令的作用:用一次新的commit来回滚之前的commit,此次提交之前的commit都会被保留。
作为对比,git reset是回到某次提交,提交及之前的commit都会被保留,但是此commit id之后的修改都会被删除。
git revert常用的命令有两种:
git revert HEAD
:撤销前一次提交。
git revert commitid
:撤销某一次提交。
3.3 分支操作命令
git branch*
git branch
:列出本地所有分支,当前分支会被星号标示出。
git branch branchname
:创建一个新的分支(当用这种方式创建分支的时候,分支是基于你的上一次提交建立的)。
git branch -m
:修改分支名称。
git branch -d
:删除分支。
git checkout branchname*
git checkout branchname
:切换分支。
git checkout -b branchname
:创建并切换分支。
git merge
git merge branchname
:合并指定分支代码到当前分支。
如果出现冲突,需要手动修改。此时解可以用到git diff,解决完之后用git add 添加即可。
3.4 远程仓库操作命令
git clone
该命令的作用:从一个指定的url拉取文件。
git fetch
该命令的作用:获取远程分支但不做合并。
git fetch origin dev
:获取远程dev分支但不做合并。
git pull*
该命令的作用:更新远程代码到本地分支。
git pull会首先执行git fetch,然后执行git merge,把取来的分支的head merge到当前分支。这个merge操作会产生一个新的提交。
常用的命令:
git pull origin dev
:获取远程的dev分支和当前分支合并,实际是先执行git fetch后,再执行git merge。
git pull origin dev:master
:获取远程的dev分支和本地的master分支合并。
git pull
:将远程仓库中和本地分支同名的分支代码更新到本地分支。
如果使用--rebase
参数,会执行git rebase来取代原来的 git merge。
git rebase
该命令的作用:会将本地的所有提交临时保存为补丁(patch),放在".git/rebase"目录中,然后将当前分支更新到最新的分支,最后把保存的补丁应用到分支上。本地的所有提交记录会被丢弃。
rebase的过程中,也许会出现冲突,Git此时会停止rebase并让你解决冲突。在解决完冲突之后,用git add去更新这些内容即可。
git push*
该命令的作用:将本地仓库的改动提交到远程仓库。
git push origin dev
:将本地上分支上提交到远程dev分支。
git remote
将远程仓库test重命名为test1: git remote rename test test1。
移除远程仓库 test1: git remote rm test1。