如何在git中备份私有分支

54

我在git中有一个本地分支用于日常开发工作。我的工作流程如下:

  1. 在local_branch上进行操作,然后提交
  2. 获取origin/master分支
  3. 将local_branch分支rebase到最新的origin/master分支

这一切都很顺利,但是我遇到的大部分建议都说不应该“push”私有分支,而在这些分支上经常执行rebase。

问题在于,在这种情况下,本地分支没有备份到服务器上,唯一保存工作的方法是将其合并回可“push”的分支(即origin/master)。

在这种情况下,您会对工作流程有什么建议呢?

谢谢!

更新:我意识到我原来的一个要求(避免使用外部工具)是不必要的限制。

我的当前解决方案是将所有存储库存储在一个云同步文件夹中 - 这样我就可以获得免费的备份。

7个回答

53

我使用 --mirror 选项并推送到个人备份存储库:

将其添加为远程:

git remote add bak server:/path/to/backup/repo

进行备份:

git push --mirror bak

这将自动使您的备份仓库看起来像您的活动仓库--分支将根据需要创建、删除、更新(甚至强制/非快进方式)。您也可以为此创建一个别名:

git config alias.bak "push --mirror bak"

然后,只需在需要备份时运行 "git bak" 即可。您也可以将此命令添加到 cron 作业中。


感谢--mirror和config别名,我会研究一下的。 - Art
提醒一下,这个解决方案不会镜像您的 .git 目录中的配置文件(confighooks/* 等)。提醒一下。尽管如此,我认为这是一个好的解决方案。 - Pat Notz

6

推送个人分支没有问题。但通常不建议这样做,因为其他人可能会基于你的分支开始工作,当你进行变基时,他们的更改就会悬而未决。

我的做法是使用前缀来表示“这是我的分支,请自行决定是否使用”,例如:fc-general-cleanup


但是在变基之后,你会收到分支分叉的警告,不是吗? 请参阅http://superuser.com/q/667146/57249。 解决方案可能是为私有分支执行git push --force,这可行吗? - Dror
当然,你会收到关于分歧的警告,这就是rebase的作用,是的,你需要执行git push --force - FelipeC

5
另一种选择是将“local_branch”推送到“origin”仓库,但是推送到该仓库的自己的分支(不是“master”),即: git push origin local_branch:local_backup 然后,在您准备进行另一个备份时(并在做了一些工作和变基之后),只需在再次推出之前从原始仓库中删除备份分支: git push origin :local_backup <=== 从原始仓库中删除分支 git push origin local_branch:local_backup 这样,当“local_branch”从“origin/master”中被变基后,就不会遇到推送问题。
如果删除备份分支让您感到紧张(直到最终将您的工作提交到“master”),您始终可以将其推送到具有新名称的新分支(例如“local_backup1”,“local_backup2”等)。

如果使用 push --force,那么删除步骤是否是不必要的呢? - Art
是的,“--force”是删除的一个好替代方案。它将用本地分支的新分支头替换远程分支头。 - Dan Moulding
默认情况下,远程仓库会拒绝非快进式推送,因此 --force 可能不足以解决问题。 https://dev59.com/gXVC5IYBdhLWcg3wjx_u#255080 - CB Bailey
@Charles:这正是“--force”标志的作用:绕过git默认拒绝接受非快进式推送的限制。 - Dan Moulding
我明白了,我只是想确保我们记录下来“--force”并不在所有情况下都足够。大多数中央仓库都被创建为“共享”(这是设置多用户启用的共享仓库的最简单方法),因此我最初的评论是远程仓库将拒绝非快进式推送,而你似乎与之矛盾。我想我本可以更详细地解释“默认情况下”,但我认为我的链接答案已经有了足够清晰的解释。 - CB Bailey
显示剩余3条评论

2

你可以设置另一个远程仓库,将所有分支都推送到该仓库吗?另一个考虑的事情就是备份本地机器上的所有重要内容,包括git仓库。


1
如果设置单独的存储库,我仍然会遇到更改历史的问题 - 也就是说,在变基后我将无法直接推送。 - Art

2
在从中重置的分支上推送没有问题。下面的图表说明了为什么这样做没问题:
假设你在本地分支上创建了一个分支,并提交了一些更改(C和D),此时提交历史如下所示。在你创建local_branch之后,其他人向origin/master提交了一个更改(E):
A -- B -- E [origin/master] \ \ \-- C -- D [local_branch]
然后运行"git rebase origin/master"后,提交历史将如下所示。"origin/master"保持不变,但是"local_branch"已经被重新设置:
A -- B -- E [origin/master] \ \ \-- C -- D [local_branch]
此时,如果你执行"git push origin local_branch:master",就会得到一个简单的快进。"origin/master"和"local_branch"将相同:
A -- B -- E -- C -- D [origin/master],[local_branch]
现在你可以在"local_branch"上继续工作。最终,你可能会得到类似于以下内容:
A -- B -- E -- C -- D -- G -- I [origin/master] \ \ \-- F -- H [local_branch]
注意,这看起来很像开始的提交历史。你可以一遍又一遍地重复这个过程。
你应该避免向一些其他分支推送,特别是那些你没有进行重置的分支。否则,你会遇到麻烦(对于其他分支,看起来你的"local_branch"历史已经被重新编写,而这是在你从"origin/master"重置之后发生的)。

1
这不是我想要的。假设工作正在进行中,我不想将其合并到主分支,只想备份它。 - Art
哦,我完全误解了你的问题。对此感到抱歉。在我看来,一个合理的解决方案是将您的本地存储库克隆到某个有备份的位置。只需定期重新克隆即可使您的备份保持最新状态。但您不一定需要在克隆中进行任何工作(您可以在重新克隆以创建新的备份之前将其删除)。 - Dan Moulding
@Dan,当你执行“git pull --rebase”时,你会得到这个工作流程吗? - cmcginty
@Casey:是的。通常情况下,“git pull”等同于“git fetch”后跟一个“git merge”。但是,“git pull --rebase”等同于“git fetch”后跟一个“git rebase”,并且它会产生上述描述的工作流程。 - Dan Moulding

1

这是我做的事情。但是 - 这不是私有的。我这样做是为了能够与自己合作(可以这么说)。它让我在两个或更多的盒子上工作在同一个分支上。如果其他人可以访问共享仓库,他们就可以看到我在分支上所做的工作。当然,在我的家庭仓库中,没有其他人可以访问,因此它仍然是私有的。在 GitHub 上,全世界都可以看到我的东西。就像他们真的关心一样。;)


您似乎没有进行任何rebase操作,这正是我遇到的实际问题。 - Art
你可以尝试使用 "git pull" 命令拉取本地副本,然后在本地进行变基操作。这样,你的本地分支就会合并所有来自主分支的更改,下一次推送操作就会将更改推送到远程分支。我还需要尝试一下才能确定,但是看起来应该是可行的。 - Don Branson
Don,在非私有分支上rebase后的下一次pull会导致冲突。 - Art
嗯,发生了什么冲突?是经典情况吗,即在不同的分支上对同一代码块进行了不同的更改? - Don Branson

1
与其依赖于Dropbox来同步git repo的所有文件,我宁愿使用git bundle,它只生成一个文件(包括所有私有分支),然后将该文件与DropBox同步。
请参见 "Git with Dropbox"
在 "Backup a Local Git Repository" 中,Yars 提到了在Dropbox中出现同步错误的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接