git使用小结
git使用小结
很多人可能和我一样,起初对git是一无所知的。我也是因为一次偶然的机会接触到git,并被它强大的功能所蛰伏。git其实就是一种版本控制工具,就像svn一样,但是git是分布式的。我不想给git打广告,我们直入正题——git能帮我们做什么?
1)源码版本控制。平常写一写demo程序可能和git打不上交道,但是当我们把程序写到10000行以上,一般一个人开发的话要持续一个多月。期间程序作者可能会保存了N多份程序不同时期的拷贝,一来是为了备份代码,二者是作者添加新的程序功能,一旦对新功能不满意时可以方便撤销。git能帮助我们保存每次提交源码更改时的历史记录,并在需要的时候帮助我们撤销回滚。
2)协同软件开发。如果说一个人把程序“写大”后需要git帮助控制版本,那么当有N个人同时开发一个软件的时候,git的功能就更加必要了。多人协同开发有很多工作模式,一般会在服务器端保存最新的源码版本。git帮助开发人员们同步修改,合并更新等。这里就涉及到了github,www.github.com就是保存开源项目的公共服务器,任何开发者都可以从该网站上下载自己项目的最新版本,修改后提交。因此github的命名也很形象,每个开发者就像客户端连接到公共的git服务器hub(集线器)上。
一言以蔽之,如果平常个人开发软件的话,git可以帮助我们方便的维护程序的版本;如果是多人共同开发的话,git能帮助我们协同工作。弄清这些,我们就开始Ubuntu上的git的使用。如果你从未用过git,这些入门级的介绍或许对你来说很有帮助,如果你是git专家,也希望你不吝指出文中的错误,共同进步!
1.git的安装和配置
首先从源上直接下载安装git。
$sudo apt-get install git-core -y
安装完毕后,需要配置git,告诉它“你是谁?”——包括你的姓名和Email,这些信息会在以后你的每次提交中出现。
$git config --global user.name “Your Name”
$git config --global user.email “your_email@email.com”
这些配置信息会保存在用户目录下。
$cat ~/.gitconfig
[user]
name = Your Name
email = your_email@email.com
到这里,就可以正常地在本地使用git了,但是我们还不能从github上下载和上传数据。因为github的仓库(Respository)一般都是开源的,所有人都可以自由的下载,但这不意味着所有人都能上传。如果要获得对github仓库的更新的权限,必须首先注册自己的公钥。
Ubuntu的用户RSA公钥和密钥默认放在用户目录下,如果没有的话使用命令创建。
$cd ~/.ssh || ssh-keygen -t rsa -C your_email@example.com
密码是可选的,最终会在~/.ssh下创建密钥文件id_rsa和公钥文件id_rsa.pub。
登录github后打开链接https://github.com/settings/ssh设置公钥。点击“Add SSH key”添加公钥。
首先拷贝刚生成的公钥的二进制数据,使用xclip命令。如果系统未安装xclip,首先安装该软件。
$sudo apt-get install xclip -y
$xclip < ~/.ssh/id_rsa.pub
给公钥命名,粘贴公钥内容,添加成功。
最后确认公钥是否正常。
$ssh -T git@github.com
当看到“Hi YourGithubID! You've successfully authenticated…”的信息时,大功告成!
2.仓库的创建和初始化
即使是个人独立开发软件使用git维护程序版本,使用github也会带来很大的便捷。只要有网络,从github上下载最新的源码,随时随地都可以修改更新。要达到这个目的,需要在github上创建一个Respository(网址:https://github.com/new),输入仓库名字(如work)创建即可。此时新创建的仓库是个空的仓库,等待我们本地上传新的数据。
首先我们需要创建一个工作目录,在这个目录我们开发源代码, 然后新建一个自读文件README.md。
$cd
$mkdir work
$cd work
$touch README.md
接着初始化该git仓库。
$git init
该命令在工作目录下生成了一个隐藏的文件.git,用于管理工作目录下所有文件的改变。
因为新建了文件README.md,如果要git对它的版本维护,则需要将它添加到git的索引中(git add . 命令可以添加所有的工作目录下的文件)。
$git add README.md
因为对git的仓库做了改动,便可以产生一次提交。
$git commit –am “first commit”
commit仅仅是把更改保存在了本地的git,下面就需要将我们所做的改动更新到服务器上,首先设置服务器git的地址。
$git remote add origin git@github:YourGithubID/work.git
origin是服务器git的别名,如果要上传我们的数据更新,则使用push命令。
$git push origin master
该命令将本地的git主分支master提交到远程服务器origin主分支master上。成功后打开地址https://github.com/YourGithubID/work可以看到新建的README.md文件已经存在了。
3.提交的更新和撤销
git的版本控制功能带给我们最大的好处是随时记录我们对源码的更改,并在我们需要的时候撤销已经做过的操作,不过这些便利是建立在每一次提交(commit)上的。每次使用commit命令后,git都会在log中增加一条历史记录。
使用status和log命令可以查看当前工作目录的状态和提交日志。
$git status
$git log
例如上一节提交的first commit记录。
commit 903fd****************************f322e05
Author: Your Name <your_email@email.com>
Date: Mon Apr 22 12:02:44 2013 +0800
first commit
除了新加文件需要使用git add命令再提交之外,其他情况的更新直接使用commit –am提交即可,所有的改变都会反映在本地的日志中。
我们也可以建立标签标记某次重要的提交。
$git tag INIT
如果我们在开发的过程突然发现某次之后的代码修改需要全部撤销,这时就是git大显身手的时候了。git reset命令可以让我们回到任何一个已经提交的历史状态!
$git reset --soft 903fd
该命令将工作的状态撤销到first commit之后(903fd为该commit的hash id的开始数个位),而且该命令不会直接修改工作目录下的源文件。我们也可以使用标签。
$git reset --soft INIT
如果此时使用commit提交更新的话,则可以把从first commit之后的全部修改合并为一次提交,这样有减少log记录的好处。
如果你确信要彻底撤销工作目录下的文件的更改,可以这样做。
$git reset --hard 903fd
这样就彻底回到了最开始的状态,除非你完全觉得有必要,否则尽量不要这样做。
如果使用git仅仅是为了达到偶尔的撤销的目的,这些功能貌似就够用了,但是git提供的便利性不仅如此。
4.版本的分支和合并
相比于其他版本控制工具,git更提倡使用分支!所谓分支是相对于服务端的主干版本而言的,从git项目建立时就默认处于主分支master上。如果在开发过程中开发人员有多个思维选择实现,或者有多个分工同步进行,那么建立多个分支分别同时开发。到分支结束后再决定是选择放弃哪些分支,或者将分支合并到主分支上等。
总的来说,git的分支模型为开发者提供一种额外的解决问题的思路,而不需要担心源代码的修改带来的副作用。分支上的开发者完全“生存”在另一个时空维度里,就像物理学中的平行空间一样,他们完全自由的在分支上更改源代码,甚至最后结果不满意时放弃这个分支的所有工作!分支模型帮助多人开发进行工作的协同,在每个人看来,开发模式一般是按照“下载最新版本——修改更新——合并提交”这样的流程进行。这种模式对于独立的开发者也很方便,开发者随时都可以下载最新的源码版本,随地的修改自己的代码,然后提交更新。我们按照这个流程看一下git的分支模型的使用。
首先是下载最新的源码版本。
$git clone https://github.com/YourGithubID/work.git
如果之前已经下载过该项目,则使用。
$git pull origin
直接从origin下载最新版本源码,并和本地主分支master合并。相当于命令组合。
$git fetch origin
$git merge origin/master
如果我们修改的源码并非自己github上的仓库,则需要将别人的仓库fork一份到自己的github上在按照上述方式下载,更新。最后push request到原作者的github上,如果原作者接受你的push request,则完成对他人代码的修改。
将最新版本的仓库下载到本地后,就可以修改源码了。一般我们不会直接对master分支更新,而是先建立一个临时的工作分支——如br1。
$git branch br1
$git checkout br1
使用checkout切换到分支br1上,此后所有的操作都是在br1上进行,不会对master有任何影响。最终我们完成了br1上的工作,然后我们需要将br1合并到master主分支上。
$git checkout master
$git merge br1
合并后的主分支记录了我们在br1上做的所有修改,最后我们需要将新的master主分支push到服务器上,完成当前阶段的工作!
5.总结
以上我们涉猎了git的基本使用方法,很多高级的用法无法在这里一一展示,本文也是期望带领初学者快速了解git的使用,并为自己的代码开发和版本控制提供便利。如果你在为开发软件不厌其烦的备份和多人源码的分工合作头疼不已时,不妨试一下git,或许有种“拨开云雾见月明”的感觉!
- WCF技术剖析之二十一: WCF基本的异常处理模式[上篇]
- 树大招风:细数2017年加密货币市场的幺蛾子事件
- 如何解决HP QC(Quality Center)在Windows 7下不能工作的问题
- WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[上篇]
- 5个典型实例启发:什么是数据可视化
- 智能家居“智商”不够,能靠情商来补吗
- 大话MVP
- AngularJS in Action读书笔记1——扫平一揽子专业术语
- MS Enterprise Library 5.0发布!!
- WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]
- 《Enterprise Library深入解析与灵活应用》博文系列汇总
- 使命必达: 深入剖析WCF的可靠会话[概念篇]
- AngularJS in Action读书笔记2——view和controller的那些事儿
- WCF技术剖析之二十一:WCF基本异常处理模式[中篇]
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- ZooKeeper 的应用场景
- 在 K8S 部署一个 Spark History Server - 篇3
- Go 学习笔记-1
- Tensorflow-gpu 运行在 cpu 母机的问题
- R语言入门之散点图
- Python函数(一)
- Spark on Kubernetes 动态资源分配
- R语言入门之偏度(skewness)与峰度(kurtosis)
- Spark Operator 是如何提交 Spark 作业
- R语言进阶之聚类分析
- 来 左边 跟我一起画彩虹
- Kubernetes v1.13 对 GPU 的支持
- Spark 3.0 对 GPU 做了什么支持
- Go语言整数值转字符串的效率问题
- R语言进阶之判别分析