git和github(部署)

下半年,运维组将逐步接手各应用的部署上线工作

为了规范化整个流程,打算所有的部署都基于tag来进行

以前的git部署脚本是直接fetch最新的代码到master上

所以就需要进行相应的修改,对tag进行操作

以下是tag的一些基本操作

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#打tag t1
 
git tag -a -m 'for tag t1'
 
git tag t2  b389     为某次的commit打一个tag
 
#显示所有的tag
 
git tag
 
#查看本地tag
 
git show t2
 
#查看远程tag
 
git ls-remote -t
 
#删除本地tag t1
 
git tag -d t1
 
#删除远程tag
 
git push origin :refs/tags/t4
 
#以tag t4为基础生成新的分支b4
 
git branch b4 t4
 
#把某个tag push到远程,默认的git push是不会push tag信息的
 
git push origin t_master_20100713
 
#push所有的tag
 
git push origin --tags
 
#切换到某个tag上
 
git checkout t2

部署的部分脚本如下:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
echo "Begin git fetch from remote repositories"
 
ori_commit_id=`cd $local_module_path;git log -1 --format="%h"`
 
cd $local_module_path;git checkout master;git reset --hard;git fetch origin
 
new_commit_id=`cd $local_module_path;git log -1 --format="%h" $tag_name`
 
echo "From commitid $ori_commit_id to $new_commit_id have some changed files........................................."
 
echo ""
 
cd $local_module_path;git log --name-status --pretty=format:"%ci %Cgreen%aN%Creset %s" $ori_commit_id..$new_commit_id
 
echo ""
 
echo "End  commitid $ori_commit_id to $new_commit_id have some changed files.........................................."
 
cd $local_module_path;git reset --hard;git pull origin master;git checkout $tag_name;
发表在Git 标签有Gittag 1条回复

搭建gitweb环境

gitweb是git提供的一个基于web的版本查看工具

在新版的git源码中,它已经打包进去了

我们可以使用cgi方式,让gitweb运行在apache中

安装配置如下:

#进入git的src目录中
cd /opt/ysz/src/git-1.7.0
make clean
#编译gitweb,GITWEB_PROJECTROOT为要查看的git仓库目录,bindir为git目录
make GITWEB_PROJECTROOT="/opt/gitroot/repositories/" bindir=/usr/local/bin gitweb
mkdir /opt/gitroot/repositories/gitweb
#将cgi文件和静态文件拷贝到某个地方
cp gitweb/gitweb.cgi /opt/gitroot/repositories/gitweb
cp gitweb/*.js gitweb/*.css gitweb/*.png /opt/gitroot/repositories/gitweb

配置Apache2:

<VirtualHost *:80>
    DocumentRoot /opt/gitroot/repositories/gitweb
    ServerName 10.10.71.10
    ScriptAlias /gitweb /opt/gitroot/repositories/gitweb/gitweb.cgi
    
    <Location />
        AuthName "Access auth"
        AuthType Basic
        AuthUserFile /usr/local/apache2/conf/passwd
        Require valid-user
    </Location>
    
    <Directory /opt/gitroot/repositories/gitweb>
        Options Indexes FollowSymLinks MultiViews
        Order allow,deny
        Allow from all
    </Directory>
    ErrorLog "/opt/log/apache2log/gitweb_error.log"
    CustomLog "/opt/log/apache2log/gitweb_access.log" common
</VirtualHost>

这样配置后,就可以通过以下url访问gitweb了

http://10.10.71.10/gitweb

由于是基于web访问git仓库,所以加上基本的权限认证

发表在Git 标签有Gitgitweb 2条回复

Git版本恢复命令reset

reset命令有3种方式:

  1. git reset –mixed:此为默认方式,不带任何参数的git reset,即时这种方式,它回退到某个版本,只保留源码,回退commit和index信息

  2. git reset –soft:回退到某个版本,只回退了commit的信息,不会恢复到index file一级。如果还要提交,直接commit即可

  3. git reset –hard:彻底回退到某个版本,本地的源码也会变为上一个版本的内容

以下是一些reset的示例:

折叠 复制代码

  1. #回退所有内容到上一个版本  

  2. git reset HEAD^  

  3. #回退a.py这个文件的版本到上一个版本  

  4. git reset HEAD^ a.py  

  5. #向前回退到第3个版本  

  6. git reset –soft HEAD~3  

  7. #将本地的状态回退到和远程的一样  

  8. git reset –hard origin/master  

  9. #回退到某个版本  

  10. git reset 057d  

  11. #回退到上一次提交的状态,按照某一次的commit完全反向的进行一次commit  

  12. git revert HEAD  

如果我们某次修改了某些内容,并且已经commit到本地仓库,而且已经push到远程仓库了

这种情况下,我们想把本地和远程仓库都回退到某个版本,该怎么做呢?

前面讲到的git reset只是在本地仓库中回退版本,而远程仓库的版本不会变化

这样,即时本地reset了,但如果再git pull,那么,远程仓库的内容又会和本地之前版本的内容进行merge

这并不是我们想要的东西,这时可以有2种办法来解决这个问题:

  1. 直接在远程server的仓库目录下,执行git reset –soft 10efa来回退。注意:在远程不能使用mixed或hard参数

  2. 在本地直接把远程的master分支给删除,然后再把reset后的分支内容给push上去,如下:

    折叠 复制代码

    1. #新建old_master分支做备份  

    2. git branch old_master  

    3. #push到远程  

    4. git push origin old_master:old_master  

    5. #本地仓库回退到某个版本  

    6. git reset –hard bae168  

    7. #删除远程的master分支  

    8. git push origin :master  

    9. #重新创建master分支  

    10. git push origin master  

在删除远程master分支时,可能会有问题,见下:

折叠 复制代码

  1. $ git push origin :master  

  2. error: By default, deleting the current branch is denied, because the next  

  3. error: 'git clone' won't result in any file checked out, causing confusion.  

  4. error:  

  5. error: You can set 'receive.denyDeleteCurrent' configuration variable to  

  6. error: 'warn' or 'ignore' in the remote repository to allow deleting the  

  7. error: current branch, with or without a warning message.  

  8. error:  

  9. error: To squelch this message, you can set it to 'refuse'.  

  10. error: refusing to delete the current branch: refs/heads/master  

  11. To git@xx.sohu.com:gitosis_test  

  12.  ! [remote rejected] master (deletion of the current branch prohibited)  

  13. error: failed to push some refs to 'git@xx.sohu.com:gitosis_test'  

这时需要在远程仓库目录下,设置git的receive.denyDeleteCurrent参数

折叠 复制代码

  1. git receive.denyDeleteCurrent warn  

然后,就可以删除远程的master分支了

虽然说有以上2种方法可以回退远程分支的版本,但这2种方式,都挺危险的,需要谨慎操作……

发表在Git 标签有Gitreset 5条回复

从Git仓库中恢复已删除的分支或丢失的commit

在使用Git的过程中,有时可能会有一些误操作

比如:执行checkout -f 或 reset -hard 或 branch -d删除一个分支

结果造成本地(远程)的分支或某些commit丢失

这时,我们可以通过reflog来进行恢复,前提是丢失的分支或commit信息没有被git gc清除

一般情况下,gc对那些无用的object会保留很长时间后才清除的

reflog是git提供的一个内部工具,用于记录对git仓库进行的各种操作

可以使用git reflog show或git log -g命令来看到所有的操作日志

 

恢复的过程很简单:

1. 通过git log -g命令来找到我们需要恢复的信息对应的commitid,可以通过提交的时间和日期来辨别

2. 通过git branch recover_branch commitid 来建立一个新的分支

这样,我们就把丢失的东西给恢复到了recover_branch分支上了

发表在Git 标签有Gitreflog 发表回复

Git clone远程分支

git clone默认会把远程仓库整个给clone下来

但只会在本地默认创建一个master分支

如果远程还有其他的分支,此时用git branch -a查看所有分支:

折叠 复制代码

  1. * master   

  2. remotes/origin/HEAD -> origin/master   

  3. remotes/origin/master   

  4. remotes/origin/python_mail.skin   

  5. remotes/origin/udisk   

  6. remotes/origin/vip

 能看到远程的所有的分支,如remotes/origin/python_mail.skin

可以使用checkout命令来把远程分支取到本地,并自动建立tracking

折叠 复制代码

  1. $ git checkout -b python_mail.skin origin/python_mail.skin   

  2. Branch python_mail.skin set up to track remote branch python_mail.skin from origin.   

  3. Switched to a new branch 'python_mail.skin'

或者使用-t参数,它默认会在本地建立一个和远程分支名字一样的分支

折叠 复制代码

  1. $ git checkout -t origin/python_mail.skin

 也可以使用fetch来做:

折叠 复制代码

  1. $ git fetch origin python_mail.skin:python_mail.skin

 不过通过fetch命令来建立的本地分支不是一个track branch,而且成功后不会自动切换到该分支上

注意:不要在本地采用如下方法:

折叠 复制代码

  1. $ git branch python_mail.skin   

  2. $ git checkout python_mail.skin   

  3. $ git pull origin python_mail.skin:python_mail.skin

因为,这样建立的branch是以master为基础建立的,再pull下来的话,会和master的内容进行合并,有可能会发生冲突…

发表在Git 标签有branchcloneGit 发表回复

git中配置autocrlf来正确处理crlf

在使用git的过程中,如果我们的项目是跨平台开发的

那么CRLF的处理也许会成为一个很头疼的事情,有可能会出以下的莫名其妙的问题:

我们的某个开发人员在linux上提交的一个文件

当从windows上pull下来后,没做任何的修改,查看其status,它的状态已经是modifed了

即使你使用git checkout -f来恢复改文件,它的状态仍然是modified,真是郁闷…

后来,才发现就是CRLF惹的祸

 

我们都知道,在Windows上是CRLF来作为一行的结束符,而Linux上则是LF作为行结束符

在git中提供了autocrlf的设置,可以用来自动转换CRLF,它可以设置成true,false,input

Windows上的msysgit默认设置了autocrlf为true

这样,在提交时自动地把行结束符CRLF转换成LF,而在签出代码时把LF转换成CRLF

这样保证了从windows平台上提交的代码,都是以LF作为行结束符

在linux平台上,git默认设置autocrlf为false,也即它不会自动处理CRLF

这样就有一个问题,如果我们把windows上的一个文件给上传到linux上,并提交

那么,提交到仓库中的代码就会以CRLF来换行了,

这样就会导致我们在windows上查看改文件的状态就会是modified

解决这个问题有以下2个办法:

  1. 在Linux上设置autocrlf为input,这样,Git在提交时把CRLF转换成LF,签出时不转换

  2. 对于从Windows上直接拷到Linux上的文件,首先把它转换成linux格式后,再进行提交

发表在Git 标签有autocrlfGit 发表回复

使用Git hook来校验push用户名的合法性

Git和CVS一个很大的不同是,它没有一个完善的权限控制系统

即使采用了Gitosis工具,它实际上是通过公钥来控制某台服务器的权限

用户在使用git前,依然需要设置user.name来控制提交时的用户名

但即使你没有设置,会有一个默认的空用户名或者是自己的登录用户名,如root

这样通过git log就很难看到对应的代码到底是哪个人员修改的了

不过,可以通过hook来初步解决这个问题

在git目录下的hooks目录里,新建一个pre-receive的hook,代码如下:

折叠 复制代码

  1. while read old new name; do

  2. name=$(git log -1 –pretty=format:%aN $new)

  3. email=$(git log -1 –pretty=format:%ae $new)

  4. user_prefix=`echo $name | awk -F'_' '{print $1}'`

  5. check_user=`echo $GIT_VALID_USER | grep -c $user_prefix`

  6. if [ "$check_user" == "0" ]

  7. then

  8. echo "Username $name denied, please set user.name"

  9. exit 43

  10. else

  11. exit 0

  12. fi

  13. done

需要在服务器上设置一个环境变量GIT_VALID_USER,保存合法的用户名列表

当用户名校验不通过,则返回一个非0的值即可

如果需要严格的用户名校验,即提交的user.name必须是gitosis里配置的对应Client的用户名

则可以在/usr/local/lib/python2.5/site-packages/gitosis-0.2-py2.5.egg/gitosis/serve.py中第202行增加如下代码:

os.environ['GIT_USER']=user

然后在hook里校验name是否等于这个环境变量的值即可

但由于我们有一些公共的服务器,可能很多开发人员都会在上面push代码,所以不能使用此严格的校验方式

只能使用上述的有效用户名列表的验证方式

发表在Git 标签有Githookuser.name 发表回复

使用rsync+git来部署java代码

项目的版本控制切换到git后,相对于cvs来说,部署java程序有了一些问题
主要是因为:
1.cvs权限控制比较简单,只需要开个username,即可在服务器上update
   但是,我们用gitosis来管理权限,就需要把各服务器的公钥给传到gitosis上
2.cvs可以支持部分update,比如我们可以指定只update某个jsp
   但git是不可以的,pull下的就是最新的所有的代码,所以在pull之前一定要把更新内容给显示出来,便于确认

这样,我们需要写脚本,来完成从服务器上集中部署
大概有以下2种方案:
1.每个server上安装git,分配其只读的权限,从中央服务器上ssh到要部署的server上,并获取本次更新的文件,核心代码如下
  ori_commit_id=`ssh root@$host “cd $module_path;git log -1 –format=”%h””`
ssh root@$host “cd $module_path;git reset –hard;git fetch origin”
new_commit_id=`ssh root@$host “cd $module_path;git log -1 –format=\”%h\” origin/master”`
ssh root@$host “cd $module_path;git log –name-status –pretty=format:\”%ci %Cgreen%aN%Creset %s\” $ori_commit_id..$new_commit_id”
   这种部署方式,相对比较可靠,因为它直接ssh到server上,把该server本次更新的文件给列表了出来,确认后即可部署
2.在中央服务器上使用rsync来同步远程server的目录
  之所以用rsync是因为:scp和tar方式都无法来根据文件修改时间来确定要拷贝的文件,只能是全部覆盖或者每次修改部署脚本
  如果采用tar后再scp,那么所有文件都会被更新了,这样ant会把所有的src都重新编译一次,很麻烦的
  rsync的命令很简单,如下:
  rsync -e ssh -tpogrv /opt/test/ –exclude=.git $host://usr/local/src/test
  注意需要后面的-t参数,它表明把文件的时间也给rsync到远程server上。
  -exclude表明是排除.git目录,主要是相对路径
  这种部署方式,相对比较简单,不需要为每个服务器开git权限
  但由于比较的版本是中央服务器的目录,所以必须保证远程服务器的版本和中央服务器的版本相同,否则可能会有问题的

发表在Git 标签有Gitrsync 发表回复

Msysgit优化

快捷键:
Alt+Space+E+K: 选择文字,拷贝
Insert: 粘贴文字
Alt+Back: 删除到前一个空格
Ctl+Back: 删除之前的所有文字


设置alias
git config –global alias.l 'log -n 10 –format=”%h %ci %Cgreen%aN%Creset %s %n”'


查看2个版本之间修改的文件列表
git log –name-status –pretty=format:\”%ci %Cgreen%aN%Creset %s\”  1258e..a3584

发表在Git 标签有aliasGitmsysgit 发表回复

Git中使用外部工具来进行diff和merge

Git默认使用自己的diff来比较合并版本的
但它也能配置外部的工具来完成
对于Windows下的Msysgit,推荐使用winmerge
当然也还有其它很多的工具,如p4mergeBeyond Compare 
在Linux下我们可以使用vimdiff来代替

下面是配置的过程:
1.安装winmerge
2.在c:\Program Files\WinMerge下建一个diff.bat文件,放在其它Path能找到的路径下也可以
#!/bin/sh
“c:\Program Files\WinMerge\WinMergeU.exe” “$2″ “$5″
3.配置git
git config –global diff.external diff.bat
然后,再使用git diff时,就会自动打开winmerge,可视化的显示文件的差别了

如果要配置git merge使用外部的工具,以p4merge为例,需要设置
git config –global merge.tool extMerge
git config –global mergetool.extMerge.cmd \
'extMerge “$BASE” “$LOCAL” “$REMOTE” “$MERGED”'
git config –global mergetool.trustExitCode false
以下是extMerge的内容
#!/bin/sh
“c:\Program Files\Perforce\p4merge.exe” $*

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值