##分支开发## 介绍一个成功的 Git 分支模型

A successful Git branching model

前言:如果你使用git管理代码(不希望公开的),但是没有钱买github的服务,你可以再自己的服务器上搭建git服务器(这里只写支持ssh协议的,与github差的太远了,希望不要怪我这个标题党)。同时如果你用git部署项目的话,只需要一条pull命令就可以把测试机上的代码更新到线上(之前我还傻傻的登录线上机子然后pull,其实只需要在本地push一下就好)。

参考资料:《git权威指南》

-.搭建支持ssh协议的git服务器

1:linux服务器上安装好git(可以参考:http://help.github.com/linux-set-up-git/)

2:本地安装git软件(参考:http://help.github.com 里面的set up git)

3:给支持git操作的用户添加认证信息,在用户家目录(~/home)新建.ssh文件夹:将本地(就你开发机子上的~/.ssh/id_rsa.pub)添加到服务器上~/.ssh/authorized_keys Generating SSH Keys

4:在linux服务器上创建项目的共享版本库

git init --bare --share;
git update-server-info

5:然后你就可以使用了,操作跟你操作github一样( git clone 添加了认证信息的用户名@服务器域名(或者ip):/项目路径)

二.git部署你的项目

1:.在你部署的机子上通过git clone把版本库中的代码克隆一份

2:设置部署机上的项目git配置

git config receive.denyCurrentBranch ignore
git config --bool receive.denyNonFastForwards false
 
cd .git/hooks
wget http://utsl.gen.nz/git/post-update
chmod +x post-update

vim post-update

#!/bin/sh
#
# This hook does two things:
#
#  1. update the "info" files that allow the list of references to be
#     queries over dumb transports such as http
#
#  2. if this repository looks like it is a non-bare repository, and
#     the checked-out branch is pushed to, then update the working copy.
#     This makes "push" function somewhat similarly to darcs and bzr.
#
# To enable this hook, make this file executable by "chmod +x post-update".

git update-server-info

is_bare=$(git config --get --bool core.bare)

if [ -z "$is_bare" ]
then
    # for compatibility's sake, guess
    git_dir_full=$(cd $GIT_DIR; pwd)
    case $git_dir_full in */.git) is_bare=false;; *) is_bare=true;; esac
fi

update_wc() {
    ref=$1
    echo "Push to checked out branch $ref" >&2
    if [ ! -f $GIT_DIR/logs/HEAD ]
    then
        echo "E:push to non-bare repository requires a HEAD reflog" >&2
        exit 1
    fi
    if (cd $GIT_WORK_TREE; git diff-files -q --exit-code >/dev/null)
    then
        wc_dirty=0
    else
        echo "W:unstaged changes found in working copy" >&2
        wc_dirty=1
        desc="working copy"
    fi
    if git diff-index --cached HEAD@{1} >/dev/null
    then
        index_dirty=0
    else
        echo "W:uncommitted, staged changes found" >&2
        index_dirty=1
        if [ -n "$desc" ]
        then
            desc="$desc and index"
        else
            desc="index"
        fi
    fi
    if [ "$wc_dirty" -ne 0 -o "$index_dirty" -ne 0 ]
    then
        new=$(git rev-parse HEAD)
        echo "W:stashing dirty $desc - see git-stash(1)" >&2
        ( trap 'echo trapped $$; git symbolic-ref HEAD "'"$ref"'"' 2 3 13 15 ERR EXIT
        git update-ref --no-deref HEAD HEAD@{1}
        cd $GIT_WORK_TREE
        git stash save "dirty $desc before update to $new";
        git symbolic-ref HEAD "$ref"
        )
    fi

    # eye candy - show the WC updates :)
    echo "Updating working copy" >&2
    (cd $GIT_WORK_TREE
    git diff-index -R --name-status HEAD >&2
    git reset --hard HEAD)
}

if [ "$is_bare" = "false" ]
then
    active_branch=`git symbolic-ref HEAD`
    export GIT_DIR=$(cd $GIT_DIR; pwd)
    GIT_WORK_TREE=${GIT_WORK_TREE-..}
    for ref
    do
        if [ "$ref" = "$active_branch" ]
        then
            update_wc $ref
        fi
    done
fi 3:设置你本地版本库
 
[remote "web"]
    url = your-ssh-username@your-host:/var/www/yoursite/ 4:然后你就可以

git psuh origin master(更新到版本库)
git push web(更新到线上)

如果你有这个需求,同时我这篇文章误导你了(没看明白我写啥,可以email我)。

——————————–华丽的分界线(以下部分是之前的自己的备忘录)———————————————

我们知道git支持很多协议,这里想说的是本地和ssh。

本地就是你的代码库分别在两个盘:

在d盘的test目录生成不包含工作区的版本库

d:/test/ git init –bare

然后在e盘就可以用了

e: git clone d:/test

e:/test git push oringin master

在网络中就是通过ssh连接到你的服务器:

在你的服务器建立git用户:

$ sudo adduser git $ su git $ cd $ mkdir .ssh

然后你自己的本地的~/.ssh/id_rsa.pub添加到服务器上~/.ssh/authorized_keys

然后用git用户创建版本库

cd /var/www/gitcode/test

git init –bare –share

git update-server-info

然后你本地就可以使用了 $ git clone git@youserver:/var/www/gitcode/test …. $ git push origin master

然后你就可以尽情使用git了。

最后再次感谢github管理员在大过年的帮我解决问题(昨晚平安夜发的问题)。

还有这个http://progit.org/,你可以学习很多git知识。

git部署站点:

上面说到搭建git没有工作区间的版本库,当我们需要部署该代码时候。(比如web服务器也在git版本库管理机子上)

cd /var/www/test

git clone /var/www/gitcode/test

web服务器就省略了…

也许我们是本地开发,我们本地有个版本,修改完了git push origin master

然后在登陆到web服务器下面git pull,才实现代码一致,我想可能有简单办法,自己对git不熟悉,刚好看到这篇文章。http://www.ooso.net/archives/596

在web部署的库中:

git config receive.denyCurrentBranch ignore

git config –bool receive.denyNonFastForwards false

给web下面的代码加上git用户可写的权限,

cd .git/hooks wget http://utsl.gen.nz/git/post-update chmod +x post-update 在本地库加上

[remote “webdev”]

    url = your-ssh-username@your-host:/var/www/yoursite/

然后你就可以

git psuh origin master

git push webdev

省去了在登陆web服务器pull的步骤。

这么强大的git了这是值得学习。

[注]:大部分的git push失败都是有权限导致的,当push失败(除冲突除外),先去检查权限问题。