推送秘密变更集

12

我知道秘密更改集是用来保密的,那么如果我想备份这些秘密更改集呢?尽管这看起来很矛盾。

我同时处理一些分支,有时我想推送其中一个,但不想推送其他分支。为了实现这一点,我在独立的克隆中工作,但我讨厌这种方式。

现在,Mercurial有了阶段(phases),我可以创建秘密分支,并将所有内容保存在同一个存储库中。问题是,在开始秘密分支和其发布之间,我想备份这些秘密更改集(我在另一台机器上克隆了一个副本,以防我的本地仓库或计算机发生故障)。

是否有方法可以做到这一点,还是我的工作流程完全错误?


如果主要目的是执行备份,我认为推送或使用其他HG命令不是最佳方法。相反,您应该将整个存储库克隆复制到备份目标。 - StayOnTarget
1
@DaveInCaz 为了备份整个仓库,可能只有几个本地变更集,而主要仓库可能已经有备份策略,这似乎有点过度了。(虽然对于一个小仓库来说可能是一个简单的解决方案。) - melutovich
如果你确定.hg文件夹是多余的,那么可以从PC备份中排除它。更好的方法是使用hg share(而不是clone)来避免一开始就产生冗余的磁盘使用。但最重要的是要有一个可靠的备份!所以个人而言,我不会选择自己动手备份,我会备份整个文件并继续前进。 - StayOnTarget
6个回答

5

不需要标记任何机密信息。如果你只想推送一个分支,使用以下命令:

hg push -r REV

这将仅推送REV及其祖先。

对于Mercurial补丁队列修订版本,Secret很有用,因为它们无法被推送,可以防止本地克隆复制它们。

Draft适用于跟踪未推送的更改。如果您仍然想备份它们,将它们推送会翻转它们到Public状态,但您可以使用以下命令将它们重置回草稿状态(与另一个存储库相比):

hg phase -fd 'outgoing(URL)'

(URL 可以为空,用于默认的推送仓库。)

3
将分支标记为保密的价值在于它可以防止意外发生(比如失误地遗漏了“-r REV”)。 - Steve Pitchers
当然,但如果他想要备份它们,它们就不能是机密的。 - Mark Tolonen
3
是的,很遗憾无法强制推送一个秘密分支。 - Steve Pitchers

3

看起来阶段仍然相对较新,某些工作流程(例如此类)似乎尚未包含在其中。截至2013-03-19,我认为您唯一能够做到的是手动将阶段从“保密”更改为“公开”。

您可以使用以下命令行命令:

for /f "delims=" %a in ('hg log --template "{rev} " -r "secret()"') do @set secret=%a
hg phase -d %secret%
hg push -f
hg phase -sf %secret%

这不会改变你要推送到的仓库上的 secret 提交,我尝试更改推送以实现此目的(但未成功):

hg push -f --remotecmd hg phase -sf %secret%

提交必须完全匹配才能使“远程hg命令”起作用,但我无法在远程存储库上进行更改。如果您想使用像TortoiseHG Workbench这样的GUI,则目前必须手动执行此操作(在任何要更改的存储库中在GUI上更改阶段)。很抱歉,希望我们能尽快找到更好的解决方案!

1
“--remotecmd”标志不适用于在服务器端运行“hg phase”。它的作用是告诉您本地的Mercurial,在使用SSH连接时应如何启动服务器端的Mercurial服务器。 - Martin Geisler

2
最佳方法是结合 @mischab1 的 答案,@mark-tolonen 的 答案 和别名。
按照 mischab1 的答案,您可以确保将备份位置推送到不会更改阶段为 "public"。
第二步是将备份位置添加到存储库的 hgrc/paths 中:
[paths]
default = ...
backup = backup_location

下一步是在全局hgrc中通过别名定义备份命令,例如“bubr”(备份当前分支)或“burev”(备份当前版本)。
[alias]
bubr = push -b . backup
burev = push -r . backup

hg bubrhg burev会将当前分支/版本推送到定义为“备份”路径的位置。

编辑这仍然有一个缺点,你可能会意外地使用“hg push”推送所有更改,因此定义一个hg pubr命令来推送当前分支并默认不使用“hg push”可能会有所帮助。


2
你可以将“默认”设置为指向备份,并给真正的HG服务器取一个不同的名称,比如“real”。然后,“hg push”将简单地推送到备份,你可以定义另一个别名“hg real-push”为“push -r . real”。这样,你就永远不会意外地将任何东西推送到真实环境了。 - DenNukem

0

这是我迄今为止想出的最好方案。我认为它基本上等同于您想要 push/pull 能够执行的操作。

  1. 将您想要传输的所有秘密变更集标记为草稿
  2. 在源存储库中运行 hg bundle -r last_draft_rev bundlefile.hg path\to\backup\repo
  3. 在目标存储库中运行 hg unbundle bundlefile.hg
  4. 变更集将作为草稿进入备份
  5. 将第一个草稿变更集标记为秘密,其所有后代都将被标记为秘密

如果变更集仍然标记为秘密,则我无法使步骤 #2 正常工作。


0
@echo off
rem hgfullpull_naive.cmd
setlocal
set SRC_REPO=%~f1
set DST_REPO=%~f2
set TMP_DIR=%TEMP%\%~n0.tmp
set NODES_LIST=%TMP_DIR%\%~n0.%RANDOM%.tmp

if "%SRC_REPO%"=="" exit /b 1
if "%DST_REPO%"=="" exit /b 1
if "%SRC_REPO%"=="%DST_REPO%" exit /b 1

call :ALL
del /Q "%NODES_LIST%"
endlocal
goto :eof

:ALL
    md "%TMP_DIR%"
    hg log --rev "secret()" --template "{node}\n" --repository "%SRC_REPO%" >"%NODES_LIST%" || exit /b 1
    call :CHANGE_PHASE "%SRC_REPO%" --draft
    hg pull --repository "%DST_REPO%" "%SRC_REPO%"
    call :CHANGE_PHASE "%SRC_REPO%" --secret
    call :CHANGE_PHASE "%DST_REPO%" --secret
    goto :eof

:CHANGE_PHASE 
    setlocal
    set REPO=%~1
    set PHASE=%~2
    for /F "eol=; delims= usebackq" %%i IN ("%NODES_LIST%") DO (hg phase %PHASE% --force --rev %%i --repository "%REPO%")
    endlocal
    goto :eof

-1
现在最简单的事情就是将备份存储库标记为非发布状态,只需在其hgrc配置文件中添加以下内容即可。
[phases]
publish = False

请查看Mercurial的Wiki获取更多信息。


2
这只是答案的一半。第一个问题是如何将秘密变更集取出... - schlamar

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