保持多个(非裸)Git repos同步的最佳/最简单方法

我有几个非裸
Git存储库.有一个中央
Git存储库(或者至少作为中央存储库处理;这可能会改变)但这也是非裸的(因为我想在同一台机器上进行结账).我的历史主要是线性的,我是唯一一个会对此存储库进行更改的人,因此不太可能发生冲突. (这是我的文件目录.)

如果我到处使用主分支,则直接推送到另一个非裸存储库不起作用.有receive.denyCurrentBranch可以允许这个,但它并没有真正帮助我,因为(1)它没有更新本地结账和(2)我害怕发生冲突时会发生什么.

这里有一些相关/类似的问题:

> simplest way to sync a repository with a checked out branch:建议设置Bash别名(基本上是ssh git pull).
> making pushes to non-bare repositories safe:使用更新后的挂钩(强烈建议避免它).或者更确切地说,将其推送到某个特定的唯一远程引用,让目标稍后处理合并.

我想要一个100%安全的解决方案.所以我认为使用更新后挂钩对我来说是没有选择的.

我认为我的用例实际上并不常见,所以我想知道是否有一些常见的解决方案.在那儿?

我想,我想要的是:

>将本地主服务器推送到某个远程特殊引用(例如merge-request-xy)(即像git push origin master:merge-request?).
>在遥控器上,如果我们可以快进并且工作副本是干净的,快进的,更新工作副本并删除ref(基本上是git merge merge-request&& git branch -D merge-request?) .

这样做是安全的还是一种好方法?

最佳答案 你建议的解决方案是安全的,只要你(1)推送到不同于master的不同分支,例如merge-request和(2)进行合并检查.对于第二部分,如果遥控器上的所有内容都是快速转发,则可以使用像这样的更新后挂钩:

#!/bin/sh

# check args to see if merge-request was pushed,
# and do nothing if it wasn't
if ! $(echo $@ | grep -q 'merge-request');
then
 echo "merge-request not updated"
 exit 0
fi

# cancel if master is not checked out
THIS_BRANCH=$(git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/')
if [ "$THIS_BRANCH" != "master" ];
then
  echo "master not checked out, not merging"
  exit 1
fi

# cancel if working dir is dirty
if [ $(git status --porcelain | wc -l) != 0 ];
then
  echo "working dir is dirty, not merging"
  exit 1
fi

# try to merge, but only do so if the merge is fast-forward
# try to delete, but only do so if the merge succeeded
git merge --ff-only merge-request && git branch -d merge-request

确保chmod x你的更新后脚本.当您按下时,此挂钩的输出将显示在控制台中,前面是“remote:”

为了从主服务器推送到远程服务器上的origin / merge-request,你可以在.git / config中设置远程配置中的push var(这可以让你调用git push origin:

[remote "origin"]
    push = +refs/heads/*:refs/merge-request/*

或者您可以设置特定于repo的别名:

[alias]
    push = push origin master:merge-request
点赞