github入门
简介:
很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了。
Linus虽然创建了Linux,但Linux的壮大是靠全世界热心的志愿者参与的,这么多人在世界各地为Linux编写代码,那Linux的代码是如何管理的呢?
事实是,在2002年以前,世界各地的志愿者把源代码文件通过diff的方式发给Linus,然后由Linus本人通过手工方式合并代码!
你也许会想,为什么Linus不把Linux代码放到版本控制系统里呢?不是有CVS、SVN这些免费的版本控制系统吗?因为Linus坚定地反对CVS和SVN,这些集中式的版本控制系统不但速度慢,而且必须联网才能使用。有一些商用的版本控制系统,虽然比CVS、SVN好用,但那是付费的,和Linux的开源精神不符。
不过,到了2002年,Linux系统已经发展了十年了,代码库之大让Linus很难继续通过手工方式管理了,社区的弟兄们也对这种方式表达了强烈不满,于是Linus选择了一个商业的版本控制系统BitKeeper,BitKeeper的东家BitMover公司出于人道主义精神,授权Linux社区免费使用这个版本控制系统。
安定团结的大好局面在2005年就被打破了,原因是Linux社区牛人聚集,不免沾染了一些梁山好汉的江湖习气。开发Samba的Andrew试图破解BitKeeper的协议(这么干的其实也不只他一个),被BitMover公司发现了(监控工作做得不错!),于是BitMover公司怒了,要收回Linux社区的免费使用权。
Linus可以向BitMover公司道个歉,保证以后严格管教弟兄们,嗯,这是不可能的。实际情况是这样的:
Linus花了两周时间自己用C写了一个分布式版本控制系统,这就是Git!一个月之内,Linux系统的源码已经由Git管理了!牛是怎么定义的呢?大家可以体会一下。
Git迅速成为最流行的分布式版本控制系统,尤其是2008年,GitHub网站上线了(github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开。),它为开源项目免费提供Git存储,无数开源项目开始迁移至GitHub,包括jQuery,PHP,Ruby等等。
历史就是这么偶然,如果不是当年BitMover公司威胁Linux社区,可能现在我们就没有免费而超级好用的Git了。
今天,GitHub已是:
- 一个拥有143万开发者的社区。其中不乏Linux发明者Torvalds这样的顶级黑客,以及Rails创始人DHH这样的年轻极客。
- 这个星球上最流行的开源托管服务。目前已托管431万git项目,不仅越来越多知名开源项目迁入GitHub,比如Ruby on Rails、jQuery、Ruby、Erlang/OTP;近三年流行的开源库往往在GitHub首发,例如:BootStrap、Node.js、CoffeScript等。
- alexa全球排名414的网站。
1、密钥连接
首先申请github账号,由于你的本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要一点设置,在本地生成密钥对:
[root@localhost ~]# ssh-keygen -t rsa -C 'lianzhilei0711@163.com'
你需要把邮件地址换成你自己的邮件地址,然后一路回车,使用默认值即可,由于这个Key也不是用于军事目的,所以也无需设置密码。如果一切顺利的话,可以在用户主目录里找到.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH Key的秘钥对,id_rsa是私钥,不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。
然后登陆GitHub,打开“Account settings”,“SSH Keys”页面。点“Add SSH Key”,填上任意Title,在Key文本框里粘贴id_rsa.pub文件的内容:
2、创建仓库
首先,登陆GitHub,然后,在右上角找到“New repository”按钮,创建一个新的仓库:
点击创建后跳转到仓库:
3、远程仓库
① 目前,在GitHub上的这个spider仓库还是空的,GitHub告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库,由于本地还从未进行过repository创建,所以先用第一种方式创建本地仓库,然后进行远程上传:
[root@localhost lzl]# mkdir spider [root@localhost lzl]# cd spider [root@localhost spider]# git init # 生成仓库 初始化空的 Git 版本库于 /lzl/spider/.git/ [root@localhost spider]# echo '# -spider' >>README.md # 创建文件 [root@localhost spider]# git add README.md [root@localhost spider]# git commit -m 'first commit' # 提交 [master(根提交) 872c5e6] first commit 1 file changed, 1 insertion(+) create mode 100644 README.md [root@localhost spider]# git remote add origin git@github.com:jefreylian/-spider.git # 远程连接 [root@localhost spider]# git push -u origin master # 推送数据 The authenticity of host 'github.com (192.30.255.113)' can't be established. RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'github.com,192.30.255.113' (RSA) to the list of known hosts. Counting objects: 3, done. Writing objects: 100% (3/3), 217 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To git@github.com:jefreylian/-spider.git * [new branch] master -> master 分支 master 设置为跟踪来自 origin 的远程分支 master。 # 推送成功
此时刷新github下spider仓库,可以看到新上传的README.md文件已经上传
② 刚刚是先有本地库,后有远程库的时候,如何关联远程库。现在要做的是如何把远程库克隆到本地,然后再进行其他操作:
在本地找一个你想存放这个远程仓库的目录,然后在本地命令行用git clone 命令来克隆这个远程库
[root@localhost project]# git clone git@github.com:jefreylian/spider.git 正克隆到 '-spider'... remote: Counting objects: 9, done. remote: Compressing objects: 100% (5/5), done. remote: Total 9 (delta 0), reused 9 (delta 0), pack-reused 0 接收对象中: 100% (9/9), done. [root@localhost project]# cd spider/ [root@localhost spider]# ll 总用量 8 -rw-r--r-- 1 root root 27 7月 5 15:51 index.html -rw-r--r-- 1 root root 10 7月 5 15:51 README.md
如果有多个人协作开发,那么每个人各自从远程克隆一份就可以了。
你也许还注意到,GitHub给出的地址不止一个,还可以用https://github.com/jefrey/spider.git 这样的地址。实际上,Git支持多种协议,默认的git://
使用ssh,但也可以使用https
等其他协议。
使用https
除了速度慢以外,还有个最大的麻烦是每次推送都必须输入口令,但是在某些只开放http端口的公司内部就无法使用ssh
协议而只能用https
。
git精通
前言:
因为最初是从Linux起家的,非常依赖文件系统的一些特性,这些在 Linux 下表现的很好,而 Windows 下特别糟糕Git 中文教程
Git是一个开源的分布式版本控制系统,用以有效、高速的处理从很小到非常大的项目版本管理.
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
Torvalds 开始着手开发 Git 是为了作为一种过渡方案来替代 BitKeeper,后者之前一直是 Linux 内核开发人员在全球使用的主要源代码工具。开放源码社区中的有些人觉得 BitKeeper 的许可证并不适合开放源码社区的工作,因此 Torvalds 决定着手研究许可证更为灵活的版本控制系统。尽管最初 Git 的开发是为了辅助 Linux 内核开发的过程,但是我们已经发现在很多其他自由软件项目中也使用了 Git。例如 最近就迁移到 Git 上来了,很多 Freedesktop 的项目也迁移到了 Git 上。
1、安装git:
最早Git是在Linux上开发的,很长一段时间内,Git也只能在Linux和Unix系统上跑。不过,慢慢地有人把它移植到了Windows上。现在,Git可以在Linux、Unix、Mac和Windows这几大平台上正常运行了。
linux系统下,你可以试着输入git
,看看系统有没有安装Git:
[root@localhost lzl]# git The program 'git' is currently not installed. You can install it by typing: sudo apt-get install git
像上面的命令,有很多Linux会友好地告诉你Git没有安装,还会告诉你如何安装Git。
如果你碰巧用Debian或Ubuntu Linux,通过一条sudo apt-get install git
就可以直接完成Git的安装,非常简单。
2、远程上传:
[root@localhost project]# git clone git@github.com:jefreylian/spider.git [root@localhost project]# cd spider/ [root@localhost spider]# echo '#create new file' > new.py # 创建新文件 [root@localhost spider]# git status # 查看状态 # 位于分支 master # 未跟踪的文件: # (使用 "git add <file>..." 以包含要提交的内容) # # new.py 提交为空,但是存在尚未跟踪的文件(使用 "git add" 建立跟踪) [root@localhost spider]# git add new.py # 文件由工作区提交到暂存区 [root@localhost spider]# git commit -m 'first commit' # 加提交标识 [root@localhost spider]# git push -u origin master # 把代码提交到仓库
补充:
[root@localhost spider]# git add new.py # 添加new.py [root@localhost spider]# git add . # 添加所有 [root@localhost spider]# git config --global user.email "lianzhilei0711@163.com" # 更改log显示名 [root@localhost spider]# git config --global user.name 'Jefrey' [root@localhost spider]# vim .git/config # 查看本地git设置
3、工作区和暂存区
Git和其他版本控制系统如SVN的一个不同之处就是有暂存区的概念。
先来看名词解释。
工作区(Working Directory)
就是你在电脑里能看到的目录,比如我的spider文件夹就是一个工作区:
[root@localhost spider]# ll drwxr-xr-x 2 root root 20 7月 5 17:09 conf -rw-r--r-- 1 root root 27 7月 5 15:51 index.html -rw-r--r-- 1 root root 44 7月 5 17:31 new.py -rw-r--r-- 1 root root 23 7月 5 15:57 README.md
版本库(Repository)
工作区有一个隐藏目录.git
,这个不算工作区,而是Git的版本库。
Git的版本库里存了很多东西,其中最重要的就是称为stage(或者叫index)的暂存区,还有Git为我们自动创建的第一个分支master
,以及指向master
的一个指针叫HEAD
。
分支和HEAD
的概念我们以后再讲。
前面讲了我们把文件往Git版本库里添加的时候,是分两步执行的:
第一步是用git add
把文件添加进去,实际上就是把文件修改添加到暂存区;
第二步是用git commit
提交更改,实际上就是把暂存区的所有内容提交到当前分支。
因为我们创建Git版本库时,Git自动为我们创建了唯一一个master
分支,所以,现在,git commit
就是往master
分支上提交更改。
你可以简单理解为,需要提交的文件修改通通放到暂存区,然后,一次性提交暂存区的所有修改。
4、本地回滚
现在,你已经学会了修改文件,然后把修改提交到Git版本库,假如要恢复到之前的代码也就是回滚,如何操作:
[root@localhost spider]# git log # 查看提交记录 commit 1560f36d2ebb48a47c7db12cd0aedf88e3d2a0f9 Author: Jefrey <lianzhilei0711@163.com> Date: Wed Jul 5 16:43:16 2017 +0800 conf commit commit 81a32a17078f92d290ea29a7bbc928e1b30bf501 Author: Jefrey <lianzhilei0711@163.com> Date: Wed Jul 5 16:34:08 2017 +0800 third commit commit 40ac1cff6d9bc827c1c3d8dac2b3aa838e4dfe70 Author: lianzl <lianzl@commchina.net> Date: Wed Jul 5 16:29:56 2017 +0800 second commit commit daf94f4cf0919b0fbc86b4a0318568a19bceb307 Author: lianzl <lianzl@commchina.net> Date: Wed Jul 5 16:18:54 2017 +0800 first commit
git log命令显示从最近到最远的提交日志,我们可以看到4次提交,最近的一次是conf commit,上一次是third commit,最早的一次是first commit。 如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline
参数
[root@localhost spider]# git log --pretty=oneline 1560f36d2ebb48a47c7db12cd0aedf88e3d2a0f9 conf commit 81a32a17078f92d290ea29a7bbc928e1b30bf501 third commit 40ac1cff6d9bc827c1c3d8dac2b3aa838e4dfe70 second commit daf94f4cf0919b0fbc86b4a0318568a19bceb307 first commit
① 回滚到上一次提交的代码:
[root@localhost spider]# git reset --hard HEAD^ HEAD 现在位于 81a32a1 third commit [root@localhost spider]# git log --pretty=oneline 81a32a17078f92d290ea29a7bbc928e1b30bf501 third commit 40ac1cff6d9bc827c1c3d8dac2b3aa838e4dfe70 second commit daf94f4cf0919b0fbc86b4a0318568a19bceb307 first commit
查看文件,发现现在已经回滚到上一次提交代码的状态
② 回滚到指定版本代码:
[root@localhost spider]# git reset --hard 40ac1cff # 指定前7位即可 HEAD 现在位于 40ac1cf second commit [root@localhost spider]# git log --pretty=oneline 40ac1cff6d9bc827c1c3d8dac2b3aa838e4dfe70 second commit daf94f4cf0919b0fbc86b4a0318568a19bceb307 first commit
现在,你回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办?找不到新版本的commit id怎么办?
在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^回退到third commit版本时,再想恢复到最新conf commit的版本,就必须找到conf commit的commit id。Git提供了一个命令git reflog用来记录你的每一次命令:
[root@localhost spider]# git reflog 40ac1cf HEAD@{0}: reset: moving to 40ac1cff 81a32a1 HEAD@{1}: reset: moving to HEAD^ 1560f36 HEAD@{2}: commit: conf commit 81a32a1 HEAD@{3}: commit: third commit 40ac1cf HEAD@{4}: commit: second commit daf94f4 HEAD@{5}: commit: first commit [root@localhost spider]# git reset --hard 1560f36 # 指定最新提交代码id HEAD 现在位于 1560f36 conf commit [root@localhost spider]# git log --pretty=oneline # 恢复如初 1560f36d2ebb48a47c7db12cd0aedf88e3d2a0f9 conf commit 81a32a17078f92d290ea29a7bbc928e1b30bf501 third commit 40ac1cff6d9bc827c1c3d8dac2b3aa838e4dfe70 second commit daf94f4cf0919b0fbc86b4a0318568a19bceb307 first commit
注:切记是本地代码回滚,不会影响到github上的仓库内容
5、撤销修改
① 未提交到暂存区撤销
假如现在在new.py文件中添加了两行代码:
#create new file second commit third commit git is great but my stupid boss still prefers SVN.
在你准备提交前,一杯咖啡起了作用,你猛然发现了“stupid boss”可能会让你丢掉这个月的奖金!
此时用git status
查看一下:
[root@localhost spider]# git status # 位于分支 master # 尚未暂存以备提交的变更: # (使用 "git add <file>..." 更新要提交的内容) # (使用 "git checkout -- <file>..." 丢弃工作区的改动) # # 修改: new.py # 修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
你可以发现,Git会告诉你,git checkout -- file
可以丢弃工作区的修改:
[root@localhost spider]# git checkout -- new.py [root@localhost spider]# more new.py #create new file second commit third commit
好了,一切恢复如初,文件中修改的内容全部清除;new.py文件修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态
new.py
自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态;- new.py已经添加到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态;
② 已经提交到暂存区的文件撤销
不但修改了代码,而且还add存放到缓存区了:
[root@localhost spider]# more new.py #create new file second commit third commit Git tracks changes of files. My stupid boss still prefers SVN. [root@localhost spider]# git add new.py
庆幸的是,在commit
之前,你发现了这个问题。用git status
查看一下,修改只是添加到了暂存区,还没有提交:
[root@localhost spider]# git status # 位于分支 master # 要提交的变更: # (使用 "git reset HEAD <file>..." 撤出暂存区) # # 修改: new.py
Git同样告诉我们,用命令git reset HEAD file
可以把暂存区的修改撤销掉(unstage),重新放回工作区:
[root@localhost spider]# git reset HEAD new.py 重置后撤出暂存区的变更: M new.py [root@localhost spider]# git status # 位于分支 master # 尚未暂存以备提交的变更: # (使用 "git add <file>..." 更新要提交的内容) # (使用 "git checkout -- <file>..." 丢弃工作区的改动) # # 修改: new.py # 修改尚未加入提交(使用 "git add" 和/或 "git commit -a")
再次执行git checkout -- <file>,恢复到最初:
[root@localhost spider]# git checkout -- new.py [root@localhost spider]# git status # 位于分支 master 无文件要提交,干净的工作区
注:这里所有的撤销都是指代码未提交到仓库时的撤销
6、删除操作
在Git中,删除也是一个修改操作,我们实战一下,先添加一个新文件test.txt到Git并且提交:
$ git add . $ git commit -m "add test.txt" [master a8fa95a] add test.txt 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test.txt
一般情况下,你通常直接在文件管理器中把没用的文件删了,或者用rm
命令删了
[root@localhost spider]# rm test.txt
这个时候,Git知道你删除了文件,因此,工作区和版本库就不一致了,git status
命令会立刻告诉你哪些文件被删除了:
$ git status On branch master Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: test.txt no changes added to commit (use "git add" and/or "git commit -a")
现在你有两个选择,一是确实要从版本库中删除该文件,那就用命令git rm
删掉,并且git commit
:
x$ git rm test.txt rm 'test.txt' $ git commit -m "remove test" [master 03df00a] remove test 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 test.txt
现在,文件就从版本库中被删除了。
另一种情况是删错了,因为版本库里还有呢,所以可以很轻松地把误删的文件恢复到最新版本:
[root@localhost spider]# git checkout -- test.txt
git checkout
其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。