使用Git推送部署项目

发布于 2024-07-08 20:35:57 字数 182 浏览 13 评论 0原文

是否可以使用 git push 部署网站? 我有预感这与使用 git hooks 有关 在服务器端执行 git reset --hard ,但是我将如何实现这一点呢?

Is it possible to deploy a website using git push? I have a hunch it has something to do with using git hooks to perform a git reset --hard on the server side, but how would I go about accomplishing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

眼泪淡了忧伤 2024-07-15 20:35:57

我在这个脚本上找到了这个网站 看起来效果很好。

  1. 将 .git 目录复制到 Web 服务器
  2. 在本地副本上,修改 .git/config 文件并将 Web 服务器添加为远程服务器:

    [远程“生产”] 
          url = 用户名@webserver:/path/to/htdocs/.git 
      
  3. 在服务器上,将 .git/hooks/post-update 替换为 此文件(在下面的答案中)

  4. 添加对文件的执行访问权限(同样在服务器上):

    chmod +x .git/hooks/post-update 
      
  5. 现在,只需在本地推送到您的 Web 服务器,它就会自动更新工作副本:

    git推送生产 
      

I found this script on this site and it seems to work quite well.

  1. Copy over your .git directory to your web server
  2. On your local copy, modify your .git/config file and add your web server as a remote:

    [remote "production"]
        url = username@webserver:/path/to/htdocs/.git
    
  3. On the server, replace .git/hooks/post-update with this file (in the answer below)

  4. Add execute access to the file (again, on the server):

    chmod +x .git/hooks/post-update
    
  5. Now, just locally push to your web server and it should automatically update the working copy:

    git push production
    
套路撩心 2024-07-15 20:35:57

使用下面的更新后文件:

  1. 将 .git 目录复制到 Web 服务器
  2. 在本地副本上,修改 .git/config 文件并将 Web 服务器添加为远程服务器:< /p>

    [远程“生产”] 
          url = 用户名@webserver:/path/to/htdocs/.git 
      
  3. 在服务器上,将 .git/hooks/post-update 替换为以下文件

  4. 添加对该文件的执行访问权限(同样,在服务器上):

    chmod +x .git/hooks/post-update 
      
  5. 现在,只需在本地推送到您的 Web 服务器,它就会自动更新工作副本:

    git推送生产 
      
#!/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

Using the post-update file below:

  1. Copy over your .git directory to your web server
  2. On your local copy, modify your .git/config file and add your web server as a remote:

    [remote "production"]
        url = username@webserver:/path/to/htdocs/.git
    
  3. On the server, replace .git/hooks/post-update with file below

  4. Add execute access to the file (again, on the server):

    chmod +x .git/hooks/post-update
    
  5. Now, just locally push to your web server and it should automatically update the working copy:

    git push production
    
#!/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
葬シ愛 2024-07-15 20:35:57

经过多次错误的开始和死胡同后,我终于能够仅使用“git push remote”来部署网站代码,这要归功于 这篇文章

作者的更新后脚本只有一行长,他的解决方案不需要像其他人那样通过 .htaccess 配置来隐藏 Git 存储库。

如果您在 Amazon EC2 实例上部署此功能,则会遇到一些障碍;

1) 如果使用 sudo 创建裸目标存储库,则必须将存储库的所有者更改为 ec2-user,否则推送将失败。 (尝试“chown ec2-user:ec2-user repo。”)

2) 如果您没有预先配置 amazon-private-key 的位置,推送将会失败em>.pem,在 /etc/ssh/ssh_config 中作为 IdentityFile 参数,或者在 ~/.ssh/config 中使用描述的“[Host] - HostName - IdentityFile - User”布局 此处...

...但是,如果在 ~/.ssh/config 中配置了主机与 HostName 不同,Git 推送将会失败。 (这可能是一个 Git 错误)

After many false starts and dead ends, I'm finally able to deploy website code with just "git push remote" thanks to this article.

The author's post-update script is only one line long and his solution doesn't require .htaccess configuration to hide the Git repo as some others do.

A couple of stumbling blocks if you're deploying this on an Amazon EC2 instance;

1) If you use sudo to create the bare destination repository, you have to change the owner of the repo to ec2-user or the push will fail. (Try "chown ec2-user:ec2-user repo.")

2) The push will fail if you don't pre-configure the location of your amazon-private-key.pem, either in /etc/ssh/ssh_config as an IdentityFile parameter or in ~/.ssh/config using the "[Host] - HostName - IdentityFile - User" layout described here...

...HOWEVER if Host is configured in ~/.ssh/config and different than HostName the Git push will fail. (That's probably a Git bug)

不醒的梦 2024-07-15 20:35:57

不要在服务器上安装 git 或将 .git 文件夹复制到那里。 要从 git 克隆更新服务器,您可以使用以下命令:

git ls-files -z | rsync --files-from - --copy-links -av0 . [email protected]:/var/www/project

您可能必须删除从项目中删除的文件。

这将复制所有签入的文件。 rsync 使用安装在服务器上的 ssh。

服务器上安装的软件越少,服务器就越安全,管理其配置和记录它也就越容易。 也无需在服务器上保留完整的 git 克隆。 这只会使正确保护一切变得更加复杂。

dont install git on a server or copy the .git folder there. to update a server from a git clone you can use following command:

git ls-files -z | rsync --files-from - --copy-links -av0 . [email protected]:/var/www/project

you might have to delete files which got removed from the project.

this copies all the checked in files. rsync uses ssh which is installed on a server anyways.

the less software you have installed on a server the more secure he is and the easier it is to manage it's configuration and document it. there is also no need to keep a complete git clone on the server. it only makes it more complex to secure everything properly.

情归归情 2024-07-15 20:35:57

git config --local receive.denyCurrentBranch updateInstead

在 Git 2.3 中添加,这可能是一个很好的可能性:https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155

您将其设置在服务器存储库上,如果工作树是干净的,它还会更新工作树。

2.4 中通过 push-to-checkout 挂钩和未出生分支的处理

示例用法:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

输出:

a
b

这确实具有 上提到的以下缺点GitHub 公告

  • 您的服务器将包含一个 .git 目录,其中包含项目的整个历史记录。 您可能想额外确保它无法提供给用户!
  • 在部署过程中,用户可能会暂时遇到站点处于不一致状态的情况,一些文件是旧版本,另一些文件是新版本,甚至是半写入的文件。 如果这对您的项目来说是一个问题,那么推送部署可能不适合您。
  • 如果您的项目需要“构建”步骤,那么您必须明确地进行设置,也许可以通过 githooks 进行设置。

但所有这些点都超出了 Git 的范围,必须由外部代码处理。 所以从这个意义上说,这与 Git hooks 一起是最终的解决方案。

git config --local receive.denyCurrentBranch updateInstead

Added in Git 2.3, this could be a good possibility: https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155

You set it on the server repository, and it also updates the working tree if it is clean.

There have been further improvements in 2.4 with the push-to-checkout hook and handling of unborn branches.

Sample usage:

git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead

cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master

cd ../server
ls

Output:

a
b

This does have the following shortcomings mentioned on the GitHub announcement:

  • Your server will contain a .git directory containing the entire history of your project. You probably want to make extra sure that it cannot be served to users!
  • During deploys, it will be possible for users momentarily to encounter the site in an inconsistent state, with some files at the old version and others at the new version, or even half-written files. If this is a problem for your project, push-to-deploy is probably not for you.
  • If your project needs a "build" step, then you will have to set that up explicitly, perhaps via githooks.

But all of those points are out of the scope of Git and must be taken care of by external code. So in that sense, this, together with Git hooks, are the ultimate solution.

抹茶夏天i‖ 2024-07-15 20:35:57

本质上,您需要做的就是以下内容:

server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"

我将这些行作为名为 deploy 的可执行文件存在于我的应用程序中。

因此,当我想要进行部署时,我输入 ./deploy myserver mybranch

In essence all you need to do are the following:

server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"

I have those lines in my application as an executable called deploy.

so when I want to do a deploy I type ./deploy myserver mybranch.

娇女薄笑 2024-07-15 20:35:57

我的做法是在我的部署服务器上有一个裸露的 Git 存储库,我可以在其中推送更改。 然后我登录到部署服务器,更改到实际的 Web 服务器文档目录,并执行 git pull。 我没有使用任何钩子来尝试自动执行此操作,这似乎比其价值更麻烦。

The way I do it is I have a bare Git repository on my deployment server where I push changes. Then I log in to the deployment server, change to the actual web server docs directory, and do a git pull. I don't use any hooks to try to do this automatically, that seems like more trouble than it's worth.

鸩远一方 2024-07-15 20:35:57

更新:我现在使用 Lloyd Moore 解决方案和密钥代理 ssh -A ...。 推送到主存储库,然后从所有机器上并行地从主存储库中拉取速度要快一些,并且在这些机器上需要的设置更少。


在这里没有看到这个解决方案。 如果服务器上安装了 git,只需通过 ssh 推送即可。

您需要在本地 .git/config 中添加以下条目

[remote "amazon"]
    url = amazon:/path/to/project.git
    fetch = +refs/heads/*:refs/remotes/amazon/*

但是,嘿,amazon: 是什么? 在本地 ~/.ssh/config 中,您需要添加以下条目:

Host amazon
    Hostname <YOUR_IP>
    User <USER>
    IdentityFile ~/.ssh/amazon-private-key

现在您可以调用

git push amazon master
ssh <USER>@<YOUR_IP> 'cd /path/to/project && git pull'

(顺便说一句:/path/to/project.git 与实际工作目录 /path/to/project 不同)

Update: I'm now using Lloyd Moore solution with the key agent ssh -A .... Pushing to a main repo and then pulling from it in parallel from all your machines is a bit faster and requires less setup on those machines.


Not seeing this solution here. just push via ssh if git is installed on the server.

You'll need the following entry in your local .git/config

[remote "amazon"]
    url = amazon:/path/to/project.git
    fetch = +refs/heads/*:refs/remotes/amazon/*

But hey, whats that with amazon:? In your local ~/.ssh/config you'll need to add the following entry:

Host amazon
    Hostname <YOUR_IP>
    User <USER>
    IdentityFile ~/.ssh/amazon-private-key

now you can call

git push amazon master
ssh <USER>@<YOUR_IP> 'cd /path/to/project && git pull'

(BTW: /path/to/project.git is different to the actual working directory /path/to/project)

没有伤那来痛 2024-07-15 20:35:57

我们使用 capistrano 来管理部署。
我们构建 capistrano 来部署在临时服务器上,然后与我们所有的服务器运行 rsync。

cap deploy
cap deploy:start_rsync (when the staging is ok)

使用 Capistrano,我们可以在出现错误时轻松回滚

cap deploy:rollback
cap deploy:start_rsync

We use capistrano for managing deploy.
We build capistrano to deploy on a staging server, and then running a rsync with all of ours server.

cap deploy
cap deploy:start_rsync (when the staging is ok)

With capistrano, we can made easy rollback in case of bug

cap deploy:rollback
cap deploy:start_rsync
丶视觉 2024-07-15 20:35:57

对于部署场景

在我们的场景中,我们将代码存储在 github/bitbucket 上,并希望部署到实时服务器。
在这种情况下,以下组合对我们有效(这是此处高度赞成的答案的重新组合):

  1. 将您的 .git 目录复制到您的网络服务器上
  2. 在您的本地副本上git Remote add live ssh://user@host:port/folder
  3. 在远程:git config receive.denyCurrentBranchignore
  4. 在远程:nano .git /hooks/post-receive 并添加以下内容:

    <代码>#!/bin/sh
    GIT_WORK_TREE=/var/www/vhosts/example.org git checkout -f

  5. 在远程:chmod +x .git/hooks/post-receive

  6. 现在您可以使用 git push live 推送到那里

注释

  • 此解决方案适用于较旧的 git 版本(使用 1.7 和 1.9 进行测试)
  • 您需要确保首先推送到 github/bitbucket,这样您就可以在实时中拥有一致的存储库
  • 如果您的 .git 文件夹位于文档根目录中,请确保通过以下方式将其从外部隐藏添加到 .htaccess):

    RedirectMatch 404 /\..*$

For Deployment Scenario

In our scenario we're storing the code on github/bitbucket and want to deploy to live servers.
In this case the following combination works for us (that is a remix of the highly upvoted answers here):

  1. Copy over your .git directory to your web server
  2. On your local copy git remote add live ssh://user@host:port/folder
  3. On remote: git config receive.denyCurrentBranch ignore
  4. On remote: nano .git/hooks/post-receive and add this content:

    #!/bin/sh
    GIT_WORK_TREE=/var/www/vhosts/example.org git checkout -f

  5. On remote: chmod +x .git/hooks/post-receive

  6. Now you can push there with git push live

Notes

  • This solution works with older git versions (tested with 1.7 and 1.9)
  • You need to make sure pushing to github/bitbucket first, so you'll have a consistent repo on live
  • If your .git folder is within document root make sure you hide it from the outside by adding to .htaccess (source):

    RedirectMatch 404 /\..*$

裂开嘴轻声笑有多痛 2024-07-15 20:35:57

Giddyup 是与语言无关的just-add-water git hooks,通过以下方式自动部署git 推送。 它还允许您使用自定义启动/停止挂钩来重新启动 Web 服务器、预热缓存等。

https://github。 com/mpalmer/giddyup

查看示例

Giddyup are language-agnostic just-add-water git hooks to automate deployment via git push. It also allows you to have custom start/stop hooks for restarting web server, warming up cache etc.

https://github.com/mpalmer/giddyup

Check out examples.

自找没趣 2024-07-15 20:35:57

听起来您的服务器上应该有两个副本。 一个裸副本,您可以从中推送/拉取,完成后您将推送更改,然后您可以将其克隆到您的 Web 目录中并设置一个 cronjob 每天从您的 Web 目录更新 git pull 或所以。

Sounds like you should have two copies on your server. A bare copy, that you can push/pull from, which your would push your changes when you're done, and then you would clone this into you web directory and set up a cronjob to update git pull from your web directory every day or so.

初见终念 2024-07-15 20:35:57

您可以想象设置一个 git 钩子,当提交一个“稳定”分支时,它将提取更改并将其应用到 PHP 站点。 最大的缺点是,如果出现问题,您将无法进行太多控制,并且会增加测试时间 - 但您可以了解当您将主干分支合并到稳定分支时会涉及多少工作,以了解您可能遇到多少冲突。 密切关注特定于站点的任何文件(例如配置文件)非常重要,除非您只想运行一个站点。

或者您是否考虑过将更改推送到网站?

有关 git hooks 的信息,请参阅 githooks 文档。

You could conceivably set up a git hook that when say a commit is made to say the "stable" branch it will pull the changes and apply them to the PHP site. The big downside is you won't have much control if something goes wrong and it will add time to your testing - but you can get an idea of how much work will be involved when you merge say your trunk branch into the stable branch to know how many conflicts you may run into. It will be important to keep an eye on any files that are site specific (eg. configuration files) unless you solely intend to only run the one site.

Alternatively have you looked into pushing the change to the site instead?

For information on git hooks see the githooks documentation.

踏月而来 2024-07-15 20:35:57

我对基督徒解决方案的看法。

git archive --prefix=deploy/  master | tar -x -C $TMPDIR | rsync $TMPDIR/deploy/ --copy-links -av [email protected]:/home/user/my_app && rm -rf $TMPDIR/deploy
  • 将 master 分支存档到 tar
  • 将 tar 存档提取到系统临时文件夹中的部署目录中。
  • rsync 更改为服务器
  • 从临时文件夹中删除部署目录。

My take on Christians solution.

git archive --prefix=deploy/  master | tar -x -C $TMPDIR | rsync $TMPDIR/deploy/ --copy-links -av [email protected]:/home/user/my_app && rm -rf $TMPDIR/deploy
  • Archives the master branch into tar
  • Extracts tar archive into deploy dir in system temp folder.
  • rsync changes into server
  • delete deploy dir from temp folder.
橘虞初梦 2024-07-15 20:35:57

我正在使用 toroid.org 提供的以下解决方案,它具有更简单的挂钩脚本。

在服务器上:

$ mkdir website.git && cd website.git
$ git init --bare
Initialized empty Git repository in /home/ams/website.git/

并在服务器上安装挂钩:

$ mkdir /var/www/www.example.org
$ cat > hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/var/www/www.example.org git checkout -f
GIT_WORK_TREE=/var/www/www git clean -f -d # clean directory from removed files

$ chmod +x hooks/post-receive

在您的客户端上:

$ mkdir website && cd website
$ git init
Initialized empty Git repository in /home/ams/website/.git/
$ echo 'Hello, world!' > index.html
$ git add index.html
$ git commit -q -m "The humble beginnings of my web site."

$ git remote add web ssh://server.example.org/home/ams/website.git
$ git push web +master:refs/heads/master

然后要发布,只需键入

$ git push web

网站上有完整的说明:http://toroid.org/ams/git-website-howto

I am using the following solution by toroid.org, which has a simpler hook script.

on the server:

$ mkdir website.git && cd website.git
$ git init --bare
Initialized empty Git repository in /home/ams/website.git/

and install the hook on the server:

$ mkdir /var/www/www.example.org
$ cat > hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/var/www/www.example.org git checkout -f
GIT_WORK_TREE=/var/www/www git clean -f -d # clean directory from removed files

$ chmod +x hooks/post-receive

on your client:

$ mkdir website && cd website
$ git init
Initialized empty Git repository in /home/ams/website/.git/
$ echo 'Hello, world!' > index.html
$ git add index.html
$ git commit -q -m "The humble beginnings of my web site."

$ git remote add web ssh://server.example.org/home/ams/website.git
$ git push web +master:refs/heads/master

then to publish, just type

$ git push web

There is a full description on the website: http://toroid.org/ams/git-website-howto

漫雪独思 2024-07-15 20:35:57

作为补充答案,我想提供一个替代方案。 我正在使用 git-ftp 并且工作正常。

https://github.com/git-ftp/git-ftp

易于使用,只需输入:

git ftp push

git 就会自动上传项目文件。

问候

As complementary answer I would like to offer an alternative. I'm using git-ftp and it works fine.

https://github.com/git-ftp/git-ftp

Easy to use, only type:

git ftp push

and git will automatically upload project files.

Regards

情释 2024-07-15 20:35:57

在有多个开发人员访问同一存储库的环境中,以下准则可能会有所帮助。

确保您有一个所有开发人员都属于的 unix 组,并将 .git 存储库的所有权授予该组。

  1. 在服务器存储库的.git/config 中设置sharedrepository = true。 (这告诉 git 允许提交和部署所需的多个用户。

  2. 将每个用户在 bashrc 文件中的 umask 设置为相同 - 002 是一个好的开始

Given an environment where you have multiple developers accessing the same repository the following guidelines may help.

Ensure that you have a unix group that all devs belong to and give ownership of the .git repository to that group.

  1. In the .git/config of the server repository set sharedrepository = true. (This tells git to allow multiple users which is needed for commits and deployment.

  2. set the umask of each user in their bashrc files to be the same - 002 is a good start

呆萌少年 2024-07-15 20:35:57

我最终创建了自己的基本部署工具,该工具会自动从存储库中提取新更新 - https://github.com /jesalg/SlimJim - 基本上它监听 g​​ithub post-receive-hook 并使用代理来触发更新脚本。

I ended up creating my own rudimentary deployment tool which would automatically pull down new updates from the repo - https://github.com/jesalg/SlimJim - Basically it listens to the github post-receive-hook and uses a proxy to trigger an update script.

三岁铭 2024-07-15 20:35:57

我对接收后挂钩使用两种解决方案:

部署解决方案 1

#!/bin/bash 
#  /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 1 

    export GIT_DIR=/git/repo-bare.git
    export GIT_BRANCH1=master
    export GIT_TARGET1=/var/www/html
    export GIT_BRANCH2=dev
    export GIT_TARGET2=/var/www/dev
    echo "GIT DIR:  $GIT_DIR/"
    echo "GIT TARGET1:  $GIT_TARGET1/"
    echo "GIT BRANCH1:  $GIT_BRANCH1/"
    echo "GIT TARGET2:  $GIT_TARGET2/"
    echo "GIT BRANCH2:  $GIT_BRANCH2/"
    echo ""

    cd $GIT_DIR/

while read oldrev newrev refname
do
    branch=$(git rev-parse --abbrev-ref $refname)
    BRANCH_REGEX='^${GIT_BRANCH1}.*

部署解决方案 2

#!/bin/bash 
#  /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 2

    export GIT_DIR=/git/repo-bare.git
    export GIT_BRANCH1=master
    export GIT_TARGET1=/var/www/html
    export GIT_BRANCH2=dev
    export GIT_TARGET2=/var/www/dev
    export GIT_TEMP_DIR1=/tmp/deploy1
    export GIT_TEMP_DIR2=/tmp/deploy2
    echo "GIT DIR:  $GIT_DIR/"
    echo "GIT TARGET1:  $GIT_TARGET1/"
    echo "GIT BRANCH1:  $GIT_BRANCH1/"
    echo "GIT TARGET2:  $GIT_TARGET2/"
    echo "GIT BRANCH2:  $GIT_BRANCH2/"
    echo "GIT TEMP DIR1:  $GIT_TEMP_DIR1/"
    echo "GIT TEMP DIR2:  $GIT_TEMP_DIR2/"
    echo ""

    cd $GIT_DIR/

while read oldrev newrev refname
do
    branch=$(git rev-parse --abbrev-ref $refname)
    BRANCH_REGEX='^${GIT_BRANCH1}.*

这两种解决方案都基于此线程中提供的早期解决方案。

注意,
BRANCH_REGEX='^${GIT_BRANCH1}.$'
过滤与“master
”或“dev*”字符串匹配的分支名称,如果推送的分支匹配,则部署工作树。
这使得将开发版本和主版本部署到不同的地方成为可能。

部署解决方案 1 仅删除属于存储库一部分并通过提交删除的文件。 它比部署解决方案 2 更快。

部署解决方案 2 的优点是,它会从生产目录中删除在服务器端添加的所有新文件,无论它是否添加到存储库中。 它将始终是回购协议的干净副本。 它比部署解决方案 1 慢。

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET1/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; git checkout -f $branch fi BRANCH_REGEX='^${GIT_BRANCH2}.*

部署解决方案 2


这两种解决方案都基于此线程中提供的早期解决方案。

注意,
BRANCH_REGEX='^${GIT_BRANCH1}.$'
过滤与“master
”或“dev*”字符串匹配的分支名称,如果推送的分支匹配,则部署工作树。
这使得将开发版本和主版本部署到不同的地方成为可能。

部署解决方案 1 仅删除属于存储库一部分并通过提交删除的文件。 它比部署解决方案 2 更快。

部署解决方案 2 的优点是,它会从生产目录中删除在服务器端添加的所有新文件,无论它是否添加到存储库中。 它将始终是回购协议的干净副本。 它比部署解决方案 1 慢。

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET2/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; git checkout -f $branch fi done

部署解决方案 2


这两种解决方案都基于此线程中提供的早期解决方案。

注意,
BRANCH_REGEX='^${GIT_BRANCH1}.$'
过滤与“master
”或“dev*”字符串匹配的分支名称,如果推送的分支匹配,则部署工作树。
这使得将开发版本和主版本部署到不同的地方成为可能。

部署解决方案 1 仅删除属于存储库一部分并通过提交删除的文件。 它比部署解决方案 2 更快。

部署解决方案 2 的优点是,它会从生产目录中删除在服务器端添加的所有新文件,无论它是否添加到存储库中。 它将始终是回购协议的干净副本。 它比部署解决方案 1 慢。

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET1/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; # DEPLOY SOLUTION 2: cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR1; export GIT_WORK_TREE=$GIT_TEMP_DIR1/. git checkout -f $branch export GIT_WORK_TREE=$GIT_TARGET1/. rsync $GIT_TEMP_DIR1/. -v -q --delete --delete-after -av $GIT_TARGET1/. rm -rf $GIT_TEMP_DIR1 fi BRANCH_REGEX='^${GIT_BRANCH2}.*

这两种解决方案都基于此线程中提供的早期解决方案。

注意,
BRANCH_REGEX='^${GIT_BRANCH1}.$'
过滤与“master
”或“dev*”字符串匹配的分支名称,如果推送的分支匹配,则部署工作树。
这使得将开发版本和主版本部署到不同的地方成为可能。

部署解决方案 1 仅删除属于存储库一部分并通过提交删除的文件。 它比部署解决方案 2 更快。

部署解决方案 2 的优点是,它会从生产目录中删除在服务器端添加的所有新文件,无论它是否添加到存储库中。 它将始终是回购协议的干净副本。 它比部署解决方案 1 慢。

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET1/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; git checkout -f $branch fi BRANCH_REGEX='^${GIT_BRANCH2}.*

部署解决方案 2


这两种解决方案都基于此线程中提供的早期解决方案。

注意,
BRANCH_REGEX='^${GIT_BRANCH1}.$'
过滤与“master
”或“dev*”字符串匹配的分支名称,如果推送的分支匹配,则部署工作树。
这使得将开发版本和主版本部署到不同的地方成为可能。

部署解决方案 1 仅删除属于存储库一部分并通过提交删除的文件。 它比部署解决方案 2 更快。

部署解决方案 2 的优点是,它会从生产目录中删除在服务器端添加的所有新文件,无论它是否添加到存储库中。 它将始终是回购协议的干净副本。 它比部署解决方案 1 慢。

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET2/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; git checkout -f $branch fi done

部署解决方案 2

这两种解决方案都基于此线程中提供的早期解决方案。

注意,
BRANCH_REGEX='^${GIT_BRANCH1}.$'
过滤与“master
”或“dev*”字符串匹配的分支名称,如果推送的分支匹配,则部署工作树。
这使得将开发版本和主版本部署到不同的地方成为可能。

部署解决方案 1 仅删除属于存储库一部分并通过提交删除的文件。 它比部署解决方案 2 更快。

部署解决方案 2 的优点是,它会从生产目录中删除在服务器端添加的所有新文件,无论它是否添加到存储库中。 它将始终是回购协议的干净副本。 它比部署解决方案 1 慢。

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET2/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; # DEPLOY SOLUTION 2: cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR2; export GIT_WORK_TREE=$GIT_TEMP_DIR2/. git checkout -f $branch export GIT_WORK_TREE=$GIT_TARGET2/. rsync $GIT_TEMP_DIR2/. -v -q --delete --delete-after -av $GIT_TARGET2/. rm -rf $GIT_TEMP_DIR2 fi done

这两种解决方案都基于此线程中提供的早期解决方案。

注意,
BRANCH_REGEX='^${GIT_BRANCH1}.$'
过滤与“master
”或“dev*”字符串匹配的分支名称,如果推送的分支匹配,则部署工作树。
这使得将开发版本和主版本部署到不同的地方成为可能。

部署解决方案 1 仅删除属于存储库一部分并通过提交删除的文件。 它比部署解决方案 2 更快。

部署解决方案 2 的优点是,它会从生产目录中删除在服务器端添加的所有新文件,无论它是否添加到存储库中。 它将始终是回购协议的干净副本。 它比部署解决方案 1 慢。

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET1/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; git checkout -f $branch fi BRANCH_REGEX='^${GIT_BRANCH2}.*

部署解决方案 2

这两种解决方案都基于此线程中提供的早期解决方案。

注意,
BRANCH_REGEX='^${GIT_BRANCH1}.$'
过滤与“master
”或“dev*”字符串匹配的分支名称,如果推送的分支匹配,则部署工作树。
这使得将开发版本和主版本部署到不同的地方成为可能。

部署解决方案 1 仅删除属于存储库一部分并通过提交删除的文件。 它比部署解决方案 2 更快。

部署解决方案 2 的优点是,它会从生产目录中删除在服务器端添加的所有新文件,无论它是否添加到存储库中。 它将始终是回购协议的干净副本。 它比部署解决方案 1 慢。

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET2/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; git checkout -f $branch fi done

部署解决方案 2

这两种解决方案都基于此线程中提供的早期解决方案。

注意,
BRANCH_REGEX='^${GIT_BRANCH1}.$'
过滤与“master
”或“dev*”字符串匹配的分支名称,如果推送的分支匹配,则部署工作树。
这使得将开发版本和主版本部署到不同的地方成为可能。

部署解决方案 1 仅删除属于存储库一部分并通过提交删除的文件。 它比部署解决方案 2 更快。

部署解决方案 2 的优点是,它会从生产目录中删除在服务器端添加的所有新文件,无论它是否添加到存储库中。 它将始终是回购协议的干净副本。 它比部署解决方案 1 慢。

I use two solutions for post-receive hook:

DEPLOY SOLUTION 1

#!/bin/bash 
#  /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 1 

    export GIT_DIR=/git/repo-bare.git
    export GIT_BRANCH1=master
    export GIT_TARGET1=/var/www/html
    export GIT_BRANCH2=dev
    export GIT_TARGET2=/var/www/dev
    echo "GIT DIR:  $GIT_DIR/"
    echo "GIT TARGET1:  $GIT_TARGET1/"
    echo "GIT BRANCH1:  $GIT_BRANCH1/"
    echo "GIT TARGET2:  $GIT_TARGET2/"
    echo "GIT BRANCH2:  $GIT_BRANCH2/"
    echo ""

    cd $GIT_DIR/

while read oldrev newrev refname
do
    branch=$(git rev-parse --abbrev-ref $refname)
    BRANCH_REGEX='^${GIT_BRANCH1}.*

DEPLOY SOLUTION 2

#!/bin/bash 
#  /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 2

    export GIT_DIR=/git/repo-bare.git
    export GIT_BRANCH1=master
    export GIT_TARGET1=/var/www/html
    export GIT_BRANCH2=dev
    export GIT_TARGET2=/var/www/dev
    export GIT_TEMP_DIR1=/tmp/deploy1
    export GIT_TEMP_DIR2=/tmp/deploy2
    echo "GIT DIR:  $GIT_DIR/"
    echo "GIT TARGET1:  $GIT_TARGET1/"
    echo "GIT BRANCH1:  $GIT_BRANCH1/"
    echo "GIT TARGET2:  $GIT_TARGET2/"
    echo "GIT BRANCH2:  $GIT_BRANCH2/"
    echo "GIT TEMP DIR1:  $GIT_TEMP_DIR1/"
    echo "GIT TEMP DIR2:  $GIT_TEMP_DIR2/"
    echo ""

    cd $GIT_DIR/

while read oldrev newrev refname
do
    branch=$(git rev-parse --abbrev-ref $refname)
    BRANCH_REGEX='^${GIT_BRANCH1}.*

Both solutions are based on earlier solutions available in this thread.

Note, the
BRANCH_REGEX='^${GIT_BRANCH1}.$'
filters for the branch names matching "master
" or "dev*" string, and deploys the work tree, if the pushed branch matches.
This makes possible to deploy a dev version and master version to different places.

DEPLOY SOLUTION 1 removes only files, which are part of the repo, and was removed by a commit. It is faster than Deployment Solution 2.

DEPLOY SOLUTION 2 has the advantage, that it will remove any new files from the production directory, which was added on server side, no matter if it was added to the repo or not. It will be always clean dupe of the repo. It is slower than Deployment Solution 1.

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET1/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; git checkout -f $branch fi BRANCH_REGEX='^${GIT_BRANCH2}.*

DEPLOY SOLUTION 2


Both solutions are based on earlier solutions available in this thread.

Note, the
BRANCH_REGEX='^${GIT_BRANCH1}.$'
filters for the branch names matching "master
" or "dev*" string, and deploys the work tree, if the pushed branch matches.
This makes possible to deploy a dev version and master version to different places.

DEPLOY SOLUTION 1 removes only files, which are part of the repo, and was removed by a commit. It is faster than Deployment Solution 2.

DEPLOY SOLUTION 2 has the advantage, that it will remove any new files from the production directory, which was added on server side, no matter if it was added to the repo or not. It will be always clean dupe of the repo. It is slower than Deployment Solution 1.

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET2/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; git checkout -f $branch fi done

DEPLOY SOLUTION 2


Both solutions are based on earlier solutions available in this thread.

Note, the
BRANCH_REGEX='^${GIT_BRANCH1}.$'
filters for the branch names matching "master
" or "dev*" string, and deploys the work tree, if the pushed branch matches.
This makes possible to deploy a dev version and master version to different places.

DEPLOY SOLUTION 1 removes only files, which are part of the repo, and was removed by a commit. It is faster than Deployment Solution 2.

DEPLOY SOLUTION 2 has the advantage, that it will remove any new files from the production directory, which was added on server side, no matter if it was added to the repo or not. It will be always clean dupe of the repo. It is slower than Deployment Solution 1.

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET1/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; # DEPLOY SOLUTION 2: cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR1; export GIT_WORK_TREE=$GIT_TEMP_DIR1/. git checkout -f $branch export GIT_WORK_TREE=$GIT_TARGET1/. rsync $GIT_TEMP_DIR1/. -v -q --delete --delete-after -av $GIT_TARGET1/. rm -rf $GIT_TEMP_DIR1 fi BRANCH_REGEX='^${GIT_BRANCH2}.*

Both solutions are based on earlier solutions available in this thread.

Note, the
BRANCH_REGEX='^${GIT_BRANCH1}.$'
filters for the branch names matching "master
" or "dev*" string, and deploys the work tree, if the pushed branch matches.
This makes possible to deploy a dev version and master version to different places.

DEPLOY SOLUTION 1 removes only files, which are part of the repo, and was removed by a commit. It is faster than Deployment Solution 2.

DEPLOY SOLUTION 2 has the advantage, that it will remove any new files from the production directory, which was added on server side, no matter if it was added to the repo or not. It will be always clean dupe of the repo. It is slower than Deployment Solution 1.

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET1/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; git checkout -f $branch fi BRANCH_REGEX='^${GIT_BRANCH2}.*

DEPLOY SOLUTION 2


Both solutions are based on earlier solutions available in this thread.

Note, the
BRANCH_REGEX='^${GIT_BRANCH1}.$'
filters for the branch names matching "master
" or "dev*" string, and deploys the work tree, if the pushed branch matches.
This makes possible to deploy a dev version and master version to different places.

DEPLOY SOLUTION 1 removes only files, which are part of the repo, and was removed by a commit. It is faster than Deployment Solution 2.

DEPLOY SOLUTION 2 has the advantage, that it will remove any new files from the production directory, which was added on server side, no matter if it was added to the repo or not. It will be always clean dupe of the repo. It is slower than Deployment Solution 1.

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET2/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; git checkout -f $branch fi done

DEPLOY SOLUTION 2

Both solutions are based on earlier solutions available in this thread.

Note, the
BRANCH_REGEX='^${GIT_BRANCH1}.$'
filters for the branch names matching "master
" or "dev*" string, and deploys the work tree, if the pushed branch matches.
This makes possible to deploy a dev version and master version to different places.

DEPLOY SOLUTION 1 removes only files, which are part of the repo, and was removed by a commit. It is faster than Deployment Solution 2.

DEPLOY SOLUTION 2 has the advantage, that it will remove any new files from the production directory, which was added on server side, no matter if it was added to the repo or not. It will be always clean dupe of the repo. It is slower than Deployment Solution 1.

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET2/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; # DEPLOY SOLUTION 2: cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR2; export GIT_WORK_TREE=$GIT_TEMP_DIR2/. git checkout -f $branch export GIT_WORK_TREE=$GIT_TARGET2/. rsync $GIT_TEMP_DIR2/. -v -q --delete --delete-after -av $GIT_TARGET2/. rm -rf $GIT_TEMP_DIR2 fi done

Both solutions are based on earlier solutions available in this thread.

Note, the
BRANCH_REGEX='^${GIT_BRANCH1}.$'
filters for the branch names matching "master
" or "dev*" string, and deploys the work tree, if the pushed branch matches.
This makes possible to deploy a dev version and master version to different places.

DEPLOY SOLUTION 1 removes only files, which are part of the repo, and was removed by a commit. It is faster than Deployment Solution 2.

DEPLOY SOLUTION 2 has the advantage, that it will remove any new files from the production directory, which was added on server side, no matter if it was added to the repo or not. It will be always clean dupe of the repo. It is slower than Deployment Solution 1.

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET1/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; git checkout -f $branch fi BRANCH_REGEX='^${GIT_BRANCH2}.*

DEPLOY SOLUTION 2

Both solutions are based on earlier solutions available in this thread.

Note, the
BRANCH_REGEX='^${GIT_BRANCH1}.$'
filters for the branch names matching "master
" or "dev*" string, and deploys the work tree, if the pushed branch matches.
This makes possible to deploy a dev version and master version to different places.

DEPLOY SOLUTION 1 removes only files, which are part of the repo, and was removed by a commit. It is faster than Deployment Solution 2.

DEPLOY SOLUTION 2 has the advantage, that it will remove any new files from the production directory, which was added on server side, no matter if it was added to the repo or not. It will be always clean dupe of the repo. It is slower than Deployment Solution 1.

if [[ $branch =~ $BRANCH_REGEX ]] ; then export GIT_WORK_TREE=$GIT_TARGET2/. echo "Checking out branch: $branch"; echo "Checking out to workdir: $GIT_WORK_TREE"; git checkout -f $branch fi done

DEPLOY SOLUTION 2

Both solutions are based on earlier solutions available in this thread.

Note, the
BRANCH_REGEX='^${GIT_BRANCH1}.$'
filters for the branch names matching "master
" or "dev*" string, and deploys the work tree, if the pushed branch matches.
This makes possible to deploy a dev version and master version to different places.

DEPLOY SOLUTION 1 removes only files, which are part of the repo, and was removed by a commit. It is faster than Deployment Solution 2.

DEPLOY SOLUTION 2 has the advantage, that it will remove any new files from the production directory, which was added on server side, no matter if it was added to the repo or not. It will be always clean dupe of the repo. It is slower than Deployment Solution 1.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文