Jump to content

Git Merge Errors

Recommended Posts

  • 42 years later...

Prepare yourself for a massive wall of text, but I'll try to cover some basic concepts and methodology in merging and patching your sources with Git. Don't expect this to be a step-by-step guide on how to do a merge. Rather, this will help you to understand better how to approach patching your MaNGOS source.

It helps if you understand C++ and have a general idea of how the code works that you wish to merge into your repository. With very large patches, such as Playerbot, the task of doing a merge can be overwhelming for those new to the concept.

I recommend starting with patches of a more manageable size, perhaps a couple hundred lines or less, to get a feel for what you're doing and familiarize yourself with using the git mergetool command for resolving source conflicts. You can direct Git to use whatever merge-diff utility you wish. I prefer Tortoise Merge for Windows. Perforce is more powerful, but it's also more complicated to use, which is something you might want to set aside in favor of a simpler tool until you're comfortable with patching your sources.

However, you can whittle a large merge down to size by applying some common sense. The first thing to look for when trying to decide which lines to use, the patch code or the code already in master, is differences in whitespace.

Whitespace is the term used for the way spaces are used when writing your code. As far as the compiler is concerned, it doesn't matter where the spaces are placed. However, Git and most merge-diff tools very much care about spaces and tend to scream "error!" when encountering differences in the way spaces are placed between one file and another. MaNGOS does have standards for how you should format your code. Unfortunately, everyone seems to have different ideas on where to put spaces when creating a patch or editing the source code.

You will find that 90% of merge conflicts are due to whitespace errors. This simply means someone put spaces in a different place for their patch than what is in your code. So long as there are no other differences between the line of code in the patch and the one in your code, you can safely ignore the difference in spaces and choose to keep your code while tossing out those lines in the patch.


theirs: this line of code i s thesame yours: this line ofcode is the same

Both lines are identical, except for the spacing. This means you can use either one without causing any functional changes in the final compiled version.

You can instruct Git to ignore or fix whitespace errors, making life a little easier:

Tell Git to ignore any spaces that have been added by theirs or yours. Will still give errors on other space differences.

git merge ignore-space-change

Tell Git to ignore all spaces, regardless of the number of spaces or where they are placed in yours or theirs.

git merge ignore-all-space

Tell Git to fix spaces on-the-fly as you do the merge:

git merge --whitespace=fix

The hard part is deciding when to use a line from the patch in place of your code where there are actual changes. Generally, a patch will add new lines for the expanded functionality it includes. This means you will have no corresponding lines of code in your source that match. In this case, you're probably correct in assuming you should add those lines from the patch.

Where things get tougher is if the patch deletes or makes changes to lines of code that you have in your source. Understanding what the patch is supposed to do can be a big help here. I recommend looking at the code in the Github repository of the patch you're wanting to merge into your source, specifically, the commit History. The commits listed will allow you to see the changes made, which can be very helpful in deciding if that line should also be used when you're merging the code in Git.

Here's an example of a commit from portal-zero, the Playerbot code for MaNGOS-Zero, that makes changes to /src/game/Creature.h:

@@ -331,10 +331,10 @@ struct VendorItemCount <--indicates the module and lines where the code is placed

struct TrainerSpell


- TrainerSpell() : spell(0), spellCost(0), reqSkill(0), reqSkillValue(0), reqLevel(0) {}

+ TrainerSpell() : spell(0), spellCost(0), reqSkill(0), reqSkillValue(0), reqLevel(0), learnedSpell(0) {}

- TrainerSpell(uint32 _spell, uint32 _spellCost, uint32 _reqSkill, uint32 _reqSkillValue, uint32 _reqLevel)

- : spell(_spell), spellCost(_spellCost), reqSkill(_reqSkill), reqSkillValue(_reqSkillValue), reqLevel(_reqLevel)

+ TrainerSpell(uint32 _spell, uint32 _spellCost, uint32 _reqSkill, uint32 _reqSkillValue, uint32 _reqLevel, uint32 _learnedspell)

+ : spell(_spell), spellCost(_spellCost), reqSkill(_reqSkill), reqSkillValue(_reqSkillValue), reqLevel(_reqLevel), learnedSpell(_learnedspell)


uint32 spell;

@@ -342,6 +342,10 @@ struct TrainerSpell

uint32 reqSkill;

uint32 reqSkillValue;

uint32 reqLevel;

+ uint32 learnedSpell;


+ // helpers

+ bool IsCastable() const { return learnedSpell != spell; }


typedef UNORDERED_MAP<uint32 /*spellid*/, TrainerSpell> TrainerSpellMap;

This is presented as a diff, which shows the [em]differences[/em] between the Playerbot code and the master code upon which it was based. You'll notice right away there are lines marked with a plus '+' and minus '-'. The plus lines means this code was changed or added by Playerbot. The minus means this was the original master code that was changed or replaced by the Playerbot code. So when you're doing the merge in Git, you'll know that the lines marked with a '+' in the above code listing should be used to replace the lines in your sources that match those lines marked with a '-'.

Another way to do this with Git is to create your own diff between Playerbot and the Zero master sources, then output it to a file so you can read over it to note the changes Playerbot makes:

git checkout master

git diff master playerbot>playerbot.diff

The above command will create a file named playerbot.diff, which should contain only the changes, or differences, in the Playerbot code versus the Zero master. It will be displayed in the same way as the example above, with '+' and '-' denoting changes and original code.

This assumes you have two branches in your MaNGOS-Zero repository, named master and playerbot, and the Playerbot code was built on the same version of the Zero master as your current master. If they weren't, you'll get unwanted "junk" code in your diff due to changes in the master code itself.

If you do find that Playerbot has older master code, you can still create a "clean" diff that has only the Playerbot changes. The simple way is to "roll-back" your master branch to the same revision as the master code used in Playerbot before executing git diff, by using git reset --HARD <commit number> on your master. Otherwise, you can specify the revision of master you wish to use for creating the diff of Playerbot with:

git checkout master

git diff <master commit number> playerbot>playerbot.diff

The <commit number> is the Git hash number used to identify the commit. In the above Playerbot code example, it was built on the Zero Revision [z1765] Provide class family mask for effect1 of spell 18271 and ranks, according to the History on Github. The commit number, or hash, that Git uses to identify this is cfdbd67a8e7772867fa50d9649f5f861d5470e1f.

I hope this has helped to clarify things for you. Please also read the stickies in this forum section as they have several useful guides and links to many online resources for learning more about using Git. There's also the Git Manual that comes with your installation of Git, formatted as plain-text and HTML. I know it's a lot of work, but you're going to have to spend time reading before you can just jump into things. When learning anything, you have to do your homework first!

Link to comment
Share on other sites

This topic is now closed to further replies.

  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use