Corrado's Blog 2.0

Online thoughts of a technology funatic

Using Git SubModules with Visual Studio

Disclaimer: I’m not a Git guru, so information in this post might not be the most accurate, it just works on my machine and wanted to share my experience.

I take for granted that you are a Visual Studio user, that you use Git using the Visual Studio plugin and, like me, have the need to work on projects where you need to share code hosted in its own separate repository among different solutions.
I know that there are several solutions for this, as example using Nuget packages for shared code, but none of them reaches the flexibility that using source code offers, both in terms of debugging and real time bug fixing.
Ok, not ‘technically correct’ I know, but it works, and I love things that works and make my life easier.
Since I’m not the only one with this need I checked online and found that, among different alternatives, the most voted one (with also several opponents indeed) is to use Git SubModules that, to make it simple, are nothing more than repositories embedded inside a main repository.
In this case, the submodule repository is copied into a subfolder of main one, and information about the original module are also added to main repository this means that when you clone the main project also all submodules are cloned.

Submodules in action
Let’s create our fist project that uses a git submodule, fasten your seat belt and enjoy the journey. Smile

I’ve created two UWP projects (but you can use any kind of project of course…) a main UWP application SubModulesApp and a UWP library named SubModulesLib, each one has its own repository hosted on github.com.
I now have the need that SubModulesApp must use some services contained inside SubModules lib and once I start using the lib, is evident that both repos will have a string relationship so, even if i could keep them separated and just reference local SubModulesLib project from main app, the best solution is to create a submodule, this also gives us the benefit to keep submodule on a different commit compared to the ‘master’ one in case we need it.

Let’s start and open our empty app in Visual Studio:

image

Now open a Visual Studio command prompt at solution folder, if you use Visual Studio PowerCommands, just right click the solution node and select Power Command –> Open Command Prompt.
Let now type: git submodule add <Path to your git repository> <foldername> and your project will be cloned into <foldername>

here’s an example of what I’ve got on my machine

image

and here’s project folder structure

image

Now you can add the Lib project inside MyAwesomeLib folder to SubModulesApp project

image

Consume the Lib services and push everything back to github.

Let’s now make an important test: What if lib author updates the code in SubModulesLib? will I get the changes if when I pull SubModulesApp?
To test it I’ve added a comment to MyCalculator.cs class and pushed the change back to original repository, I then pulled the SubModulesApp that uses the lib as submodules and, unfortunately, the change is not there Sad smile so, it looks like that what we get here is a copy, or, to better say, something not pointing to the latest commit.
To see the changes we need to open the solution from inside our nested folder (in this case MyAwesomeLib) and pull the changes from there, totally annoying stuff that could be avoided if Git plugin for Visual Studio would support multiple repositories (please vote for this feature here: https://visualstudio.uservoice.com/forums/121579-visual-studio-ide/suggestions/8960629-allow-multiple-git-repositories-to-be-active-at-on)
What about the opposite? If I do a modification of code inside a submodule, will it be pushed back to the original repository? (in our case from inside SubModuleApp solution) unfortunately not, as before you need to push changes from the instance of Visual Studio that hosts the SubModuleLib residing inside MyAwesomeLib folder Sad smile doing that properly aligns the original source repository.

All this works because we are working on the project where submodule was created, if someone else need to clone and work on the same project the following steps must be done:

1-Clone the project from Visual Studio (or manually if you’re an hypster…)
2-Open a VS Command Prompt at solution level and issue this command: git submodule update –init –recursive
3-Open each submodule under main solution, and checkout the associated branch using Visual Studio plugin (you will see that it results in detached state)

Now your cloned solution’s submodules are attached to original repositories and everything works as previously described.

A bit tricky for sure, at least until Visual Studio Git plugin won’t support multiple repositories. but once project is properly initialized is just a matter of remembering to open the submodule project each time you need to interact with git.

UWP Localization inside a library

Many of my blog posts comes from personal real world needs, since many of them requires more than just an internet search, when i struggle with some of them I try to share my experience with the online community.
The goal of this post is very simple at first sight: Localize a control that resides inside a control library and make the language used by the control different from the OS one (e.g. Control text in German while running on an English version of Windows)
The master of UWP localization documentation is this MSDN link, so I won’t add anything else since it will just result in a duplicate,
Following the MSDN documentation I’ve created two projects: A UWP client (LocalizationInLib) and a control library project (ControlLibrary) inside the latter I’ve created a Strings folder containing the default localization file Resources.resw and inside of it an additional “it” folder containing the italian translation of master Resources.resw content.

Here’s the project structure

image

and here’s what’s inside both Resources.resw files

Default
image

Italian
image

Nothing new until now if you read the previously mentioned MSDN link.

Let’s now define our simple MyTimer control in XAML and a SetLanguage method that accept the control culture to use.

This way we can invoke SetLanguage from the client application depending of what culture the user selected in main app.
We have now reached the core point of this post and what made me hit the head several times: what code should I use to load the proper resources at runtime? after many tests and investigations here’s what I ended up with:

Important detail is to use the proper namespace inside GetForViewIndependentUse otherwise the method will fail.
Just few lines of code, but took me some time to figure out how to properly combine them, so I hope this will help you in future.

Detect Application closing in UWP

Nearly every application when user closes it using the “X” button on upper right corner prompts something like this

image

Asking user if he wants to save actual work or cancel closing operation. 
Doing this in a UWP application is far from trivial, sounds strange uh? Smile

Despite some options are available (like CoreWindow esposes a Closed event but it never fires) the only available solution sounded to be this one which is unfortunately complex and unreliable. 
From Creators update (version 1703) a new class SystemNavigationManagerPreview  has been added and this class exposes a CloseRequested event (yeah!)
Ok, let’s see how it works, let’s fire up a brand new UWP app inside Visual Studio and let’s add this code inside MainPage.Xaml codebehind.

Let’s put a breakpoint inside OnCloseRequested method, run the app and try closing the window clicking the upper right “X” button.
The breakpoint doesn’t it right? so What’s wrong with that? nothing indeed, we just miss an important detail:  In order to work, you need to add a restricted capability inside package.appmanifest, the one we need is AppClose Confirmation that MSDN describes as: confirmAppClose restricted capability allows apps to close themselves, their own windows, and delay the closing of their app.

Ok, let’s manually edit the manifest file adding following lines:

Inside Package tag: xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"

then add rescap to IgnorableNamespacesAttribute: IgnorableNamespaces="uap mp rescap"
Then inside Capabilities tag:
<Capabilities>
    <Capability Name="internetClient" />
    <rescap:Capability Name="confirmAppClose"/>
  </Capabilities>

Very important: confirmAppClose capability must be listed before any optional DeviceCapability otherwise it won’t work.
Let’s  now try again and… yes! it works! Smile
You can now do whatever you want inside the OnCloseRequest handler, like showing a dialog and if user denies closing setting SystemNavigationCloseRequestedPreviewEventArgs.Handled=true to prevent app from closing.

Please take care of the note inside capabilities declaration page on MSDN:

Some of these restricted capabilities are almost never approved for apps submitted to the Store, except in very specific and limited circumstances. These capabilities are called out in the table below. We recommend not declaring these capabilities in your app if you plan to distribute it through the Store.

I see no reason why Microsoft should prevent this but take note and don’t forget to mention its use inside portal Submission options page

Install Windows 10 April update on Alienware machine

My main development machine is an Alienware 15 R3, a very powerful and nicely colored machine and, as many of you I wanted to install the latest release of Windows 10, the April 2018 update a.k.a build 1803.
Unfortunately looks like it was not possible because of this issue

image

A quick search on the internet and a hint from my colleague Emanuele lead me to the solution.

1-Get the update iso (i got mine from MSDN…)
2-Go to device manager and un-install device drivers from all of your graphic cards
3-Enable Airplane mode

Launch the installation and enjoy the April 2018 update Smile

Learning Git with Visual Studio #8

It’s inevitable, you or someone in your team make some changes and code doesn’t work as it should anymore and so is important to understand what has changed, when it has changed and maybe even who and why he made that change.
Since the team uses Git is easy to compare different commits and visually see what differs between them.
Let’s go to git history, let’s select the commits we want to compare and select Compare Commits…

image

Inside Team Explorer tab we’ll see a detail of what has changed including all files

image

Double clicking any of listed files I can see what has changes inside that file

image

Same result can be reached by selecting the file in solution explorer, right click, View History and then Compare

image

Of course is not necessary to Commit a file in order to compare it, you can compare any modified or staged file by just right clicking it and select Compare with unmodified menu

image

Of course comparison can be done between different branches as well

image

If you want to in deeper detail about changes related to a file, we can use the Blame (annotate) option, let suppose we did some changes to Program.cs  and we want to know who (and what) has changed that file, just select the file and select the menu Blame (Annotate)

image

A new window will open containing the content of the file and on the left the list of commits that changed those lines

image

To know what had been changed in a commit just click the commit, the changes tab inside Team Explorer will open, right click the file and select Compare with previous menu.

image

No rocket science here, but a feature used quite often during normal dev life Smile

Learning Git with Visual Studio #7

Until now, we worked with a local installation of git and everything was good but once we start working on a project together with someone else we’ll soon discover that we need a way to share our work with other members so working offline is no longer an option.
It’s now time to go online, and in this post we’ll use GitHub as service for host and share our projects.

In order to user GitHub we need to have an account, if you don’t have one, navigate to https://github.com and register:

image

once registration is completed, login and click Start a project button to create a brand new repository, fill form with your data

image

the click Create Repository to create it, after a moment you will have the uri to GitHub repository

image

Now is time to add to Visual Studio plugin the capability to connect to GitHub repository, if not already present go to Tools->Extensions and Updates, select Online on left column and using search box in upper right corner and type github.

The first result should be the extension you need:

image

Select it and click Download to install it, then restart Visual Studio to complete installation.

Now go to Team Explorer, click on the green plug in top toolbar and connect to your GitHub account

image

Sign in with GitHub credential to complete connection of Visual Studio to GitHub.
We can now create or clone a new github repository, let’s clone the repository we created before by clicking clone above GitHub connection.

image

we are now prompted with a list of our repositories, including the one we just created

image

select and click Clone, we’ll now have an empty GitHub project inside Visual Studio, time to add a blank solution using File->New->Project->Other Project Types->Visual Studio Solutions

image

We’ll now see our blank solution inside Solution Explorer

image

Time to add a new project, let’s add a Console Application Project, right click the Solution->Add New Project->Windows Classic Desktop->Console Application

image

and click Ok, the project will be listed under our solution now

image

From the “+” on the left of the items you will now recognize that items are added to local git repository but not committed, let’s add a comment and try to commit the changes

image

Wait! there’s a problem!, what are those files? we don’t need them to be tracked! but since we didn’t added a .gitignore file, git will track all files that are part of our solution.
Let add it before committing the project: In Team Explorer, click Settings->Repository Settings and click Add button next to Ignore File

image

If we now go back to Changes tab, we’ll see this status, and only files making up our solution will be now tracked

image

Let’s click Commit Staged to commit staged and the Commit to complete the commit phase.
Ok, our new project is now tracked by local Git, how to we sync with GitHub?
Let’s select Sync tab, we’ll see something like this picture

image

Let’s click Push to push changes to GitHub and let’s see how they appear on GitHub portal

image

It is an online copy of our local repository.
Let’s add a property to P1 to Program.cs, commit and push the change, we’ll now see the latest commit listed

image

Let’s make a branch dev, and let’s push it, if we have a look online we will see it listed under branches dropdown list

image

It is now evident that GitHub now acts as online hub for all push operation from different team members and relative pull operation when members need to retrieve changes pushed by other developers.
Of course, if two developers works on the same part of code during pull operation conflicts might happen and need to be fixed.
We’ll talk about that… Smile

Learning Git with Visual Studio #6

In previous post we talked a lot about branches and all the stuff involved (merge, rebasing, cherry-pick) but we didn’t covered a quite simple scenario: You’re working on a branch, and while in the middle of an important refactoring you’ve to urgently move to a different branch to fix a bug.
Answer is easy, commit changes and then checkout the other branch, but in this case we committed something that maybe doesn’t even compile, adding a sort of “ok, need to commit, sorry” entry into project history.
Git covers this need with a feature called Stashing, that is the option to ‘save’ your work without involving commit and retrieve it later.
Unfortunately this feature is not yet available into Git plugin for Visual Studio 2017, but with a little help from a 3rd party extensions we can stash changes without resorting to command line.
First of all, install this extension from Visual Studio Gallery.
The extension adds a new entry Stashes into Team Explorer home tab.

image

While on dev branch, let’s add a new property to Class2.cs and click Stashes, a new tab will open where we can add a comment and save current work.

image

Let’s click Create stash to confirm, we will see our change disappear and code revert back to last commit, don’t worry, nothing is lost.
If we have a look at Changes tab we’ll also note that there are no changes pending.
We can now checkout another branch, work on that and then go back to dev branch and click Stashes again.

image

Let’s now right click the Stash entry we want to load and select Apply stash option, this will get our changes back and we can continue working and, at the end, commit to history something that worth it and not clutter the history with meaningless commits.
Here’s the history after committing all changes, no trace of the temporary switch of branch,

image

When you’re no longer interested on a specific stash, just right click it and select Delete stash.

The extension sometime causes some Visual Studio slowness during stash/unstash operation but apart this small issue it works pretty well.

Learning Git with Visual Studio #5

In previous article I showed how to take changes from a branch into parent branch, visually we could imagine this operation like “copying” some files from a directory into his parent, but what if, while acting on a branch a colleague working on another branch fixes a bug or add a feature we need to get asap? What if we need to “copy” some changes from parent folder into the one we’re working on at the moment?
This operation is called Rebasing

Starting from the sample solution we’re using in this series of post, let’s move to Master branch and let’s add an empty MustHave.cs class, solution now looks like in following picture

image

Let’s commit this change and checkout the dev branch created in the past article, we’ll see that MustHave.cs class is not present, how can we have it, together with any related change happened on Master branch since we initially created the dev branch?
Checkout Master branch (or in general, the branch that contains the change you want to “merge” into your branch) go to Team Explorer, Branches tab, right click Master branch and select Rebase Onto… menu

image

You will be now prompted to indicated the destination branch where the changes will be merged, in our case the dev branch

image

Click Rebase and you’ll now see MustHave.cs class being listed into the project, so basically we can think Rebase being a sort of reverse Merge, a really nice to have feature especially when multiple people are working on different branches.

Cool but: We have included ALL changes, including maybe some that could conflict or break the branch we’re working on. What if I need to take just one or more commits, maybe from different branches, because very critical for what I’m working on and ignore the others?
Cherry-Pick is the git feature we need.

Let’s imagine, that while on dev branch, someone did a series of commits adding a NewFeature1.cs file, then a P1 property and suddenly a P2 property (of course in real world the changes would be more articulated)
The history for master branch now is:

image

While on dev branch, let’s now take single commits 193d63b4 by right clicking and selecting Cherry-Pick

image

You will get this confirmation message on Team Explorer

image

Let’s do the same with commit b46c2419, we will get a similar confirmation message, and the history of dev branch will now include both cherry-picked commits.

image

As you see, git offers several option for mixing and matching code residing in different branches, of course all have to be treated with care since the risk of overwriting changes is always around the corner.

Learning Git with Visual Studio #4

When you’re in a team and start working on a new implementation or when you just want to do some experiments with your code without worrying about introducing regression with actual code, the best thing to do is to use a git feature called Branching.
Branching can be considered a total independent copy of the last commit, so, since we’re on a copy, the original source remains safe and untouched.
While considered a copy, technically is not, because copying all files making up a solution would be not only slow, but also a total waste of disk space, so git handles all this internally, taking care of deltas, giving us the impression that we’re working on a physical copy.

To create a new local branch (we’re still working locally exclusively) let’s select Branches inside Team Explorer, right click the only branch we have now master, and select New Local Branch From…

image

name it dev and select Create Branch

image

This will create a new “copy” named dev and it will make it the default project we will work on, you can see what’s current branch and even switch quickly by looking at Visual Studio lower right corner

image

Let’s now add a new Class2.cs file and commit the change as usual.
If we have a quick look at the history we will see now a new Tag on the right indicating that that commit refers to dev banch

image

If we now, right click master branch and select Commit we will see that Class2 is not there, even on disk.
Let move back to dev branch and let’s add a property P1 to Class2.cs without committing and let’s try to switch back to Master branch.
We’ll see an error message stating that switching is not possible otherwise some changes will be lost, something that git tries to avoid anytime.

image

Let’s commit the change.
Let’s say we’re done with changes on dev branch and we want to bring them into master branch, together with any changes that might have taken place since we created the dev branch.
We can do that using Merge feature.
Right click the branch were we want to push the changes of the actual branch (master in our case) select checkout to switch to that branch, right click it again and select Merge From…

image

Leave the Commit changes option to commit the changes after the merge automatically.
Let’s have a look at Master branch history now

image

As you see you can’t see from the history there’s no trace that a merge operation occurred.
Let Reset the merge and let’s do it again but this time unchecking the Commit Changes flag.
This time we have a warning informing us that we have to commit changes to apply the merge

image

Let’s do it, giving a meaningful comment and let’s see how the history has changed

image

In this case the branch is evident including the additional comment we added after the merge.
If you like this option, as I personally, do, make it permanently unchecking it on plugin settings tab.

image

Learning Git with Visual Studio #3

In this post we’re going to talk about History.
In the previous post we saw how to commit changes so that git can track them, but without an history browser this list of changes wouldn’t be available and we couldn’t do anything regarding commit history.
Git of course let you see all commits history and so the Visual Studio Plugin of course.
From Team Explorer, inside the Changes Tab, select the Actions button and click View History

image

and the list of commits will open

image

Let’s now add a new Class1.cs file to our project, commit the change, then let’s add a property named P1 to the same class and commit the change again.
If we now refresh the list using leftmost button we will see two new entries

image

One of the interesting features of history is that we can see what has changed in each commit, just select a commit entry, right click it and select View Commit Details, the Team Explorer tab will change to Commit Details and will show all files involved, in our case just Class1.cs.

image

Double click the Class1.cs and a diff viewer window will open showing what has changed compared with latest commit in our case we’ll see that property P1 has been added.

image

If you want to compare two specific commits instead just select them and click View Commit Details.

Another interesting feature is Reset, with this option you can delete a series of commits and rollback to a specific point in history.
Right click the commit you want to reset to, select Reset and select Delete Changes, this will remove all changes committed after that point resetting your project to that exact moment.
Reset will remove all changes, including any file added that commit, so use it with care because your job will be definitely lost.
In my case the Reset Hard operation deleted the Class1,cs file from both the project and the disk.

image

under Reset menu there’s another option: Reset (Keep Changes).
After last Reset Hard I’ve re-added Class1.cs, committed, then added P1 property again and committed, putting the git history in the same status as it was before the Reset operation.

image

If I now right click commit with Id 0206669f and select Reset (Keep Changes) it looks like that nothing has changed since both Class1 and P1 are already there and if i add a new P2 property and I commit I see history changing appropriately and Class1 contains both P1 and P2.
Still not totally clear to me honestly, comments welcome.

If you want to delete a specific commit your can right click it and use Revert.
To understand how it works, let’s add P3 and P4 properties to Class1 committing each addition, thus generating following history

image

Let’s now say that we want to delete commit with ID a5aa04f5, right click it and select Revert, we’ll now see Team Explorer tab to prompt something like this

image

and if we click Merge will see that merge tool will try to remove P3 from Class1

image

Click Accept Merge in the upper left corner and P3 property will be no longer present in Class1.

What if you want to undo some modification did to a file returning it to last commit state? Just go to Changes tab, right click changed file, select Undo Changes… and you’re done.

image

Older Posts »