【问题标题】:Does any version control system have a "persistent local only change" feature?是否有任何版本控制系统具有“仅本地持久更改”功能?
【发布时间】:2009-10-27 01:55:39
【问题描述】:

这个问题是我在玩 git 时想到的,但我会问一般情况......

我只是想到了一个可能对版本控制很好的功能,但我不知道它是否存在或它被称为什么。我想称之为持久的本地更改。

假设我在 svn 中有一个配置文件,其中包含许多有用的不可重新创建的东西(因此必须在版本控制中),但有一个部分需要每个人自己编辑。可能是数据库配置,或者用户名和密码,或者某些 3rd 方软件的本地路径。您在这种情况下的选择是

  1. 在版本控制中编辑战争。继续更改文件,并希望其他人在您之前放弃编辑​​文件。

  2. 编辑它,但永远不要提交这些更改。他们只是坐在那里让你的“新增/更改”命令看起来很脏,你必须记住不要提交它。

  3. 对其进行模板化。从版本控制中删除该文件,并在末尾使用 .template 签入该文件的副本。在本地复制文件并将其重命名为您所做的更改。

  4. 使用新的(虚构的?)持久本地更改功能。进行更改,然后发出 record-changes-as-local-persistent 命令,该命令会计算出一个补丁,并在每次更新后重新应用您的补丁。

这个功能是否存在于任何地方(感觉就像 git stash,但目的略有不同)? 如果它不存在,是否有充分的理由不存在? (有人考虑过并认为这是个坏主意吗?)

【问题讨论】:

    标签: git version-control


    【解决方案1】:

    您可以在 git 中使用主(或“供应商”)分支和本地分支执行此操作。您的本地提交在本地分支上进行,当它更改时,您将其重新设置在 master 之上。如果您没有为本地分支指定远程,您将无法意外推送它;如果你不小心提交了一些你想要持久化到本地分支的东西,只需挑选到 master 并从那里推送。

    【讨论】:

    • +1。这是做到这一点的方法。干净且非侵入性,并且您不需要有脏的源代码树以及未提交的更改。
    • 一旦你开始有合并冲突,每次你必须重新设置基准时都必须修复相同的合并有点糟糕。如果您使用git merge 而不是git rebase,则不必继续修复合并,但我不知道这是否会导致其他问题...
    【解决方案2】:

    您可以忽略版本控制中的任何配置文件。这是.gitignore 文件。

    例如,如果您想忽略所有日志目录,请在该文件中添加一行:

    log/*
    

    要忽略 .DS_Store 文件,请添加一行:

    .DS_Store
    

    然后您可以在本地更新文件,您将永远不会在已修改但未提交的文件中看到它。如果你执行git add .,它不会被添加到提交中。

    如果您需要将配置文件放到 git 中,但只在其中保留一个密码或 var,我所做的就是在该配置文件中调用一个远程文件。这个文件包含我的密码。

    以 Rails 项目为例,我的数据库配置如下所示:

    production:
     database: project_database
     username: database_user
     password: <%= File.read('path/to/my/password/file').chomp if File.readable? 'path/to/my/password/file' %>
    

    文件“path/to/my/password/file”不在版本控制中。
    所以我的配置文件是版本化的。但密码取决于我们所在的机器。

    它还有一个优点是版本控制中的密码不会被任何人读取。

    【讨论】:

      【解决方案3】:

      这可能对 Visual Studio 更具体一点,但我认为大多数 IDE 都会有一些类似的功能。

      在我的所有应用程序/Web 配置中,我的设置会因不同环境而改变

        <dataConfiguration configSource="Config\Development\dataConfiguration.config" />
        <connectionStrings configSource="Config\Development\connectionStrings.config" />
        <appSettings configSource="Config\Development\appSettings.config"/>
      

      然后对于每个文件,它类似于

      <?xml version="1.0" encoding="utf-8" ?>
      <dataConfiguration defaultDatabase="defaultDatabase"/>
      

      之后,我为每个环境 Dev/Staging/Prod 等创建文件夹,并在每个文件夹中使用不同的子配置文件,以便可以将所有设置检入 TFS。我有我的 Web 部署项目设置,可以在每个版本配置中提取适当的文件。稍后当我配置 TFS 来管理我的版本时,只需复制正确的配置即可轻松实现。

      此时,您可以签入程序的基线,然后当开发人员只需要更改他们不打算签入的内容时,他们可以轻松地将文件设置为非只读文件并对其进行编辑。

      【讨论】:

        【解决方案4】:

        Darcs 提供此功能。您可以在本地存储库中记录对设置的更改补丁,而永远不要将其推送到另一个存储库。遗憾的是,FAQ states 无法将补丁标记为仅限本地。

        Once 可以通过使用仅包含您的存储库唯一的补丁的第二个存储库来解决此限制。

        【讨论】:

          【解决方案5】:

          如果您可以将多个存储库组合到一个工作树中,这是可行的。最简单的解决方案是符号链接。

          问题(这很困难)是 VCS 想要保留变更集的概念。因此,如果您将此类文件与常规版本化文件一起提交 - 更改是否属于变更集?在不同的机器上拥有相同的变更集意味着不同的东西显然是令人困惑的。

          对于多个存储库,您当然可以将提交放在一个存储库或另一个存储库中。这需要多少本地设置取决于 VCS 系统。例如,对于 svn:externals,您需要在每台机器上使用相同的 file: 存储库,但它们可以指向不同的文件集。使用符号链接,您可以按您喜欢的任何形式组织它(假设符号链接本身没有版本控制)。

          【讨论】:

            【解决方案6】:

            我在monotone 上做了类似的事情,使用propagate 命令。

            简而言之,我有一个“开发”分支和一个“已部署”分支。在部署的分支中,配置有一些不同的设置(一些目录和 DEBUG=False)。当我想部署时,我从开发到部署的分支执行mtn propagate。然后在服务器上进行拉取和更新,因此工作区从其分支获取最新更改,其中包括所有新开发,但尊重设置差异。

            【讨论】:

              【解决方案7】:

              我总是通过完全避免这种情况来解决这个问题。

              我尝试使所有环境尽可能地相似。唯一不同的地方通常是登录名,有时还有基础设施服务(数据库、消息代理、企业数据服务等)的 URL。

              所有开发者的开发环境设置完全一样,开发环境的配置也被签入,开发者可以直接从版本控制中检出代码并构建,无需任何进一步的摆弄。

              已签入 CI 和测试环境的密码和配置,因此构建和部署服务器可以自动在测试环境中启动系统。

              从不签入生产密码(这通常是我工作的法律要求),并且管理员在生产环境中维护密码文件。

              【讨论】:

                【解决方案8】:

                你可以用 SVN 来做这件事。

                如果您从库中检出一个文件并对其进行更改,然后再进行“更新”,您将从库中获取该文件的新副本,并应用您的更改。我经常将它用于配置文件。

                这与您所描述的不太一样,因为每次提交时,您都必须排除配置文件。我想如果您在某个时候忘记这样做,您将使用您的本地更改更新存储库,并导致其他人有些悲伤。

                当您确实需要更改配置文件的“公共”部分时,您必须进行单独签出,以便将“公共”更改与“本地”更改分开。

                我也赞同 Chris Marisic 所描述的计划。我有几个 Web 应用程序,我在其中创建了多个配置文件,程序会根据环境动态决定使用哪一个。

                在一种情况下,配置文件包含外部文件的路径,我同时使用 Windows 服务器和 Linux 服务器,因此路径名称不同。所以我最终创建了一个“Linux 配置”和一个“Windows 配置”,然后根据我运行的操作系统进行选择。

                在另一种情况下,程序在启动时检查 servlet 上下文的名称(它是一个 JSP/servlet 应用程序),然后查找名为“WEB-INF/.properties”的文件。如果没有找到,它会加载一个默认名称。然后我在与生产版本不同的上下文名称下运行开发版本,每个版本都会自动选择正确的配置文件。

                【讨论】:

                  【解决方案9】:

                  Mercurial 可以将本地文件添加到 .hgignore 并因此被忽略 - 这样它就不会弄乱您更改的文件或其他任何东西。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2018-02-01
                    • 2010-09-05
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-08-02
                    • 1970-01-01
                    相关资源
                    最近更新 更多