git检出轻量分支

有时有检出轻量分支的需求,即只检出某一分支的最新版本,不需要其对应的历史信息,但以后的新的版本信息可能是需要的。

这时可以使用depth参数指定版本深度。

比如,只检出当前版本的master分支:

git clone --depth 1 git@git.westgis.ac.cn:westdc/version-multiple-update

 

若要检出非master分支,可以使用b参数指定:

git clone --depth 1 -b card git@git.westgis.ac.cn:westdc/westdc-zf1

 

git检出单独一个分支

有时候,只想从版本库中clone出一个单独的分支来(比如,网站发布的代码),其他相关分支并不需要检出。

这时直接使用 git clone出整个版本库就显得不合适了。搜索了一下,发现这个需求很多,在stackoverflow上有几个相关答案:

这个问题里,回答中最认可的是这个:

git clone <url> --branch <branch> --single-branch [<folder>]

 

但这个回答和我的实际情况稍有不同,我的代码之前是用svn管理的,在服务器上已经使用svn方法发布了,使用这个命令就提示错误了:

git clone  -b qinghaihu --single-branch .

因为当前目录上已经有对应文件了,若是发布到一个新目录下则没有这个问题。

从另一个问题中找到了答案:

即:

cd $BRANCH
git init
git remote add -t $BRANCH -f origin $REMOTE_REPO
git checkout -f $BRANCH

注意最后一个checkout命令加了一个-f参数,这样就可以强制覆盖已有文件。

基于git实现多分支的自动发布

前面使用了gitincron进行了网站的自动发布,但一个git版本系统里的多个分支要是同时发布在一台服务器上,则显得太冗余。因此需要处理多分支的自动发布方案。

在此处找到了解决方案:

http://www.ekynoxe.com/git-post-receive-for-multiple-remote-branches-and-work-trees/

结合incron技术,最终的解决方法就是修改post-receive钩子:

#!/bin/bash
  while read oldrev newrev ref
  do
    branch=`echo $ref | cut -d/ -f3`

    if [ "master" == "$branch" ]; then
      date +"%Y-%m-%d %H:%M:%S" >> /home/wlx/westdc.git/hooks/westdc.update.lck
    fi

    if [ "heihedata" == "$branch" ]; then
      date +"%Y-%m-%d %H:%M:%S" >> /home/wlx/westdc.git/hooks/heihedata.update.lck
    fi

    if [ "card" == "$branch" ]; then
      date +"%Y-%m-%d %H:%M:%S" >> /home/wlx/westdc.git/hooks/card.update.lck
    fi
  done

 

使用git进行分支间的合并

使用svn的时候,在分支之间的合并,使用svn merge进行操作,同时也可以合并部分目录和文件。

现在开始使用git,一开始只是知道git merge,将不同分支完整合并到另一分支。但我的实际需求是,将某一次或某几个commit,合并到几个不同的分支上。

搜索后发现可以使用git cherry-pick命令,可以非常好的解决这个需求。

 

参考:

http://stackoverflow.com/questions/881092/how-to-merge-a-specific-commit-in-git

结合incron实现git自动发布

上个帖子讨论了git的自动web发布流程,但实际测试过程中发现存在用户权限问题,导致更新出错。今天在服务器上采用incron结合git进行自动发布,可以完美解决(或避开)权限问题。

1. git hooks post-receive部分

此处仅创建一个临时文件,比如heihedata.update.lck

#!/bin/bash

touch /home/wlx/heihedata.git/hooks/heihedata.update.lck

 

2. incron部分

使用incron监测post-receive生成的文件,然后使用root账号进行更新操作。

设置incron

/home/wlx/heihedata.git/hooks/heihedata.update.lck IN_CLOSE_WRITE /root/heihedata.sh

 

执行的脚本

#!/bin/bash

cd /home/wlx/heihedata.git

GIT_WORK_TREE=/var/www/heihedata.org/ git checkout heihedata -f

rm /home/wlx/heihedata.git/hooks/heihedata.update.lck

 

基于git系统发布网站代码

网站的开发版本管理系统从svn切换到了git,之前更新网站的代码方法是ssh到服务器上,然后sudo svn update即可,但采用git后,若采用git clone的方法更新代码,会导致每个网站都是一个完整的代码系统,不是太合适。

从网上搜索了几个基于git发布网站代码的文章,多数都是采用的这个blog里提供的方法:

http://sebduggan.com/blog/deploy-your-website-changes-using-git/

但是这个blog的方法测试下来也有问题,即通常网站代码的发布的用户会是www-data,而此blog的方法会产生写权限问题。

继续搜索到另一个blog,解决了这个问题:

https://halfthetruth.de/2011/09/13/using-git-to-deploy-a-website/

即将git放到sudo里,让其可以自动指定用户进行更新,最终按照这个blog的方法进行了部署。

主要方法记录如下:

1. Web服务器端

建立一个空git目录,

mkdir website.git && cd website.git
git init --bare

并创建hook脚本:

$> cat website.git/hooks/post-receive
#!/bin/bash
GIT_WORK_TREE=/var/www/domain.com/ git checkout master -f 
$> chmod +x website.git/hooks/post-receive

同时也要修改sudoers文件:

username ALL=(ALL) NOPASSWD: /usr/bin/git

2. 本地机器

在git版本库中指定一个remote,并push某一个branch到web服务器。

git remote add web ssh://webserver/path/to/website.git
git push web master

 

 

从svn转换到git

数据中心之前的代码一直使用svn进行管理,现在team已经转换到git了。需要将之前的版本代码也全部转换到git了。
转换步骤在这本git书中有详细的说明:
但在试验过程中,发现有几处地方不能完整执行,需要进行修改。修改后的代码如下:
#clone metadata
git svn clone https://svn.westgis.ac.cn/svn/westdc/metadata --authors-file=users.txt --no-metadata --stdlayout westdc-zf1

#convert tags to local
git for-each-ref refs/remotes/origin/tags | cut -d / -f 5-| grep -v @ | while read tagname; do git checkout -b "$tagname" origin/tags/$tagname; git checkout master; git tag $tagname $tagname;git branch -D "$tagname";git branch -r  -d "origin/tags/$tagname";done

#convert branches to local
git for-each-ref refs/remotes | cut -d / -f 4- | grep -v @ | while read branchname; do git checkout -b "$branchname" origin/$branchname;git branch -r -d origin/$branchname; done

git remote add origin git@git.westgis.ac.cn:westdc/westdc-zf1.git
git push origin --all
git push origin --tags

 

在ubuntu 14.04上搭建gitlab环境

团队正在尝试从svn转换到git,因此需要构建gitlab环境,用于实现git的整套管理。

按照官网的安装指南,在ubuntu 14.04上安装应该很简单。

wget https://downloads-packages.s3.amazonaws.com/ubuntu-14.04/gitlab_7.2.1-omnibus-1_amd64.deb
sudo apt-get install openssh-server
sudo apt-get install postfix
sudo dpkg -i gitlab_7.2.1-omnibus-1_amd64.deb

然后修改默认的域名:

sudo -e /etc/gitlab/gitlab.rb

安装并启动gitlab服务:

sudo gitlab-ctl reconfigure

但我在服务器上测试后发现不能正常访问,检查log后发现主要问题是:gitlab安装包自带了nginx,要使用80端口对外服务,同时unicorn要使用8080端口对内服务,但在我们的服务器上这两个端口都已经被占用了。

因此,解决办法是:修改nginx的默认端口为8000,指定unicorn的默认端口为8001,修改gitlab-shell的默认端口为8000。

sudo su
nano /var/opt/gitlab/nginx/etc/gitlab-http.conf

将其中的listen *:80改为listen *:8000,

nano /var/opt/gitlab/gitlab-rails/etc/unicorn.rb

将listen行的内容改为:

listen “127.0.0.1:8001”, :tcp_nopush => true

然后修改:

nano /var/opt/gitlab/gitlab-shell/config.yml

修改这行:

gitlab_url: “http://127.0.0.1:8000”

这样应该就能使用了。

git使用中遇到needs update问题

在git使用过程中,遇到了needs update问题:

$ git svn dcommit
htdocs/index.php: needs update
update-index --refresh: command returned error: 1

产生此问题的原因是htdocs/index.php是本地修改(适配本机的测试环境),不需要更新到版本库。

此问题的解决办法是:

git update-index --assume-unchanged htdocs/index.php

这样即可假定为此文件未变更,然后再提交其他对应的变更即可。