代码之家  ›  专栏  ›  技术社区  ›  Rob Golding

利用Git开发Django项目

  •  8
  • Rob Golding  · 技术社区  · 16 年前

    我想知道是否有人在使用Git源代码管理的小团队(在我的例子中是3个)中从事Django项目的工作经验。

    这个项目托管在一个开发服务器上,这就是为什么我会遇到这样的问题。在将更改提交到本地存储库,然后将这些更改推送到服务器之前,开发人员无法查看代码是否正常工作。然而,即便如此,Git似乎也没有更新服务器上存储库所在目录中的文件——可能是因为它只存储更改以节省空间。

    在这个项目中,我们开始互相推敲,所以需要某种版本控制——但我就是想不出解决方案。

    如果有人克服了类似的问题,我很想听听怎么做。

    3 回复  |  直到 16 年前
        1
  •  12
  •   Greg Hewgill    16 年前

    当推送到远程存储库时,最好的结果是远程存储库是一个没有工作目录的“裸”存储库。听起来您在远程存储库上有一个工作目录,在执行推送时,Git不会更新该目录。

    对于您的情况,我建议开发人员拥有自己的测试环境,在将代码推送到其他地方之前,可以在本地对其进行测试。有一个中心位置,每个人都需要在工作之前推动他们的工作。 尝试 它会导致很多痛苦和痛苦。

    对于部署,我建议将其推送到一个中央“裸”存储库,然后拥有一个流程,其中部署服务器 拉扯 从中央存储库到其工作目录的最新代码。

        2
  •  3
  •   araqnid    16 年前

    当您推送到(共享)Git存储库时,它不会更新该存储库的工作文件。基本上,因为工作文件可能是脏的,在这种情况下,您必须合并——为此,您需要在那里具有完全的shell访问权限,一般情况下可能不是这样。

    如果您希望在某个地方签出共享回购的最新“主数据”,可以通过编写更新后挂钩来安排。我将给出下面的一个示例,用于签出“ui”子目录并使其可供Apache使用。

    但是,我认为您的流程可以改进。开发人员通常需要在推进到共享点之前可以测试的个人服务器:否则,共享的repo可能非常不可靠。考虑一下,如果我推动一个改变,但它不起作用,是我的改变打破了它还是其他人的副作用?

    好的,我把它用作更新后的钩子:

    #!/bin/sh
    # Should be run from a Git repository, with a set of refs to update from on the command line.
    # This is the post-update hook convention.
    
    info() {
        echo "post-update: $@"
    }
    
    die() {
        echo "post-update: $@" >&2
        exit 1
    }
    
    output_dir=..
    for refname in "$@"; do
        case $refname in
            refs/heads/master)
                new_tree_id=$(git rev-parse $refname:ui)
                new_dir="$output_dir/tree-$new_tree_id"
                if [ ! -d "$new_dir" ]; then
                    info "Checking out UI"
                    mkdir "$new_dir"
                    git archive --format=tar $new_tree_id | ( cd $new_dir && tar xf - )
                fi
                prev_link_target=$(readlink $output_dir/current)
                if [ -n "$prev_link_target" -a "$prev_link_target" = "tree-$new_tree_id" ]; then
                    info "UI unchanged"
                else
                    rm -f $output_dir/current
                    ln -snf "tree-$new_tree_id" "$output_dir/current"
                    info "UI updated"
                    title=$(git show --quiet --pretty="format:%s" "$refname" | \
                        sed -e 's/[^A-Za-z][^A-Za-z]*/_/g')
                    date=$(git show --quiet --pretty="format:%ci" "$refname" | \
                        sed -e 's/\([0-9]*\)-\([0-9]*\)-\([0-9]*\) \([0-9]*\):\([0-9]*\):\([0-9]*\) +0000/\1\2\3T\4\5\6Z/')
                    ln -s "tree-$new_tree_id" "$output_dir/${date}__${title}"
                fi
                ;;
        esac
    done
    

    如前所述,这只是检查“ui”子目录。这是“:ui”位设置新的_tree_id。只需取出“:ui”(或更改为“^ tree”)即可查看所有内容。

    签出位于包含git repo的目录中,由output_dir控制。脚本应该在git repo内部运行(反过来,应该是裸的):这不是很干净。

    签出被放在“treeXXXX”目录中,并管理一个“current”符号链接指向最新的。这使得从一个原子变为另一个原子,尽管它不太可能花那么长时间才重要。它还意味着还原重用旧文件。这也意味着它会在你不断推修订版的时候,消耗磁盘空间…

        3
  •  0
  •   msmart    16 年前

    有同样的问题,也和姜戈一起工作。

    如前所述,同意在部署前进行本地测试。

    然后可以将本地版本推送到服务器上的新分支。然后,您将与这个分支和主节点进行合并。之后,您将看到更新的文件。

    如果你不小心被推到主分支,那么你可以做一个Git重置——很难。但是,当前工作分支中未提交的所有更改都将丢失。所以要小心。