首发日期:2018-09-23
git的介绍
题外话:什么是版本控制系统?--以版本控制系统的功能开始 在你日常生活中,如果你对某个项目进行不断的版本增强的时候,你可能会得出多个版本(例如初定版,1.1版,3.0版,最终版),而由于你是不能百分百确定最新版本是否是符合开发思路的(可能走某条路反而让版本增加了更多bug,于是要从头开始),所以你会需要每个版本的记录文件,确保存有原来的版本来进行重新开发,你可能会对每个版本进行拷贝一份,这样就可以确保自己存有发生错误之前的版本了。但“拷贝”法有很严重的问题,一是单纯的拷贝会浪费较多空间、二是每个拷贝你都需要提供一个文件来描述这个拷贝是哪个版本的。而版本控制系统就可以很大程度地解决上面两个问题。 1.版本控制系统可以帮助开发者协同工作,节省项目管理时间:以Linux的版本控制为例,众所周知,Linux是开源的,所以它有很多“免费的员工”,如果没有一个版本控制系统的话,一个普通公司的多个程序员提交的代码主管要“手动拷贝+手动合并+手动清理优化”才能得到最终的代码,而使用一些市面上的版本控制软件如SVN,主管就可以定义一个“房间”,程序员给“这个房子装修的东西”,主管可以在版本控制软件上进行代码对比查看合并,这样就节省了项目管理的时间。 2.版本控制系统可以帮助开发者记录项目的开发记录、回退版本和版本对比:以给软件增加新功能为例,开发新功能,首先要保证旧系统运行,在没有版本控制系统的情况下,我们一般都要对原始代码进行拷贝,避免在原始代码的基础上修改导致出错时无法恢复到功能上线前(假设不是修复新功能而是先下线再修复)。而使用版本控制系统后,开发者可以将原始代码记录提交到版本控制系统上,然后每一次开发都提交一次记录到版本控制系统上,版本控制系统会将提交的所有的开发记录保存,这使得我们可以方便的“回退”到某一版本。而版本控制系统一般还提供版本对比功能,可以查看某版本与另一个版本的代码在哪里有区别。(有人说可以拷贝,但长期开发时,拷贝消耗的时间很多,而提交只需要几条命令。并且不同的版本控制系统采用不同的记录方法,所以会比拷贝要节省资源,同时拷贝不可以对比文件的细致内容。) 所以,总的来说,版本控制系统有以下几个好处:
题外话:集中式与分布式版本控制系统的区别? git与集中式版本控制系统(如svn等)不同,集中式版本控制系统由主服务器存储更新记录,git可以在多台主机中保存更新记录。 集中式的版本控制系统,都有一个单一的集中管理的服务器,保存所有文件的修订版本,开发者通过客户端连到这台服务器,取出最新的文件或者提交更新。 完成工作后,开发者都必须提交到这台服务器。由于服务器的限制,集中式版本控制系统最大的毛病就是必须联网才能工作。 分布式控制系统,每一个客户机都相当于一台服务器,每台主机都是一个版本库,当需要协作开发时,客户端并不只是从某台主机中提取最新版本的文件快照,而是把代码仓库完整地镜像下来。 这么一来,任何一处协同工作用的服务器发生故障,事后都可以用任何一个镜像出来的本地仓库恢复。而开发者完成工作后,开发者可以将修改推送给别人,别人就可以看到开发者的修改。
补充:
# git的基础使用相关知识区域:要把代码提交到本地服务器,那么就要认识下面几个区域。考虑到对项目更新的追踪情况,git将项目的所处区域分为以下几种。 工作区:工作区就是你最开始的工作目录。你开发了一个项目,并且这个项目位于仓库目录(仓库后面说)中,但还没有做任何版本跟踪或版本提交操作,那么此时这个项目就位于工作区。 暂存区:你可以把暂存区理解成提交到本地库前的一个中间者,因为直接提交到本地库的话,有时候可能会发生错误,为了避免错误,所以有了个暂存区。当你执行git add XXX【XXX是一个文件或目录】的时候,git就会把XXX添加到暂存区,这样就会开始进行版本跟踪。你可以把暂存区理解成幼儿园的校车,老师(开发者)把一个个孩子(项目文件)带到校车(暂存区)上,等到装满了并且检查没少人(验错,以免漏了文件)之后再把小孩子送到家(提交到本地库)。暂存区中会对将要提交的文件进行追踪,如果这时候工作区中进行了修改,那么可以使用git status 查看出来。 本地库:本地库就是本地的版本仓库,在本地的仓库中存有版本更新记录。你的每一次提交都会在本地库中记录下来。当项目提交到本地库,即代表此次提交成为了一个历史版本。对于多个版本,你可以选择前进到某个版本或者回退到某个版本。 区域转换命令:工作区 --git add-->暂存区--git commit -->本地库
文件状态:未跟踪状态Untracked:一个文件没有被git追踪时【说明不在仓库中也不再暂存区中】,是Untracked状态,需要git add 来让它被git追踪。 已暂存staged:一个文件刚刚被git add 后就会变成staged状态。 已提交commited:一个文件被git commit 后,数据已经提交并保存在本地仓库中,就会变成已提交状态。【这个状态也是未修改状态,刚提交的文件就是说明是未修改的】 已修改modified:一个文件被追踪后,如果在工作区中进行了修改,这个工作区的文件就会变成已修改状态,它需要重新git add 或git commit 来将修改后的文件提交到本地库。
本地库与远程库:由于git是分布式的,所以它可以在本地中创建版本仓库,但在多人协作开发的时候,由于处在不同的主机,所以需要某个主机作为“远程库”来管理核心的版本信息。远程库与本地库性质相同,不同它由于处在远端区域,所以称为远程库,远程库用于管理多人协作时的版本更新,开发者可以克隆远程库到本地中作为本地库,然后提交修改后的信息到远程库。
windows中git的安装这里以windows安装为例,如果想了解其他系统的安装方式,可以自查。 1.下载安装 官网:https:/// 2.开始安装
之后就是纯粹的安装了。
git的使用命令的使用位置:先提一下命令的输入位置,然后下面再介绍有什么命令。在windows下,右键可以看到(如果你安装过程勾选了的话) ,第一个就是在本目录中以可视化方式打开git,第二个是以命令行方式打开git。下面介绍的使用将只介绍命令行方式。学会了命令行方式你就很容易去学会在可视化窗口下操作git。 命令行窗口是这样子的: 稍微提一下,git是linux之父创造的,git也支持很多Linux命令。所以你可以使用linux命令的方式来显示下一页、显示下一行等操作【这些命令由于是Linux的内容,这里不会讲】
初始化仓库:git用于版本控制更新,要使用它,必须要有一个用于记录版本信息的仓库。 git的版本控制命令要在仓库中才能使用,所以要在需要进行版本控制的项目目录进行初始化仓库(也就是追踪一个项目的也必须要在这个项目文件夹进行初始化仓库。)。这样就可以对项目的文件进行管理了。 《git官方文档》:初始化后,在当前目录下会出现一个名为 .git 的目录,所有 Git 需要的数据和资源都存放在这个目录中。不过目前,仅仅是按照既有的结构框架初始化好了里边所有的文件和目录,但我们还没有开始跟踪管理项目中的任何一个文件。
设置签名:git的其他命令使用需要先设置用户签名,这是为了区分不同开发人员的身份。如果没有任何能够标识提交者的东西的话,就没办法知道这份工作是谁做的了,这是不允许的。 用户签名包含用户名和邮箱,仅用于本地库中区分开发者(这不是远程库的账户密码)。远程库需要的别的用户名和密码,这会在后面github协作中再讲。【用户签名中用户名和邮箱仅仅涉及用户标识,所以它不必是真实的,邮箱和用户名是可以随机的】 用户签名是必须的,不允许匿名用户提交版本操作。 用户签名也是有作用范围的,采用两种不同的设置方式。 语法: 示例: $ git config user.name neo
$ git config user.email xxx@163.com
$ git config --global user.name tom
$ git config --global user.email tom@163.com 仓库级别的用户签名信息保存在仓库目录下.git/config文件中;全局级别的用户签名信息保存在系统用户目录下的.gitconfig 文件中【使用cd ~ 可以快速切换到当前用户目录】 查看这些配置信息可以使用git config --list 来查看
查看状态:提交到暂存区:命令: 提交指定文件:git add 文件名 提交所有文件到暂存区:git add .
作用:目标文件会被提交到暂存区,并被git进行追踪,被追踪之后,可以使用git status查看文件的变化。 文件名可以使用通配符* ,例如git add *.java 代表提交所有以.java为后缀的文件名。 提交到暂存区,相当于给文件拍了一个快照,然后存储到暂存区中。
提交到本地库:
从暂存区移除文件:如果你想把某个文件删掉,但又想把这个删除操作提交到仓库中(git add只能添加文件到暂存区,git add +git commit也只能做到修改或增加文件),可以使用以下命令。 命令: 要把这个删除操作提交到本地库,那么还需要git commit
文件重命名:
查看历史记录:每一次git commit 都相当于提交一次版本更新操作,这会留下一个版本记录。 版本记录会使用哈希值来唯一标识每一个版本。 查看版本记录可以帮助我们了解版本更新情况,以及可以帮助我们进行版本回退等操作。 命令: 选项 | 说明 |
---|
%H | 提交对象(commit)的完整哈希字串 | %h | 提交对象的简短哈希字串 | %T | 树对象(tree)的完整哈希字串 | %t | 树对象的简短哈希字串 | %P | 父对象(parent)的完整哈希字串 | %p | 父对象的简短哈希字串 | %an | 作者(author)的名字 | %ae | 作者的电子邮件地址 | %ad | 作者修订日期(可以用 -date= 选项定制格式) | %ar | 作者修订日期,按多久以前的方式显示 | %cn | 提交者(committer)的名字 | %ce | 提交者的电子邮件地址 | %cd | 提交日期 | %cr | 提交日期,按多久以前的方式显示 | %s | 提交说明 |
默认不用任何参数的话,git log 会按提交时间列出所有的更新,最近的更新排在最上面。
查看所有版本更新记录:git log 【注意翻页(space)、下一行(enter)这些操作与linux的相同,q为退出】 显示每次提交的内容差异:git log -p 查看最近num次的提交:git log -num 单行显示版本更新记录(只包含哈希值和版本描述信息):git log --pretty=oneline 或git log --oneline 以格式化的方式显示版本更新记录:git log --pretty=format:"%h - %an, %ar : %s" 显示版本更新中分支变化情况(用于查看分支合并情况):git log --graph 完整显示版本更新记录:git reflog【git永远只会增加版本,不会因为版本回退而删除某个版本(完整地记录版本更新情况,连回退操作也当成一个版本更新操作),版本回退之后,git log是看不到比回退版本更高的版本的,而git reflog可以看到完整的版本更新情况】
版本回退与前进:当发生某个重大bug时,我们可能希望回到某个版本重新开始,那么可以使用版本回退。【前进就是回退之后又突然想去新版本看看】 文件对比:
分支操作:什么是分支? 当多人协作开发一个项目时,可能多人开发的并不是同一种功能(例如战斗功能、交易功能),一般来说都会分别开发功能,最后再进行整合。 而这些功能可能都会基于某个前置功能,某些额外功能的开发都需要前置功能的代码,对于不使用版本控制的开发来说,可能会使用拷贝基础的代码,再进行开发。 而使用了git之后,你应该知道你可以直接使用命令来获取某个版本的代码文件的。这就省去了繁杂的拷贝了。 但git提供的分支(默认我们开发的分支是master分支)可以形象地显示分功能开发问题,而分支合并可以处理整合问题。
"分支就是不同流向的分支历史"
基于当前版本来创建分支:git branch 分支名 查看分支:git branch -v 或git branch 切换分支:git checkout 分支名 创建并切换分支:git checkout -b 分支名 合并分支:git merge 分支名 【在某个分支执行这个命令,就是把当前分支与目标分支合并】 删除分支:git branch -d 分支名 其他话: 切换分支也会更改工作区的文件。
分支合并冲突:上面提到了分支合并,但有时候合并会发生冲突的。例如,某个开发者基于master分支的某个版本创建了issue分支来进行了开发,(要注意的是这时候issue分支基于某一份共同的代码),但创建了issue分支之后,master分支上继续进行了版本更新,于是原本issue基于的代码发生了变化。开发完了之后,要进行分支合并,git会检查文件是否相同,它就会发现两份代码有了不一样的地方,于是就有了冲突。【就好比A从B的冰箱拿了四个苹果,B自己偷偷拿了1个苹果,后来A要还给B苹果的时候,B说原本有五个苹果,但A说只拿了四个,这就是一种冲突】
查看哪个文件发生冲突:git status 解决方案:
git与github的搭配使用:
创建github仓库:1.创建新仓库:
2.填写仓库描述:
## 给git添加远程仓库:命令: url地址的获取:
## 查看远程仓库:要查看当前配置有哪些远程仓库,可以用 git remote 命令,它会列出每个远程库的简写名字及url。 克隆远程库:克隆远程库,就是从远程库拉取完整的版本更新记录和项目数据下来,会在本地创建一个远程仓库名的文件夹。
拉取远程库分支到本地:克隆远程库是完整地拷贝一个仓库。如果你之前已经有过这个仓库了,你可以直接拉取分支,拉取某个分支需要的流量会比克隆远程库要少得多。**在拉取的时候也会获取到版本更新记录 ** 命令: git pull 远程库简写名 分支名 :拉取某个分支的代码到本地,要求本地已经初始化了仓库,会与本地的分支进行合并。【由于会合并,所以要考虑本地库和远程库版本差距太大的时候的情况。】
git fetch 远程库简写名 分支名 :拉取某个分支的代码到本地,要求本地已经初始化了仓库,但注意pull会尝试合并分支,而fetch不会尝试合并分支。
推送本地代码到远程库:
标签查看标签:创建标签:
查看标签信息:推送标签:
文件提交过滤一个项目在开发的过程中,可能会需要运行测试,所以可能会把一些运行日志文件留在项目目录中,而这些日志文件对于版本更新是没有作用的,所以不应该把他提交到远程库中。要知道每一份空间都是珍贵的。 而除了日志文件,可能还有其他一些文件,这些文件可能是比较有用的,所以我们不能去“净化工作区”----删除它们。通常我们都会定义一个.gitignore 文件,这个文件通常用于过滤上传到远程库的项目文件,在里面定义的文件不会被提交到仓库中。 .gitignore文件要位于仓库的根目录
文件 .gitignore 的格式规范如下: 所谓的 glob 模式是指 shell 所使用的简化了的正则表达式。星号(* )匹配零个或多个任意字符;[abc] 匹配任何一个列在方括号中的字符(这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c);问号(? )只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符,表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)。
通常来说,网上都会有大量的针对不同项目的gitignore文件。普通使用的时候去网上抄一份就行,如果有特殊文件,那么就要自己手写了。
下面以在github中创建仓库时选择自动生成的针对java项目的.gitignore文件为例: # Compiled class file 过滤.class文件
*.class
# Log file 过滤日志文件
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files # 过滤jar包,war包
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www./en/download/help/error_hotspot.xml
hs_err_pid*
写在最后基本来说,上面这些命令足够日常使用了。 希望这篇博文能帮助到你
|