Github – Merge conflict and how to solve it

I recently contributed to one of Microsoft’s DSC resource modules via Github web interface (click on the file > edit > paste revised code > create pull request) as I’ve done countless times before. This time however I ran into a merge conflict that couldn’t be solved through the web site so I had to do it from the command line.

I contributed to the dev branch of the following repository and created a Pull Request:

  • Repository: https://github.com/PowerShell/xPSDesiredStateConfiguration
  • Branch: dev
  • Pull Request

There are countless guides on how to solve github merge conflicts but the ones I had a look at all presumed things that were missing in my case (see here or here).

So I clone my fork of the official xPSDesiredStateConfiguration repository and my default branch is dev:

PS D:\dsc> git clone https://github.com/megamorf/xPSDesiredStateConfiguration.git
Cloning into 'xPSDesiredStateConfiguration'...
remote: Counting objects: 713, done.
Receiving objects:  96% (685/713)   0 (delta 0), pack-reused 713 eceiving objects:  95% (678/713)
Receiving objects: 100% (713/713), 261.82 KiB | 0 bytes/s, done.
Resolving deltas: 100% (398/398), done.
Checking connectivity... done.
PS D:\dsc> cd .\xPSDesiredStateConfiguration\
PS D:\dsc\xPSDesiredStateConfiguration> git branch
* dev

Fetching updates from the upstream repo is required to update our fork but it fails because there is no upstream repository configured:

PS D:\dsc\xPSDesiredStateConfiguration> git fetch upstream
fatal: 'upstream' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

So I add Microsoft’s repo as remote upstream location (as you can see it’s listed in the git remote output) and update my fork’s dev branch with all the changes from the official repo’s dev branch:

PS D:\dsc\xPSDesiredStateConfiguration> git remote add upstream https://github.com/PowerShell/xPSDesiredStateConfiguration.git
PS D:\dsc\xPSDesiredStateConfiguration> git remote -v
origin https://github.com/megamorf/xPSDesiredStateConfiguration.git (fetch)
origin https://github.com/megamorf/xPSDesiredStateConfiguration.git (push)
upstream https://github.com/PowerShell/xPSDesiredStateConfiguration.git (fetch)
upstream https://github.com/PowerShell/xPSDesiredStateConfiguration.git (push)
PS D:\dsc\xPSDesiredStateConfiguration> git fetch upstream
remote: Counting objects: 38, done.
remote: Total 38 (delta 18), reused 18 (delta 18), pack-reused 20
Unpacking objects: 100% (38/38), done.
From https://github.com/PowerShell/xPSDesiredStateConfiguration
 * [new branch] TravisEz13-patch-1 -> upstream/TravisEz13-patch-1
 * [new branch] dev -> upstream/dev
 * [new branch] master -> upstream/master
 * [new tag] 3.8.0.0-PSGallery -> 3.8.0.0-PSGallery
PS D:\dsc\xPSDesiredStateConfiguration> git merge upstream/dev
Updating 171b484..e1cc5eb
Fast-forward
 .../PublishModulesAndMofsToPullServer.psm1 | 167 +++++++++++++++++++++
 DSCPullServerSetup/README.md | Bin 0 -> 2482 bytes
 .../MSFT_xDSCWebService.Schema.mof | 1 -
 .../MSFT_xDSCWebService/MSFT_xDSCWebService.psm1 | 146 +++++++-----------
 .../PullServerSetupTests.ps1 | 135 +++++++++++++++++
 Examples/Sample_xDscWebService.ps1 | 14 +-
 Examples/Sample_xDscWebServiceRegistration.ps1 | 14 +-
 Examples/Sample_xDscWebServiceRemoval.ps1 | 7 -
 README.md | 15 +-
 Tests/Integration/MSFT_xDSCWebService.xxx.ps1 | 36 ++---
 appveyor.yml | 4 +-
 xPSDesiredStateConfiguration.psd1 | 5 +-
 12 files changed, 384 insertions(+), 160 deletions(-)
 create mode 100644 DSCPullServerSetup/PublishModulesAndMofsToPullServer.psm1
 create mode 100644 DSCPullServerSetup/README.md
 create mode 100644 Examples/PullServerDeploymentVerificationTest/PullServerSetupTests.ps1
PS D:\dsc\xPSDesiredStateConfiguration> ise .\DSCPullServerSetup\PublishModulesAndMofsToPullServer.psm1

But wait, something is wrong here – my changes aren’t visible in the ISE. Instead, the file seems to be the one from Microsoft’s dev branch. So where did my changes go?

It turns out that editing a file from a remote repository through the Github web interface creates an entirely new branch in your forked repository called patch-#. What you have to do is merge the upstream repo’s changes with that branch and not the dev branch of your fork. Then fix remaining merge conflicts manually, add the affected files and commit with a descriptive message before you push it to your fork.

PS D:\dsc\xPSDesiredStateConfiguration> git checkout patch-1
Branch patch-1 set up to track remote branch patch-1 from origin.
Switched to a new branch 'patch-1'
PS D:\dsc\xPSDesiredStateConfiguration> git merge upstream/dev
Auto-merging DSCPullServerSetup/PublishModulesAndMofsToPullServer.psm1
CONFLICT (content): Merge conflict in DSCPullServerSetup/PublishModulesAndMofsToPullServer.psm1
Automatic merge failed; fix conflicts and then commit the result.
PS D:\dsc\xPSDesiredStateConfiguration> ise DSCPullServerSetup/PublishModulesAndMofsToPullServer.psm1
PS D:\dsc\xPSDesiredStateConfiguration> git add DSCPullServerSetup/PublishModulesAndMofsToPullServer.psm1
PS D:\dsc\xPSDesiredStateConfiguration> git commit -m "Merged patch-1 fixed conflict."
[patch-1 c77509d] Merged patch-1 fixed conflict.
PS D:\dsc\xPSDesiredStateConfiguration> git branch
 dev
* patch-1
PS D:\dsc\xPSDesiredStateConfiguration> git status
On branch patch-1
Your branch is ahead of 'origin/patch-1' by 10 commits.
 (use "git push" to publish your local commits)
nothing to commit, working directory clean
PS D:\dsc\xPSDesiredStateConfiguration> git push

Github will tell you in your Pull Request whether all merge conflicts have been solved.

Hope this helps 🙂

Advertisements

Best Practice – Git commit messages

Best practices:

  • The first line should contain 50 characters or less and explain the change very briefly.
  • The next paragraph should contain a bit more explanation about what you are trying to solve. Try to keep the length of the line under 72 characters; this way, it’s easy to scan people.
  • If you have more information that you want to tell, you can do so in the next paragraph. This can be as long and detailed as you want. More details are better!
  • If you want to create a list, use the – or * characters to do so.
  • When you’re working on an issue, add a reference to that issue in the last line.

An example of a nicely formatted Git commit message is as follows:

Show an error page if the user is not logged in

When a user is not logged in, we do not show an error message.
This was confusing to some users. We now show the correct error
message.

* Here is some extra information
* And here is some more bullet information

Fixes: #1123