最好/最简单的方法来保持多个(非裸)Git仓库同步 [英] best/simplest way to keep multiple (non-bare) Git repos in sync
问题描述
我有几个非裸Git存储库。有一个中央Git存储库(或者至少作为中央仓库来处理;这可能会改变),但这也不是光秃秃的(因为我想要在同一台机器上进行结账)。我的历史大部分是线性的,而且我是唯一一个对此存储库进行更改的人,所以不太可能发生冲突。 (这是我的文档目录。)
如果我使用 master $ c,则直接推入另一个非裸存储库不起作用$ c>无处不在。有
receive.denyCurrentBranch
这将允许这个,但它并没有真正帮助我,因为(1)它不更新本地结帐和(2)我害怕如果发生冲突,会发生什么情况。
这里有几个相关/类似的问题:
ssh git pull
)。
更新后
钩子(强烈建议避免它)。或者将它推送到某个特定的唯一远程引用,并让目标稍后处理合并。
我想要一个100%安全。所以我认为使用更新后的
挂钩对我来说是不行的。
我认为我的用例不是实际这是罕见的,所以我想知道是否有一些共同的解决方案。有没有?
我想,我想要的是:
- 推送本地(例如
merge-request-xy
)(即像git)
master 推送原点主控:合并请求
?)。 - 在远程,如果我们可以快进,工作副本干净,快进,更新工作副本并删除ref(基本上
git merge merge-request&& git branch -D merge-request
?)。
这是安全的还是一种很好的方法? >只要您(1)推送到不同于 master
的分支,像 merge-request
和(2)进行关于合并的检查。对于第二部分,如果所有内容都在远程清除,则可以使用后更新
钩子,如下所示:
#!/ bin / sh
#检查参数是否推入了合并请求,
#和do没有,如果它不是
! $(echo $ @ | grep -q'merge-request');
然后
echomerge-request not updated
exit 0
fi
#如果master没有被检出,则取消
THIS_BRANCH = $(git branch --no-color | sed -e'/ ^ [^ *] / d'-e's / * \(。* \)/ \1 /')
if [ $ THIS_BRANCH!=master];
然后
echo主未检出,未合并
出口1
fi
#取消如果工作目录很脏
if [$(git status --porcelain | wc -l)!= 0];
然后
echoworking dir is dirty,not merging
exit 1
fi
#尝试合并,但仅当合并时才这样做是快进
#尝试删除,但只有在合并成功时才这样做
git merge --ff-only merge-request&& git branch -d merge-request
确保 chmod + x
您的更新后脚本。当你推动时,这个钩子的输出将显示在以remote:开头的控制台中。
为了从 master
到 origin / merge-request
,您可以在远程设置 push
var配置文件 .git / config
(它可以让你调用 git push origin
:
[remoteorigin]
push = + refs / heads / *:refs / merge-request / *
或者您可以设置特定于回购的别名:
[别名]
push =推送原点主控:合并请求
I have several non-bare Git repositories. There is one central Git repository (or at least handled as being the central repo; this might change) but this is also non-bare (because I want to have a checkout on the same machine). My history is mostly linear and I'm the only person who will ever do changes on this repository, so it is unlikely that conflicts will happen. (It is my documents directory.)
Pushing directly into another non-bare repository doesn't work if I use the master
branch everywhere. There is receive.denyCurrentBranch
which would allow this but it doesn't really help me because (1) it doesn't update the local checkout and (2) I'm afraid of what happens in case there is a conflict.
There are a few related/similar questions here:
- simplest way to sync a repository with a checked out branch: Suggests setting up an Bash alias (basically
ssh git pull
). - making pushes to non-bare repositories safe: Using a
post-update
hook (with a strong advise to avoid it). Or rather push it to some specific unique remote ref and let the destination later handle the merging.
I want a solution which is 100% safe. So I think using a post-update
hook is no option for me.
I think my use case is not actual that uncommon so I wonder if there are some common solutions for this. Are there?
I think, what I want is:
- Push local
master
to some remote special ref (likemerge-request-xy
) (i.e. likegit push origin master:merge-request
?). - On the remote, if we can fast-forward and the working copy is clean, fast-forward, update the working copy and delete the ref (basically
git merge merge-request && git branch -D merge-request
?).
Would that be safe or a good way to do it?
The solution you have suggested is safe as long as you (1) push to a different branch than master
, like merge-request
and (2) do the checks about merging. For the second part, fast-forwarding if everything is in the clear on the remote, you can use a post-update
hook like this one:
#!/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
Make sure to chmod +x
your post-update script. When you push, output of this hook will be shown in the console prefaced by "remote:"
In order to push from master
into origin/merge-request
on the remote, you can either set the push
var in your remote config in .git/config
(which lets you call git push origin
:
[remote "origin"]
push = +refs/heads/*:refs/merge-request/*
or you can set a repo-specific alias:
[alias]
push = push origin master:merge-request
这篇关于最好/最简单的方法来保持多个(非裸)Git仓库同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!