【问题标题】:Can I commit only parts of my code using SVN or Mercurial?我可以使用 SVN 或 Mercurial 只提交部分代码吗?
【发布时间】:2010-09-14 00:48:38
【问题描述】:

我通常使用 Tortoise SVN,但我一直在研究 Mercurial,因为它是一个分布式版本控制系统。

在这两个系统中,我都在寻找一种工具,它可以让我只选择文件的一部分并提交它们。如果我现在想这样做,我必须复制到文件的临时版本并只保留我想在当前版本中提交的更改,然后在提交后再次将临时版本复制到当前版本。就是这么麻烦,程序应该可以帮我做。

我听说 Git 支持这个,如果正确请告诉我。

【问题讨论】:

  • 为SVN开发这样的工具应该是相当容易的。我想知道为什么还没有人这样做。
  • @PavelRadzivilovsky 补丁欢迎。我的意思是你可以写一个补丁并发送到 dev@ 邮件列表。
  • 现在有一个内置的interactive 提交实用程序用于这个确切的目的,它与 Mercurial 一起开箱即用。请参阅下面的答案。

标签: git svn version-control mercurial tortoisesvn


【解决方案1】:

Mercurial 可以通过 record 扩展来做到这一点。

它会提示您输入每个文件和每个差异块。例如:

% hg record
diff --git a/prelim.tex b/prelim.tex
2 hunks, 4 lines changed
examine changes to 'prelim.tex'? [Ynsfdaq?]  
@@ -12,7 +12,7 @@
 \setmonofont[Scale=0.88]{Consolas}
 % missing from xunicode.sty
 \DeclareUTFcomposite[\UTFencname]{x00ED}{\'}{\i}
-\else
+\else foo
 \usepackage[pdftex]{graphicx}
 \fi

record this change to 'prelim.tex'? [Ynsfdaq?]  
@@ -1281,3 +1281,5 @@
 %% Local variables:
 %% mode: latex
 %% End:
+
+foo
\ No newline at end of file
record this change to 'prelim.tex'? [Ynsfdaq?]  n
Waiting for Emacs...

commit之后,剩下的diff会被留下:

% hg di
diff --git a/prelim.tex b/prelim.tex
--- a/prelim.tex
+++ b/prelim.tex
@@ -1281,3 +1281,5 @@
 %% Local variables:
 %% mode: latex
 %% End:
+
+foo
\ No newline at end of file

或者,您可能会发现使用 MQ(Mercurial Queues)将存储库中的各个更改分成补丁更容易。还有一个记录的 MQ 变体 (qrecord)。

更新:还可以试试crecord 扩展,它提供了一个curses 接口来选择大块/行。

【讨论】:

  • 遗憾的是没有用于此的 GUI 工具。用 GitX 做这件事真是太棒了。
  • 阿门。 GitX 是我使用 Git 的原因;希望 Murky 也有能力。 (不幸的是,尽管我为 GitX 和 Murky 做出了贡献,但我的开源项目太多,无法修复它 :-)
  • 有一个 GUI 工具:Tortoisehg 支持大块选择。
  • ……现在使用了 TortoiseHg,它缺乏恢复大块的能力,这是 GitX 提供的,而且通常提供的接口要少得多。从差异中轻松删除意外(例如仅空格)更改的能力非常重要......
  • 无法编辑大块头是件好事。我不喜欢让我的开发人员提交他们实际上没有构建或测试过的代码的“特性”。当他们运行hg record 时,个别帅哥应该被视为不可变的;如果它们需要进一步编辑,那么是时候中止提交了。
【解决方案2】:

是的,git 允许你这样做。 git add 命令有一个-p(或--patch)选项,允许您逐块查看更改,选择要暂存的内容(您还可以优化块或编辑补丁)。您也可以使用交互模式来 git-add (git add -i) 并使用“p”选项。

这是一个screencast on interactive adding,它也演示了git add的补丁功能。

【讨论】:

  • 另请注意,git gui 提供了执行此操作的图形方式。
【解决方案3】:

查看 TortoiseHG,它会进行大块选择,并让您将不同的更改提交到一个文件,就像不同的提交一样。

它甚至可以让您在一次提交中提交对某些文件的所有更改以及对其他文件的部分更改。

http://tortoisehg.bitbucket.io/

【讨论】:

  • GUI 仅适用于 Windows
  • @user7610 不,它也支持Linux
  • Nautilus 扩展和 CLI 是的,但 TortoiseHg 中的一些 GUI 工具适用于 Windows
  • @user7610 "一些 GUI 工具" != "GUI"
【解决方案4】:

我刚才问了similar question,使用hgshelve extension得到的答案正是我想要的。

在进行提交之前,您可以将来自不同文件的更改(或文件中的大量更改)放在“架子”上,然后提交您想要的内容。然后,您可以取消搁置未提交的更改并继续工作。

过去几天我一直在使用它并且非常喜欢它。非常易于可视化和使用。

【讨论】:

    【解决方案5】:

    Mercurial 现在为commit 命令提供了一个选项--interactive(或-i),可以直接启用此功能。

    这直接从命令行工作,所以如果你是一个命令行爱好者,它是完美的!

    跑步

    > hg commit -i
    

    开始一个交互式会话,允许检查、编辑和记录单个更改以创建提交。

    这与git addgit commit 命令的--patch--interactive 选项非常相似。

    【讨论】:

    • 这是最好的答案。不需要扩展等。谢谢你的回答。
    【解决方案6】:

    我建议不要这样工作。

    如果您必须进行多组更改,即已准备好签入的设置 A 和尚未准备好的设置 B,您如何确保仅签入设置 A 不会破坏您的构建/测试?你可能会错过一些行,忘记不同文件中的行,或者没有意识到 A 对 B 的依赖会破坏其他人的构建。

    您的提交应该是谨慎的原子更改,不会破坏您或您团队中的其他人的构建。如果您只提交部分文件,那么您在不知情的情况下为他人破坏构建的机会将大大增加,直到您遇到一些不高兴的同事敲门。

    最大的问题是,您为什么觉得有必要以这种方式工作?

    【讨论】:

    • 通常是因为我在提交之前写了太多代码。我可能会更改文件中的两个不同的东西,并希望使用不同的 cmets 提交它们。
    • Git 支持(使用 git stash --keep-index)仅隔离您将要提交的更改,这使您可以轻松地运行单元测试或其他任何内容。
    • 来自 VisionMap 开发约定:“没有比将一个危险的更改与一千个微不足道的更改结合起来更糟糕的评论者的噩梦了。从这个意义上说,必须彻底清除任何模糊的垃圾,才能进行有意义的更改”跨度>
    • 这对于 Subversion 来说是个问题,因为提交会影响到每个人,但对于 Git 和 Mercurial 这样的分布式系统来说,这根本不是问题。您可以在实际分发您的更改之前拆分您的提交并测试它们。如果您真的是 1337,您甚至可以在之后编辑历史记录以清理任何错误,这样其他人就不需要知道它们发生了。如前所述,如果做这件事的人有足够的能力,这仍然可以在 Subversion 中完成。不过,中心化模型保证了 Subversion 存储库中不可避免地会出现问题。
    • 这并不总是一种选择。有时为时已晚,您放弃更改直到另一天,赶上另一个功能/更改,然后才意识到发生了什么。我们是人。我们的 VCS 应该处理我们笨拙的工作。这会发生,即使是错误的。因此,有必要具备这样的特点。 tomayko.com/writings/the-thing-about-git
    猜你喜欢
    • 2012-10-27
    • 2010-12-16
    • 1970-01-01
    • 1970-01-01
    • 2012-07-26
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    相关资源
    最近更新 更多