CentOS 7 学习(四)Git配置(一)
1、对于版本管理系统,目前常用的是Subverion和Git,Subversion是集中式版本管理系统中最好的,所有人的代码都要提交到服务器上,如果要知道修改历史,就需要访问服务器;Git的哲学不同,是分布式管理版本,即本地也维护一个或者多个版本或分支,需要的时候才会提交到主服务器上,提供了非常优秀的分支合并功能,这种方式非常适合于分布式开发,即可以在本机开发完成,再同步到主干上,同时本机也可以拥有所有的历史修改信息。
2、环境:
主服务器:CentOS 7, 192.168.1.14
从服务器:CentOS 7, 192.168.1.12
3、CentOS 7带的git版本太低了,是1.8.3,为方便起见,从主站上下载了git-2.0.4.tar.gz,运行命令
tar xvf git-2.0.4.tar.gz
cd git-2.0.4
./configure
make
make install
在make命令,可能会出现错误,我遇上的如下:
/usr/bin/perl Makefile.PL PREFIX='/usr/local' INSTALL_BASE='' --localedir='/usr/local/share/locale'
Can't locate ExtUtils/MakeMaker.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at Makefile.PL line 3.
BEGIN failed--compilation aborted at Makefile.PL line 3.
make[1]: *** [perl.mak] 错误 2
make: *** [perl/perl.mak] 错误 2
这是缺少一些Perl的扩展包,运行命令yum install perl-ExtUtils-*
再执行make指令就可以了
[root@centos1 git-2.0.4]# git --version
git version 2.0.4
这说明安装成功了
按照相似的步骤,在另外一台机器上创建同样的git
4、在从服务器上做些测试
1)创建一个用户git,主目录为/opt/git,这个用户是将来连接git服务器的用户名,/opt/git是git仓库的起始目录
useradd git -d /opt/git -U -m -s /bin/bash
2)创建版本库
[git@centos-s1 ~]$ su - git
[git@centos-s1 ~]$ mkdir mysite
[git@centos-s1 ~]$ cd mysite
[git@centos-s1 mysite]$ ls
[git@centos-s1 mysite]$ git init
初始化空的 Git 版本库于 /opt/git/mysite/.git/
3)配置
git的配置通常用git config命令完成,这个命令有很多参数,大致如下
[git@centos-s1 mysite]$ git config
用法:git config [选项]
配置文件位置
--global 使用全局配置文件
--system 使用系统级配置文件
--local 使用版本库级配置文件
-f, --file <文件> 使用指定的配置文件
--blob <数据对象ID> 从给定的数据对象读取配置
操作
--get 获取值:name [value-regex]
--get-all 获得所有的值:key [value-regex]
--get-regexp 根据正则表达式获得值:name-regex [value-regex]
--get-urlmatch 获得 URL 取值:section[.var] URL
--replace-all 替换所有匹配的变量:name value [value_regex]
--add 添加一个新的变量:name value
--unset 删除一个变量:name [value-regex]
--unset-all 删除所有匹配项:name [value-regex]
--rename-section 重命名小节:old-name new-name
--remove-section 删除一个小节:name
-l, --list 列出所有
-e, --edit 打开一个编辑器
--get-color <slot> 找到配置的颜色:[默认]
--get-colorbool <slot>
找到颜色设置:[stdout-is-tty]
类型
--bool 值是 "true" 或 "false"
--int 值是十进制数
--bool-or-int 值是 --bool or --int
--path 值是一个路径(文件或目录名)
其它
-z, --null 终止值是NUL字节
--includes 查询时参照 include 指令递归查找
可以看到配置的等级有3层,全局、系统、本地版本库,使用-l或--list命令可以看到已有的配置,目前还什么都没有。
[git@centos-s1 mysite]$ git config --global user.name "Shi Yongqiang"
[git@centos-s1 mysite]$ git config --global user.email "flysyq@163.com"
[git@centos-s1 mysite]$ git config --global --list
user.name=Shi Yongqiang
user.email=flysyq@163.com
用户名和用户邮件是必须的,这是用来标识你的个人身份,会体现在你的提交历史中。
4)常用命令
git add file_name #增加文件到暂存区
git commit file_name -m "file comment" 提交到本地
git log #查看log
git status #显示状态,即是否有文件修改了没有提交
git branch RB1.0 master #创建分支(必须主分支有了内容这个命令才生效),前一个参数为分支名,后一个为源分支名,系统默认创建的分支,即根分支,叫master
git checkout RB1.0 #切换到RB1.0分支,这时候查看当前目录,会发现已经变成RB1.0的内容了,如果创建了分支RB1.0之后修改了master分支的文件,会看的更清楚
git checkout -b RB2.0 RB1.0 #创建一个新分支,并切换到新分支
git merge RB1.0 #当前分支为master,这个命令将RB1.0的内容合并到master分支上,这时候有可能会出现冲突,需要手工解决之后才能提交,这时候其内容已经提交到master的当前目录了,但是还没有最后提交,你可以修改文件内容,提交,合并完成了,如果没有冲突,这个命令很容易就完成了。
日常来说,这些命令就够了,不过很少有人会这么用,一般都会使用开发工具如Eclipse带的git工具来实现。
5)协同工作
本机工作的git没什么特别之处,其实和本机安装一个SubVersion没太多区别,其优势在于其分布式开发。
a)连接远程服务器
git clone https://github.com/alibaba/otter.git #从远程服务器下载git项目到本地,这个地址指向的阿里巴巴的mysql同步项目-otter
b)自己架设服务器
在从服务器上按照上述办法架设一个git服务器,这样主从服务器就都有了git环境,理想环境是在从服务器上开发,主服务器上发布。
对于分布式管理git项目,对于分支的选择会很麻烦,可以参考这个博客http://www.ruanyifeng.com/blog/2012/07/git.html
一般来说,都会有至少两个分支,一个主分支master,一个开发分支developer,开发结束之后,将开发分支合并到主分支上发布,如果出现同时开发的现象,可以将developer分支再创建一个分支,修改完毕之后,合并到开发分支和主分支上,这个分支在主分支发布之后要立刻删除,否则会不好管理。需要注意的是,这种情况下开发分支和主分支再次合并很可能会出现冲突,需要耐心解决。
访问git服务器常用的协议有ssh、git、http,通常来说ssh适合小团队读写,http适合大范围读,git相对来较难架设,且使用非标准端口,只能在内部系统使用。更详细的说明,可以看git官方文档。
使用ssh协议连接服务器有两种办法,一种是通过用户名密码连接,一种是通过公钥私钥连接,前者容易配置,但是没法区分人群,除非不停的增加系统用户,为简单起见,都试验一下:
i)使用用户名密码
在主服务器(192.168.1.14)上创建一个git仓库,如下命令
[git@centos1 ~]$ mkdir gitsite
[git@centos1 ~]$ cd gitsite/
[git@centos1 gitsite]$ git init
初始化空的 Git 版本库于 /opt/git/gitsite/.git/
[git@centos1 gitsite]$ vim test.txt
[git@centos1 gitsite]$ git add test.txt
[git@centos1 gitsite]$ git commit -m "git 测试"
[master(根提交) 82e77f9] git 测试
1 file changed, 1 insertion(+)
create mode 100644 test.txt
记得要设置用户git的密码
在从服务器上(192.168.1.12)运行命令
[git@centos-s1 ~]$ git clone git@192.168.1.14:/opt/git/gitsite
正克隆到 'gitsite'...
git@192.168.1.14's password:
remote: 对象计数中: 3, 完成.
remote: Total 3 (delta 0), reused 0 (delta 0)
接收对象中: 100% (3/3), 完成.
检查连接... 完成。
本地出现一个目录gitsite,进入目录,可以看到text.txt文件,运行git log可以看到提交历史。
这样就创建了一个本地版本,
[git@centos-s1 gitsite]$ git status
位于分支 master
您的分支与上游分支 'origin/master' 一致。
无文件要提交,干净的工作区
本地编辑一个文件,提交到14服务器上,如下
[git@centos-s1 gitsite]$ vim t.txt
[git@centos-s1 gitsite]$ git add .
[git@centos-s1 gitsite]$ git commit -m "add by 12"
[master d1cd89a] add by 12
1 file changed, 1 insertion(+), 1 deletion(-)
[git@centos-s1 gitsite]$ git commit -m "add by 12"
位于分支 master
您的分支领先 'origin/master' 共 1 个提交。
(使用 "git push" 来发布您的本地提交)
无文件要提交,干净的工作区
可以看出本地创建了t.txt,提交到本地,在第二次提交的时候,系统给了提示,可以用git push来更新到远程目录
运行命令如下
[git@centos-s1 gitsite]$ git push
warning: push.default 尚未设置,它的默认值在 Git 2.0 已从 'matching'
变更为 'simple'。若要不再显示本信息并保持传统习惯,进行如下设置:
git config --global push.default matching
若要不再显示本信息并从现在开始采用新的使用习惯,设置:
git config --global push.default simple
当 push.default 设置为 'matching' 后,git 将推送和远程同名的所有
本地分支。
从 Git 2.0 开始,Git 缺省采用更为保守的 'simple' 模式,只推送当前
分支到远程关联的同名分支,即 'git push' 推送当前分支。
参见 'git help config' 并查找 'push.default' 以获取更多信息。
('simple' 模式由 Git 1.7.11 版本引入。如果您有时要使用老版本的 Git,
为保持兼容,请用 'current' 代替 'simple')
git@192.168.1.14's password:
对象计数中: 6, 完成.
Delta compression using up to 2 threads.
压缩对象中: 100% (4/4), 完成.
写入对象中: 100% (6/6), 591 bytes | 0 bytes/s, 完成.
Total 6 (delta 0), reused 0 (delta 0)
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.
To git@192.168.1.14:/opt/git/gitsite
! [remote rejected] master -> master (branch is currently checked out)
error: 无法推送一些引用到 'git@192.168.1.14:/opt/git/gitsite'
这是个常见错误,看提示信息可以看出很多东西,首先来说,提示设置push.default变量,2.0之前默认是matching,提交所有和远程同名的分支,2.0之后默认是simple,只提交当前分支。后面的提示是远程的分支正处于checkout状态,所以无法推送。
可以在服务器上配置,可以提交当前分支,如下
[git@centos1 gitsite]$ git config --global receive.denyCurrentBranch "ignore"
这样12服务器就可以提交了。
所以如果是大型的项目,多个分支、多个版本,一般来说,主服务器上的版本库都会建立裸库,即没法进行checkout,add,commit的库,不过对于小型项目,主版本库还是能操作比较好,如果已经比较成熟了,就可以采用裸库。
有些情况下,是先有本地的版本库,然后采用主版本库,需要将本地的版本库复制到主本版本库,然后可以同步
在12机器创建版本库gitsite1,然后
[git@centos-s1 ~]$ git init --template=/opt/git/gitsite1 gitsite1.git
初始化空的 Git 版本库于 /opt/git/gitsite1.git/.git/
[git@centos-s1 ~]$ cd gitsite1.git/
[git@centos-s1 gitsite1.git]$ ls
[git@centos-s1 gitsite1.git]$ pwd
/opt/git/gitsite1.git
[git@centos-s1 gitsite1.git]$ cd ..
[git@centos-s1 ~]$ scp -r gitsite1.git/ ssh:git@192.168.1.14:/opt/git
git@192.168.1.14's password:
test.txt 100% 28 0.0KB/s 00:00
HEAD 100% 23 0.0KB/s 00:00
config
100% 92 0.1KB/s 00:00
这样就传输到了主目录
在本地和远程建立连接
[git@centos-s1 gitsite1]$ git push git@192.168.1.14:/opt/git/gitsite1.git master
git@192.168.1.14's password:
对象计数中: 3, 完成.
写入对象中: 100% (3/3), 234 bytes | 0 bytes/s, 完成.
Total 3 (delta 0), reused 0 (delta 0)
To git@192.168.1.14:/opt/git/gitsite1.git
* [new branch] master -> master
master是分支名称
也可以为远程服务器建立名称,这样用起来会舒服一些
[git@centos-s1 gitsite1]$ git remote add orign git@192.168.1.14:/opt/git/gitsite1.git
[git@centos-s1 gitsite1]$ git push orign master
git@192.168.1.14's password:
Everything up-to-date
远程的常用命令
git push #推送
git pull #下载远程代码
ii)使用密钥
密钥的使用非常简单,客户端创建公钥和密钥,设置密钥密码,将公钥上传到服务器,服务器将公钥加入信任文件中,然后客户端操作会提示输入密码,就是密码密码,具体如下
[git@centos-s1 gitsite1]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/opt/git/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /opt/git/.ssh/id_rsa.
Your public key has been saved in /opt/git/.ssh/id_rsa.pub.
The key fingerprint is:
20:70:11:47:f8:ca:91:37:6d:5d:43:cd:13:1c:40:61 git@centos-s1
The key's randomart image is:
+--[ RSA 2048]----+
| . +=o oE*oo |
| o.. .o = |
| .o.. . . . . |
| o.+.o . |
| . + oS |
| o |
| |
| |
| |
+-----------------+
[git@centos-s1 gitsite1]$ cd
[git@centos-s1 ~]$ cd .ssh
[git@centos-s1 .ssh]$ ls
id_rsa id_rsa.pub known_hosts
[git@centos-s1 .ssh]$ mv id_rsa.pub id_rsa_shiyq.pub
[git@centos-s1 .ssh]$ scp id_rsa_shiyq.pub git@192.168.1.14:/opt/git
Enter passphrase for key '/opt/git/.ssh/id_rsa':
git@192.168.1.14's password:
id_rsa_shiyq.pub 100% 395 0.4KB/s 00:00
[git@centos-s1 .ssh]$ scp id_rsa_shiyq.pub git@192.168.1.14:/opt/git
Enter passphrase for key '/opt/git/.ssh/id_rsa':
id_rsa_shiyq.pub
服务器端
[git@centos1 ~]$ mv id_rsa_shiyq.pub .ssh/.
[git@centos1 ~]$ cd .ssh/
[git@centos1 .ssh]$ ls
authorized_keys id_rsa id_rsa.pub id_rsa_shiyq.pub known_hosts
[git@centos1 .ssh]$ cat id_rsa_shiyq.pub >> authorized_keys
客户端
[git@centos-s1 gitsite1]$ vim test.txt
[git@centos-s1 gitsite1]$ git add .
[git@centos-s1 gitsite1]$ git commit -m "add by 12 下午"
[master 77801a8] add by 12 下午
1 file changed, 6 insertions(+), 1 deletion(-)
[git@centos-s1 gitsite1]$ git push git@192.168.1.14:/opt/git/gitsite1.git master
Enter passphrase for key '/opt/git/.ssh/id_rsa':
对象计数中: 3, 完成.
Delta compression using up to 2 threads.
压缩对象中: 100% (2/2), 完成.
写入对象中: 100% (3/3), 304 bytes | 0 bytes/s, 完成.
Total 3 (delta 0), reused 0 (delta 0)
To git@192.168.1.14:/opt/git/gitsite1.git
4cbda98..77801a8 master -> master
从远程服务器下载数据常见的办法是git fetch和git pull
git pull比较危险,因为直接从服务器上下载,覆盖本地
git fetch是将远程的分支下载到本地的临时分支上,可以看有多大区别,然后可以选择是否合并。