这是我早期的问题 "如何使用mercurial管理并发开发" 的表亲问题,该问题涵盖了各个开发人员的工作流程.这个问题的答案实际上会影响开发人员工作流程的选择.
这不是一般的"版本管理最佳实践"或CI问题,因为它已经被问 很多 次有很好的答案,而且也可用来消磨时间的文学庞大的身躯.
我只是要求在发布管理的上下文中使用mercurial的具体方法.
最明显和最主要的答案应该是稳定的/默认的,这完全由@Steve Losh 的漂亮博客覆盖,并且在他的回答中更简洁.它简单而有效.
这种设置的一个突出例子是hg本身.hg使用更多的存储库进行主动开发,但是出于管理目的,一切似乎都包含在主repo的stable/default分支中.
hg设置实际上表示稳定/默认的变体,或者更确切地说是扩展版本:分支克隆.我在回答关于命名分支与多重回购的问题时描述了这个过程(来自@Martin Geisler的另一个很好的答案).在我的回答中我忘记提到的是分支克隆如何为开发人员工作流程工作:如果你需要修复分支的bug,你可以hg clone <main repo>#<branch>但不是分支克隆,因为你的变更集仍然会回到主仓库并推出自动分支克隆.当然,您可以选择不克隆并仅hg update <branch>在主克隆中,但是大多数使用单独克隆的参数(尤其是独立构建)都适用于此处.
现在回到问题:是否有其他方法适合不同的现实场景?例如,传统的主要/次要/补丁发布周期与版本之间的长时间推移可能需要完全不同于快节奏,即用即发的Web应用程序.如果您愿意,还请评论稳定/默认和分支克隆方法.
由于这几乎是一个调查问题,我只能主观地接受"最佳"答案.如果我能得到比我的开发人员工作流程问题更多的答案,那就是.
感谢您的所有投入!
这是一个最佳实践问题,我希望答案是"它取决于".我只是希望了解更多真实世界的场景和工作流程.
首先,我在谈论同一个项目的不同变化,所以请不要再使用subrepo.
假设您在hg存储库中拥有代码库.您开始处理复杂的新功能A,然后由您的可信测试人员报告复杂的错误B(您有测试人员,对吧?).
如果(修复)B取决于A,那将是微不足道的.你可以ci A然后ci B.
我的问题是当他们独立时(或至少现在看来)该怎么做.
我可以想到以下几种方式:
1和2 由@Steve Losh 的优秀博客覆盖,该博客与一个稍微相关的问题相关联.
与其他选择相比,1的一个巨大优势是,当您从处理一件事物到另一件事物时,它不需要任何重建,因为文件是物理上分离且独立的.所以它真的是唯一的选择,例如,A和/或B接触定义三态布尔的头文件,并被数千个C文件包含(不要告诉我你没有看到这样的遗留代码基础).
3可能是最简单的(在设置和开销方面),如果B是一个小的和/或紧急修复,你可以翻转A和B的顺序.但是,如果A和B接触相同的文件,它会变得棘手.如果A和B的变化在同一个文件中是正交的,那么很容易修复无法应用的补丁,但从概念上讲它仍然有点风险.
4可以让你头晕,但它是最强大,最灵活和可扩展的方式.我默认hg qinit使用,-c因为我想标记正在进行中的补丁并推送/拉取它们,但它确实需要一个概念上的飞跃才能意识到你也可以在MQ repo中进行分支.以下是步骤(mq = hg --mq):
hg qnew bugA; 为A做出改变;hg qrefmq branch branchA; hg qcihg qpop; mq up -rtip^hg qnew bugB; 为B做出改变;hg qrefmq branch branchB; hg qcihg qpop; mq up branchA; hg qpush采取这么多步骤似乎很疯狂,每当你需要切换工作时,你必须这样做hg qci; hg qpop; mq up <branch>; …
考虑一下这个简单的回购:
mkdir temp
cd temp
hg init
echo abc > file1
hg ci -A -m init
echo def >> file1
echo hey > file2
hg ci -A -m A
hg up -r0
echo ghi >> file1
echo hey > file3
hg ci -A -m B
hg merge
hg ci -m merge
Run Code Online (Sandbox Code Playgroud)
在合并期间,取"ghi"(哪一方并不重要).
DAG是:
0 - 2 - 3
\- 1 -/
Run Code Online (Sandbox Code Playgroud)
hg diff -r1:3 显示file1更改和新文件3.
hg diff -r2:3显示新文件2.对于hg log -p -r3和相同hg st --change 3,因为2是第一个父级.
我的问题是: …
对于带有图标的JLabel,如果setHorizontalTextPosition(SwingConstants.LEADING)是,则无论标签有多宽,都会在文本后面立即绘制图标.
这对于列表来说尤其糟糕,因为图标将遍布整个地方,具体取决于每个项目的文本长度.
我跟踪代码,似乎是SwingUtilities#layoutCompoundLabelImpl,文本宽度只是设置为SwingUtilities2.stringWidth(c, fm, text),而图标x设置为跟随文本而不考虑标签宽度.
这是最简单的情况:
import java.awt.*;
import javax.swing.*;
public class TestJLabelIcon
{
public static void main(String args[])
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JLabel c = new JLabel("abc");
c.setHorizontalTextPosition(SwingConstants.LEADING);
c.setHorizontalAlignment(SwingConstants.LEADING);
c.setIcon(UIManager.getIcon("FileChooser.detailsViewIcon"));
c.setBorder(BorderFactory.createLineBorder(Color.RED));
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add(c);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
您可以看到标签始终填充框架但图标保持不变.如果将两个参数都设置为,则会出现镜像问题TRAILING.
我知道我可以覆盖UI,或使用JPanel等.我只是想知道我是否在JLabel中遗漏了一些简单的东西.如果没有,它似乎是一个Java bug.
仅供参考,这是Windows XP上的jdk1.6.0_06.
我已经阅读了几次关于键绑定的明确教程,但是我的脑缓存似乎不足以容纳复杂的进程.
我正在调试一个键绑定问题(事实证明我使用的是错误的JComponent.WHEN_*条件),我偶然发现javax.swing.KeyboardManager了一个(不幸的)匿名Java工程师私有包的简洁和欢闹的javadoc .
我的问题是:除了KeyEventDispatcher在一开始就检查过,描述是否错过和/或错误?
KeyboardManager类用于帮助调度WHEN_IN_FOCUSED_WINDOW样式操作的键盘操作.具有其他条件的操作直接在JComponent中处理.
下面是我理解的键盘调度应该如何工作的语法[原文如此]的描述.[原文如此].
KeyEvents被分派到焦点组件.焦点管理员首先处理此事件.如果焦点管理器不想要它,那么JComponent调用super.processKeyEvent(),这允许侦听器有机会处理事件.
如果没有一个听众"消费"该事件,那么键绑定就会得到一个镜头.事情开始变得有趣.首先,使用WHEN_FOCUSED条件定义的KeyStokes [sic]有机会.如果这些都不想要该事件,那么该组件会通过它[sic]父母查找WHEN_ANCESTOR_OF_FOCUSED_COMPONENT类型的操作.
如果还没有人接受它,那么它就会在这里结束.然后,我们查找为WHEN_IN_FOCUSED_WINDOW事件注册的组件并触发它们.请注意,如果没有找到这些,那么我们将事件传递给菜单栏并让它们有一个裂缝.他们的处理方式不同.
最后,我们检查一下是否正在查看内部框架.如果我们是,并且没有人想要这个事件,那么我们将向上移动到InternalFrame的创建者,看看是否有人想要这个事件(依此类推等等).
(更新)如果你曾经想过关键绑定指南中这个大胆的警告:
因为搜索组件的顺序是不可预测的,所以避免重复WHEN_IN_FOCUSED_WINDOW绑定!
这是因为以下部分KeyboardManager#fireKeyboardAction:
Object tmp = keyMap.get(ks);
if (tmp == null) {
// don't do anything
} else if ( tmp instanceof JComponent) {
...
} else if ( tmp instanceof Vector) { //more than one comp registered for this
Vector v = (Vector)tmp;
// There is no well defined order for WHEN_IN_FOCUSED_WINDOW
// bindings, but we …Run Code Online (Sandbox Code Playgroud) 这应该是一个非常简单的运行,但由于某种原因它不适用于我的Mercurial存储库.我想要的只是远程仓库hg update在有人推送时自动运行.所以我在.hg/hgrc文件中有这个:
[hook]
changegroup = hg update
Run Code Online (Sandbox Code Playgroud)
简单吧?但由于某种原因,这永远不会执行.我也尝试编写一个执行此操作的shell脚本..hg/hgrc看起来像这样:
[hooks]
changegroup = /home/marc/bin/hg-update
Run Code Online (Sandbox Code Playgroud)
和hg-update看起来像这样:
#!/bin/sh
hg help >> /home/marc/works.txt;
hg update >> /home/marc/works.txt;
exit 0;
Run Code Online (Sandbox Code Playgroud)
但同样,这不会更新.hg help写出来的内容works.txt,但没有写出来hg update.有什么明显的东西我在这里不见了吗?这一直困扰着我好几天,我似乎无法让它发挥作用.
更新
好的,再次,使用-v我的工作站命令行上的开关推送到远程仓库,即使我有这些echo行,也不打印任何详细消息.hg/hgrc.但是,当我从同一文件系统上的repo克隆推送(我通过SSH登录)时,这就是我得到的:
bash-3.00$ hg -v push ../test-repo/ pushing to ../test-repo/ searching for changes 1 changesets found running hook prechangegroup: echo "Remote repo is at `hg tip -q`" echo "Remote repo wdir is at `hg parents -q`" Remote repo is …
正如明确指南恰当指出的那样(搜索"标签和克隆"):
当您
hg clone -r foo从标记运行克隆存储库时foo,新克隆将不包含比标记引用的更新的任何修订版本,包括创建标记的修订版本.结果是,您将在新存储库中获得项目历史记录的正确子集,但不会获得您可能预期的标记.
这意味着hg tags在您的新克隆中不显示foo标记.如果您在foo添加标记之前克隆了同样的事情,那么就是这样hg pull -r foo.
(题外话:标签是我唯一不太理解的东西.我理解将它放入变更集中有优势(例如合并),但是将元数据与源代码混合在一起感觉很奇怪.)
很明显,我要求采用自动化方式,而不是将标签变更集作为单独的手动步骤.
我知道我可以在incoming钩子中检查这个场景(因此它适用于克隆和拉动),或者包装clone和pull.
但是有更好/更简单的方法吗?
UPDATE hg bug tracker已经有了这个问题.
在AWT或Swing中是否有一种方法要么告诉我是否有模态窗口(或多个),或者返回它们的数组?
我看了看Window,Dialog,JDialog,SwingUtilities,等,但没能找到.
(我知道我可以循环Window#getWindows检查Dialog#isModal.)
在任何非平凡的hg安装中,hgrc往往包含重要的东西.
有没有办法完全忽略/绕过从系统,用户到回购级别的所有配置?
用例是在某些自动化脚本中使用一些hg核心功能.目前,如果有任何错误配置(我和我的〜/ .hgrc混乱),脚本将中止它根本不使用的东西.
它是完美的,我可以hg <whatever> --config:none.
我正在尝试在Windows上运行Mercurial进程内挂钩.
问题不在于如何编写钩子(我想使用现有的钩子,在这种情况下BugTracker.Net的钩子用于Mercurial集成 - 我没有找到该文件的直接链接,但你可以看到它如果你在这里下载BT.net ,它位于"mercurial"子文件夹中.
问题是如何告诉Mercurial运行它.
我花了很长时间阅读文档,但我现在卡住了.
(使用Python的某些知识可能会更容易 - 我没有)
我知道我必须在hgrc文件中插入一行(在我的存储库的.hg文件夹中).
HG Book中有一个例子如下:
[hooks]
commit.example = python:mymodule.submodule.myhook
Run Code Online (Sandbox Code Playgroud)
还有Mercurial网站上的另一个例子,它看起来像这样:
[hooks]
changegroup = /path/to/changegrouphook
Run Code Online (Sandbox Code Playgroud)
现在我想要一个"传入"钩子,所以至少我知道我必须这样做:
[hooks]
incoming.btnet = X
Run Code Online (Sandbox Code Playgroud)
问题是找出"X".
文件名是hg_hook_for_btnet.py,在文件中有一行如下所示:
def debug_out(s):
Run Code Online (Sandbox Code Playgroud)
我想这就是"功能"本身的名称.
所以我的行需要看起来像这样:
[hooks]
incoming.btnet = python:hg_hook_for_btnet.debug_out
Run Code Online (Sandbox Code Playgroud)
但是这给了我一个错误信息[Errno 2]当我推送时没有这样的文件或目录.
我已经尝试了很多不同的变化,但它不起作用,我不知道我做错了什么.
另外,我是否将钩子文件放入正确的文件夹中?
现在,它位于我的存储库的主文件夹中(与.hg文件夹位于同一级别).
编辑:
马丁,我改成了这个:
[hooks]
incoming.btnet = python:~c:\HG\MyRepo\hg_hook_for_btnet.py:debug_out
Run Code Online (Sandbox Code Playgroud)
现在我得到一个不同的消息: …
问题可以简单地说明:
hg init temp
cd temp
touch a
hg ci -A -m file
hg rm a
mkdir a
hg ci -m dir
hg up -r0
Run Code Online (Sandbox Code Playgroud)
最后一个命令失败abort: Is a directory: a(或Access is denied在Windows上更加神秘).
有没有解决方法?
在转换遗留代码库时遇到了这个确切的问题.我真的需要完全自动化转换,因为我有几十个版本的巨大代码库来处理,同义文件/目录可以随时发生.
hg tags 总是显示所有标签,那么我怎样才能获得指向特定修订及其所有祖先的标签?
真实世界的用例是,如果我使用本地标签来指定变更集上的功能(或错误修复),我需要找出累积的功能/错误直到特定的转速.
一种解决方案是添加一个将"-r"添加到的包装器命令tags.那么实现它的最佳方法是什么?使用revsets获取所有祖先转速并过滤标签?
我正在寻找创建一个Mercurial钩子,当我推送到本地存储库时,它会推送到备份远程存储库.我以为我可以挂钩'传出'钩子,但这会产生一个不太漂亮的无限循环.那么有没有像推后挂钩,或者最好是让我推送的存储库有一个"传入"钩子来推送到远程备份而不是?