【问题标题】:Is there a way with Git to make future merges ignore version number difference in a pom file between branches?Git有没有办法让未来的合并忽略分支之间pom文件中的版本号差异?
【发布时间】:2015-08-05 02:21:06
【问题描述】:

我的团队正计划从 Perforce 切换到 Git,我正试图找到一种方法让 Git 忽略分支之间的 pom 版本差异。这在 Perforce 中运行良好,我没有运气用 Git 重现该行为。

这是我的步骤:

  1. 结帐父分支

    ndeckard@ws /c/dev/proj/testgit (master)
    $ git checkout release/1.0
    Switched to branch 'release/1.0'
    Your branch is up-to-date with 'origin/release/1.0'.
    
  2. 从中创建子分支

    ndeckard@ws /c/dev/proj/testgit (release/1.0)
    $ git branch branch/FEA-650
    
  3. 切换到新分支

    ndeckard@ws /c/dev/proj/testgit (release/1.0)
    $ git checkout branch/FEA-650
    Switched to branch 'branch/FEA-650'
    
  4. 更新子分支pom版本

    <version>1.0.0-FEA-650-SNAPSHOT</version>
    
  5. 添加并提交

    ndeckard@ws /c/dev/proj/testgit (branch/FEA-650)
    $ git status
    On branch branch/FEA-650
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git checkout -- <file>..." to discard changes in working directory)
    
            modified:   pom.xml
    
    no changes added to commit (use "git add" and/or "git commit -a")
    
    ndeckard@ws /c/dev/proj/testgit (branch/FEA-650)
    $ git add pom.xml
    
    ndeckard@ws /c/dev/proj/testgit (branch/FEA-650)
    $ git commit -m "set feature branch pom version"
    [branch/FEA-650 59e156e] set feature branch pom version
    1 file changed, 1 insertion(+), 1 deletion(-)
    
  6. 切换回父分支

    ndeckard@ws /c/dev/proj/testgit (branch/FEA-650)
    $ git checkout release/1.0
    Switched to branch 'release/1.0'
    Your branch is up-to-date with 'origin/release/1.0'.
    
  7. 将子分支合并到父自动接受的父分支版本中(使用“我们的”合并策略)

    ndeckard@ws /c/dev/proj/testgit (release/1.0)
    $ git merge branch/FEA-650 -s ours
    Merge made by the 'ours' strategy.
    
  8. 尝试第二次将孩子合并到父母中(已经是最新的。)很好。这就是我想要的

    ndeckard@ws /c/dev/proj/testgit (release/1.0)
    $ git merge branch/FEA-650
    Already up-to-date.
    
  9. 签出子节点并将父节点合并到子节点(它快进并将父分支 pom 版本粘贴在子节点上)。不好。我需要它像上面一样说“已经是最新的”,并保持子分支 pom 版本已经在子分支上

    ndeckard@ws /c/dev/proj/testgit (release/1.0)
    $ git checkout branch/FEA-650
    Switched to branch 'branch/FEA-650'
    
    ndeckard@ws /c/dev/proj/testgit (branch/FEA-650)
    $ git merge release/1.0
    Updating 59e156e..2f3a2a0
    Fast-forward
    pom.xml | 2 +-
    1 file changed, 1 insertion(+), 1 deletion(-)
    

在第 7 步之后,我想在父母和孩子之间的任一方向合并说(已经是最新的。)

Git 有没有办法让未来的合并忽略分支之间 pom 文件中的版本号差异?

【问题讨论】:

  • 你不能创建一个别名来检查差异,并且只有在有差异时才合并?如果没有发现差异,您可以输出任何您需要的内容。
  • 我从来没有处理过这个问题,但我看到了三种解决问题的方法:(1)完全忽略 POM 文件,并从元数据(分支等)自动生成它们; (2)使用涂抹/清洁过滤器插入和去除分支细节(这是1和3之间的中间方法); (3) 为此类文件编写自定义合并驱动程序。在实践中没有真正做到这一点,我不能说哪些方法真正有效或问题会是什么。
  • 关于 (1) - 完全忽略 pom 文件对我来说不是一个选项。我仍然关心合并这些文件中的其他行。关于 (2) - 我之前在文档中遇到了对涂抹和过滤器的引用,但没有深入研究。我不完全了解它们是什么,并将开始阅读它们以查看是否可行。关于 (3) - 我想避免编写特殊的合并驱动程序。将行差异标记为合并的功能是我通过 perforce 免费获得的,我想在 git 中找到类似的东西。
  • 您会考虑将部分版本计算从 POM 外部化的非 Git 特定解决方案吗?如果是这样,请添加到您的问题中。
  • Javabrett,您下面的解决方案看起来像是解决问题的一个不错的替代方法。放假后我试试。我仍然希望将我的版本保留在 POM 中,并让 VCS 跟踪这些行已经解决。 Perforce 按照上述步骤很好地做到了这一点,我认为执行此类操作的能力将是任何现代 VCS 的基本功能。

标签: git maven merge perforce pom.xml


【解决方案1】:

我最初的想法是通过部分外部化 POM &lt;version&gt; 计算来自动化您的 POM 版本号,请参阅答案。如果您不想这样做,那么您需要重新评估您的 Git 工作流程。

两种方式合并,进入master,然后回到特性分支会导致问题。您的 git merge branch/FEA-650 -s ours 使用 ours 策略告诉 Git 您已将功能分支中的 所有 提交和更改集成到 master,包括您的 pom.xml 版本更改,这丢失,master 保留其版本。 master 分支现在认为特性分支的 HEAD 是一个共同的祖先(它是合并时的父提交),所以当你将它合并回特性分支时,Git 说“当你合并到 master 时一切都已解决,没有变化……快进”。

简单的答案是你应该在合并到 master 之后重新分支到一个新的特性分支,给你的特性分支一个新的/以后最年轻的共同祖先,然后你需要以某种方式重放你的 POM &lt;version&gt; 更改。您不应继续在原始功能分支上工作,因为它已被合并。要从 master 获取新的更改,您应该重新分支。似乎有些暗示您可能在未与 master 合并的功能分支上留下了更改,否则您将不再需要它并可以重新分支,或者它可能只是您感兴趣的 &lt;version&gt; 更改提交.

有许多方法可以简化/加速/自动化重新分支时的版本号管理,从外部化(见下文)到 cherry-picking 从占位符分支,使用 Maven 插件,例如Versions Maven Plugin.

原答案

另一种方法是根据分支元数据或来自 CI 的其他输入从外部计算 POM 文件之外的最终/有效&lt;version&gt;。在 Maven 中执行此操作有点棘手,无需在结帐后自行预先设置 pom.xml,但请查看 Maven External Version Plugin

它与 Maven 生命周期挂钩,并将即时构建一个 pom.xml.new-version 文件(您可以 .gitignore),根据您提供的任何内容动态替换全部或部分版本号 - 功能分支名称、git commit hash 等。

构建/部署插件并将其添加到您的 POM:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-external-version-plugin</artifactId>
    <version>0.1.0-SNAPSHOT</version>
    <extensions>true</extensions>
    <configuration>
        <strategy hint="sysprop"/>
    </configuration>
</plugin>

...然后通过替换版本字符串获得创意,例如您可以:

mvn install -Dexternal.version-qualifier=$(git symbolic-ref --short HEAD| sed s_^master\$__)

...如果当前签出的 Git 分支是 FEA-650,这会将 1.2.3-SNAPSHOT 更改为 1.2.3-FEA-650-SNAPSHOT。您可能需要考虑在您的分支命名策略中将/ 替换为-,具体取决于Maven 的想法(我发现/s 令人困惑,但这只是我),或者相应地修改sed .

在最坏的情况下,这将允许您从 POM 中删除您的版本号,因此可以安全地合并其他 POM 更改并且已知与版本号无关 - 如有必要,您可以将版本号保留在另一个文件中,使用 Maven 属性插件加载它们并在需要时替换整个版本号。

【讨论】:

  • 这看起来是解决问题的一个不错的替代方法。节后我试试看。
  • 这个插件不能很好地与 maven-jar-plugin 配合使用。当我添加 maven-external-version-plugin 时,jar 插件会出现此错误(没有足够的字符限制来完整堆栈跟踪)。原因:org.apache.maven.project.artifact.AttachedArtifact.getVersion(AttachedArtifact.java:138) 处的 java.lang.NullPointerException
  • 在此之前我看到: [INFO] Building jar: C:\dev\code\myproject\target\myproject-4.0.0-EXT-VERSION-NATHAN-SNAPSHOT.jar 和 [ERROR]无法在项目 myproject 上执行目标 org.apache.maven.plugins:maven-jar-plugin:2.6:test-jar (默认):目标 org.apache.maven.plugins:maven-jar-plugin:2.6 的执行默认值:测试罐失败。 NullPointerException -> [
  • 命令行是:C:\dev\code\myproject>mvn clean install -Dexternal.version=4.0.0-EXT-VERSION-NATHAN-SNAPSHOT -e
  • 你的 mvn 版本是多少?外部版本插件要求最低 3.2.0。
【解决方案2】:

每次合并都这样做可能会很麻烦,但这里有一个想法。

git merge --no-ff --no-commit &lt;other-branch&gt;

git checkout HEAD -- pom.xml

第一个命令允许您在合并完成之前进行内容更改,即使没有任何合并冲突。第二个将 pom.xml 替换为当前分支上一次提交中的任何内容 - 有效地忽略了来自另一个分支的 pom.xml。

如果在 pom.xml 以外的任何文件中存在冲突,使用合并策略 --ours 是有问题的,所以我会厌倦将它用于此目的。

【讨论】:

  • 感谢您的回答。忽略整个 pom 文件的所有未来合并差异并不是我想要的。如果将来文件的其他部分发生变化,我仍然需要能够合并文件的其余部分,它会自动忽略这一行差异。
  • 在我要离开的版本控制系统中,每当我创建一个新分支时,下一步就是仅更改 pom 版本,然后更新合并历史记录,以便仅在内部进行该行差异pom 被标记为已合并。可以合并文件中其他行发生更改的后续合并,而此 pom 版本行遵循忽略版本差异的第一个合并的分辨率。我们自动化工具的很大一部分取决于能够将这样的单个行标记为合并。我需要 git 记住合并之间这条线的分辨率。
猜你喜欢
  • 2011-09-11
  • 1970-01-01
  • 2016-04-04
  • 1970-01-01
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多