是“git push --mirror”吗?足以备份我的存储库吗?

发布于 2024-09-11 13:08:57 字数 833 浏览 4 评论 0原文

我是一名独立开发人员,在本地 Git 存储库中工作。对于备份,我想将该存储库的精确副本发送到另一台服务器。

这样做就足够了吗?

git push --mirror

我这么问是因为有时我可以在 Git 告诉我“一切都是最新的”之前运行这个命令两到三次,所以显然它不是一个精确的镜像。似乎正在重新推送跟踪分支...?

$ git push --mirror
Counting objects: 42, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (30/30), done.
Writing objects: 100% (30/30), 5.09 KiB, done.
Total 30 (delta 17), reused 0 (delta 0)
To ssh://my/repo/url
   c094a10..0eedc92  mybranch -> mybranch
$ git push --mirror
Total 0 (delta 0), reused 0 (delta 0)
To ssh://my/repo/url
   c094a10..0eedc92  origin/mybranch -> origin/mybranch
$ git push --mirror
Everything up-to-date

发生了什么事,这是一个好的策略吗?

编辑:我不喜欢使用诸如 git bundle 或 .tar.bz2 档案之类的东西,因为我希望备份成为可访问的工作副本。由于我的备份服务器已连接到网络并且始终处于开启状态,因此这是我在路上访问存储库的好方法。

I'm a solo developer, working in a local Git repository. For backups, I want to send an exact copy of that repository off to another server.

Is it sufficient to do this?

git push --mirror

I'm asking because I can sometimes run this command two or three times before Git tells me "Everything up-to-date", so apparently it's not an exact mirror. It seems to be re-pushing tracking branches...?

$ git push --mirror
Counting objects: 42, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (30/30), done.
Writing objects: 100% (30/30), 5.09 KiB, done.
Total 30 (delta 17), reused 0 (delta 0)
To ssh://my/repo/url
   c094a10..0eedc92  mybranch -> mybranch
$ git push --mirror
Total 0 (delta 0), reused 0 (delta 0)
To ssh://my/repo/url
   c094a10..0eedc92  origin/mybranch -> origin/mybranch
$ git push --mirror
Everything up-to-date

What is happening, and is this a good strategy?

Edit: I don't like to use something like git bundle or .tar.bz2 archives, because I'd like the backup to be an accessible working copy. Since my backup server is connected to the net and always on, this is a nice way to access the repository when I'm on the road.

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

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

发布评论

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

评论(9

回忆那么伤 2024-09-18 13:08:57

您第二次看到某些内容被推送的原因是 --mirror 推送的内容比您预期的要多一些。除了本地分支之外,它还会推送远程分支,因为镜像意味着一切。因此,当您正常推送(或使用 --mirror)时,mybranch 会被推送,并且 origin/mybranch 会更新以反映 origin 上的新状态。当您使用 --mirror 推送时,origin/mybranch 也会被推送。

这会导致你看到奇怪的情况,并且当你从遥控器拉出时,也会导致更严重的奇怪情况;你会得到名为 origin/origin/mybranch 等的分支。所以通常最好使用 --mirror 进行一次复制,并且只使用普通推送(也许与 >--all) 正常使用。

要始终推送所有分支和标签,您可以像这样更新 .git/config

[remote "origin"]
  url = ...
  fetch = ...
  push = +refs/heads/*
  push = +refs/tags/*

这将使普通推送类似于镜像,只不过它不会删除不存在的分支源或非快进更新。

The reason you see something pushed the second time is that --mirror pushes a little more than you expect. Apart from your local branches, it also pushes your remote branches, because mirror implies everything. So when you push normally (or with --mirror), mybranch is pushed and origin/mybranch is updated to reflect the new status on origin. When you push with --mirror, origin/mybranch is also pushed.

This results in the strangeness you see, and also in a worse strangeness when you pull from that remote; you would get branches named origin/origin/mybranch etc. So it's usually best to use --mirror for one time copies, and just use normal push (maybe with --all) for normal uses.

To always push all branches and tags, you can update .git/config like so:

[remote "origin"]
  url = ...
  fetch = ...
  push = +refs/heads/*
  push = +refs/tags/*

That will make a normal push similar to a mirror, except that it won't delete branches that don't exist at the source or for non-fast-forward updates.

你是暖光i 2024-09-18 13:08:57

不幸的是,您无法通过推送获得精确的副本。您丢失了您的存储

Unfortunately, you don't get an exact copy with push. You lose your stash.

九公里浅绿 2024-09-18 13:08:57

我想说这是一个完全可以接受的备份存储库的策略。它应该为存储库中的每个引用执行到原始远程的推送。使其成为本地存储库的完整“镜像”。

编辑:我刚刚在问题中看到了您更新的描述。看来 git 正在将您的远程引用与其他所有内容一起推送到远程本身。推送完成后,远程引用将更新以反映您刚刚推送到它。现在,这对于远程存储库来说已经过时,因此需要进一步推送。如果这还不能满足你。您可以删除此远程引用

git推送:origin/mybranch

然后使用

git推送--全部

请记住,这不会推送您创建的任何新分支。

I would say this is a perfectly acceptable strategy for backing up your repository. It should perform a push to your origin remote for every ref in the repository. Making it a complete 'mirror' of your local repository.

EDIT: I've just seen your updated description in the question. It seems git is pushing your remote ref to the remote itself along with everything else. Once the push has finished, the remote ref will be updated to reflect that you have just pushed to it. This will now be out of date with the remote repository so a further push is necessary. If this doesn't satisfy you. You can delete this remote ref with

git push :origin/mybranch

and then use

git push --all

remember that this won't push any new branches you create though.

星軌x 2024-09-18 13:08:57

我所做的是:

设置存储库:git clone --mirror user@server:/url-to-repo.git

然后当您想要刷新备份时:git Remote update code> 来自克隆位置。

这会备份所有分支,包括稍后添加的新分支,但值得注意的是,被删除的分支不会从克隆中删除(这对于备份来说可能是一件好事)。

来自 http://www.garron.me/en/bits/备份-git-bare-repo.html

What I do is:

Setup the repo: git clone --mirror user@server:/url-to-repo.git

Then when you want to refresh the backup: git remote update from the clone location.

This backs up all branches, including new branches that get added later, although it's worth noting that branches that get deleted do not get deleted from the clone (which for a backup may be a good thing).

From http://www.garron.me/en/bits/backup-git-bare-repo.html

時窥 2024-09-18 13:08:57

我通常使用 git push --all 。我只在需要推送新创建的分支或者删除了一些分支并且不想一一命名时使用 --mirror 。否则,push --all 通常可以按我的需要工作。

I usually use git push --all. I only use --mirror when i need to push newly created branches or I deleted some branches and dont want to name them one by one. Otherwise the push --all usually works as I need.

浅忆 2024-09-18 13:08:57

本着与Amber的回答<相同的精神< /a>,您可以:

In the same spirit than Amber's answer, you could:

眼波传意 2024-09-18 13:08:57

我花了很长时间尝试开发一个 bash 脚本来安全地将一组存储库从 git 服务器备份到另一个存储库。

我相信以下脚本可以正常工作,但我建议对其进行测试。

问题陈述:有一组存储库托管在名为 origin 的服务器中。需要定期将所有存储库备份到另一台主机(称为上游),获取所有分支。

解决方案:

declare -a projects=("rep1 rep2 rep3 rep4")

for project in ${projects}; do
    cd $project;
    pwd;
    git fetch --all -v;
    git status -v;
    for remote in `git branch -r | grep origin | grep -v /HEAD`; do
        echo Remote $remote; 
        git checkout --track $remote ; 
    done;
    for remote in `git for-each-ref --format '%(refname:short)' refs/heads/`; do
        echo Branch $remote;
        git checkout $remote;
        git pull;
    done
    git push -v --all upstream;
    cd ..;
done

在此解决方案中,脚本循环遍历所有项目,并且对于每个项目,它执行另外两个循环。在第一个循环中,脚本识别并开始跟踪主机(源)中的所有分支,甚至是尚未跟踪的分支。在第二个循环中,脚本拉取所有分支。最后,脚本将所有分支推送到新的 git 主机(上游)。

I've been working for a long time trying to develop a bash script to safelly backup a set of repositories from a git server to another one.

I believe the following script works properly, but I recomend testing it.

Problem statement: One has a set of repositories hosted in a server called origin. One needs to periodicaly backup all repositories to another host (called upstream), taking all branches.

Solution:

declare -a projects=("rep1 rep2 rep3 rep4")

for project in ${projects}; do
    cd $project;
    pwd;
    git fetch --all -v;
    git status -v;
    for remote in `git branch -r | grep origin | grep -v /HEAD`; do
        echo Remote $remote; 
        git checkout --track $remote ; 
    done;
    for remote in `git for-each-ref --format '%(refname:short)' refs/heads/`; do
        echo Branch $remote;
        git checkout $remote;
        git pull;
    done
    git push -v --all upstream;
    cd ..;
done

In this solution, the script loops over all projects, and for each project, it does two other loops. In the first loop, the script identifies and start tracking all branches that are in the host (origin), even branches that are not tracked yet. In the second loop, the script makes pull of all branches. Finally, the script pushes all branches into new git host (upstream).

三月梨花 2024-09-18 13:08:57

对于那些想要通过中间存储库(通过 CI / Jenkins)镜像 Git 存储库的人来说,--mirror 是不够的 - 因为 CI 存储库不是一个可用的存储库,refs/heads代码> 未填充!

您使用 refspec 语法:

git push https://evil.com/proj/repo +refs/remotes/origin/*:refs/heads/* +refs/tags/*:refs/tags/*

用冒号分隔的引用表示 src:dst - 就像来自 origin 的每个分支推送到远程镜像。标签也一样。

For those who want to mirror a Git repo via intermediate repository (via CI / Jenkins) --mirror is not sufficient - because a CI repo is not a working repo, refs/heads are not populated!

You use refspec syntax:

git push https://evil.com/proj/repo +refs/remotes/origin/*:refs/heads/* +refs/tags/*:refs/tags/*

Refs separated by colon denote src:dst - like every branch from origin to push to a remote mirror. Same for tags.

猫弦 2024-09-18 13:08:57

为什么不直接压缩 .git 文件夹的副本并将其发送到另一台服务器呢?

Why not just compress a copy of the .git folder and send that off to another server?

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