My team is planning to switch from Perforce to Git and I am trying to find a way to make Git ignore pom version differences between branches. This works well in Perforce and I'm not having any luck reproducing the behavior with Git.
Here are my steps:
Checkout parent branch
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'.
Create child branch from it
ndeckard@ws /c/dev/proj/testgit (release/1.0)
$ git branch branch/FEA-650
Switch over to new branch
ndeckard@ws /c/dev/proj/testgit (release/1.0)
$ git checkout branch/FEA-650
Switched to branch 'branch/FEA-650'
Update child branch pom version
<version>1.0.0-FEA-650-SNAPSHOT</version>
Add it and commit
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(-)
Switch back to parent branch
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'.
Merge child branch into parent auto-accepting parent branch version (using the “ours” merge strategy)
ndeckard@ws /c/dev/proj/testgit (release/1.0)
$ git merge branch/FEA-650 -s ours
Merge made by the 'ours' strategy.
Attempt 2nd merge of child into parent (Already up-to-date.) Good. This is what I want
ndeckard@ws /c/dev/proj/testgit (release/1.0)
$ git merge branch/FEA-650
Already up-to-date.
Checkout child and merge parent into child (it fast forwards and sticks the parent branches pom version on the child). Not good. I need it to say "already up-to-date" like above and keep the child branch pom version as it already is on the child branch
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(-)
After step 7, I would like merges in either direction between parent and child to say (Already up-to-date.)
Is there a way with Git to make future merges ignore the version number difference in the pom file between branches?
The git merge command integrates the independent lines of development into a single branch. The command is used to combine two branches and also to merge multiple commits into one history. Once you make changes in the local repository and ready to share it with your team members, then execute git push.
No, merging does only affect one branch.
Recursive. This operates on two heads. Recursive is the default merge strategy when pulling or merging one branch. Additionally this can detect and handle merges involving renames, but currently cannot make use of detected copies.
My initial thought is to automate your POM version numbers by partly externalizing the POM <version>
computation, see further down in the answer. If you don't want to do that, then you need to re-evaluate your Git workflow.
Merging two-ways, into master
and then back into the feature branch causes problems. Your git merge branch/FEA-650 -s ours
using the ours strategy tells Git that you have integrated all commits and changes from the feature branch into master
, including your pom.xml
version change, which is lost, with master
retaining its version. The master branch now considers the feature branch's HEAD to be a common ancestor (it's a parent commit on the merge), so when you merge it back into the feature branch, Git says "everything was resolved when you merged to master, there are no changes ... fast-forward".
The simple answer is that you should re-branch to a new feature branch after merging to master, giving your feature branch a new/later youngest common ancestor, then you need to somehow replay your POM <version>
change. You should not continue to work on the original feature branch, since it has been merged. To pick up new changes from master you should re-branch. There seems to be some implication that you may have left changes on the feature-branch unmerged with master, otherwise you wouldn't need it anymore and could re-branch, or it might just be the <version>
change commit you are interested in.
There's any number of ways to simplify/speed-up/automate the version-number management on re-branching, from externalizing (see below) to cherry-picking
it from a placeholder branch, using a Maven plugin e.g. Versions Maven Plugin .
Original answer
Another approach would be to externally calculate the final/effective <version>
outside your POM file, based on branch metadata or other input from your CI. This is slightly tricky to do in Maven without pre-munging pom.xml
yourself after checkout, but take a look at the Maven External Version Plugin.
It hooks into the Maven lifecycle and will build a pom.xml.new-version
file on the fly (which you can .gitignore
), dynamically-replacing all or part of the version number, based on whatever you supply - a feature-branch name, git commit hash etc.
Build/deploy the plugin and add it to your 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>
... then get creative with replacing the version-string, for example you can:
mvn install -Dexternal.version-qualifier=$(git symbolic-ref --short HEAD| sed s_^master\$__)
... which will change 1.2.3-SNAPSHOT
to 1.2.3-FEA-650-SNAPSHOT
if the current checked-out Git branch is FEA-650
. You might need to consider replacing /
with -
in your branch-naming strategy, depending on what Maven thinks of it (I find the /
s confusing, but that's just me), or modify the sed
accordingly.
At worst this would allow you to remove your version-number from of your POM, so other POM changes can be safely merged and known to be non-version-number related - if necessary you can keep version numbers in another file, using a Maven Properties Plugin to load them and replace the entire version number if required.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With