 Hi, welcome to Visual Studio Toolbox. I'm your host Robert Green, and on today's episode, we're going to look at Git. Git is a distributed version control system and has become very, very popular. So we're going to look at what Git is. We're going to look at how it works. As I'll say repeatedly throughout this episode, Git is plumbing. It's how the version control actually occurs. Then we're going to see how you can use it inside Visual Studio. We're also going to take a look at places where you can share code with others. GitHub, Visual Studio Team Services, both have great support for Git. You'd obviously expect GitHub to have great support for Git, but it turns out Visual Studio Team Services does as well. So we're going to look at some of the basics of Git. We're going to start out looking at the very, very high-level basics of what it is and how it works, and then we'll switch over to Visual Studio and run through some examples where we work with an actual project or two and see how to do source control using Git. This episode is going to be about an hour long, but I think at the end of it, you'll have a really good understanding of what Git is and how to use it. So as I said, it's a distributed version control system. The cool thing about that is it's not what we might be used to where we have a server which has the main version of our code, and then when we want to work with something, we have to go to the server, get code back. If we want to do a commit, we got to go to the server and get code back. GitHub is distributed, which means that everybody who's using it has locally a complete version of the source code and all of the history of commits and etc. So that means it's very, very fast because the bulk of what you're doing happens locally. It also means that you can work offline. So if you're on an airplane or a train or something, you can work with your code and then later on, move that code into a more central location to share with others. It also means that everybody has a backup of the entire system because it's all local. Now, Git is plumbing. So let's take a look at some of the basics of what you can do and for that, I'm going to use the command line. If you watch this show and know me, I'm not a big command line guy, but I think the basics of Git, that's the way to go. So I'm going to start off very, very simply. I have a folder, Git repos, and in that I have a command line folder, and I'm going to work with some code that's in here. So right now, Git repos backslash command line is just a folder. I want to turn it into a Git repo, which is short for repository. A Git repository is a place where you store code or something you're tracking and I've told Git that I'm going to have source code in here and I want you to track it for me. So to turn this folder into a Git repo, I'm going to run some commands. So I'm going to go out and go to my start menu and I'm going to use the Git command. There's Git bash, there's Git GUI. I got all of these when I installed Git for Windows, which I let Visual Studio install for me. I'm just going to use Git command because oops, I'm trying to move this, there we go. So first thing I want to do is move into this folder. So CD into that folder, which again, right now is just a folder. But if I say Git init, I have now created a Git repository. So a Git repository is now a folder. It's just a folder where I'm tracking the code I'm writing. What's in this Git folder? It contains a whole bunch of stuff. We're not going to spend any time looking in this, but this is the history of the project, all of the commits I've made. We're going to see later on that code actually gets stored in there, presumably in a very compressed format. But now I have a Git repository. Let's rearrange this so I can see both windows. There we go. So now I'm going to do a Git status. And we see I'm on the master branch. I did an initial commit when I created this and there's nothing to commit, there's nothing to do because I haven't actually written any code yet. Let's keep this really simple. I'm going to use a text file. I'm going to copy this myfile.txt file in here and now if I do a git status and spell it right then Git says, hey look, there is an untracked file in here. Git knows there's a file in here, but it also knows I'm not doing anything with it. It's not part of source control yet. If I want to start working with it as part of source control, then I do a git add. I add my file and now if I do a git status it says, hey there's a tracked file in there that is actually staged to be committed. So this file is now available to commit. So I'll do a commit. Git commit and the comment will be added my file. Okay, so now if I do a git status, nothing to do and if I do a git log, I do a git log, then I can see the most recent commit that I did. There's its unique identifier, who committed it and when. Okay, now I decide to keep working on these things. I make a change to my file. This is my updated file and then I'm going to add another file, my other file into here. And now if I do a git status, I can see that I have a new untracked file and then a change. It knows that I made a change, but it knows that I haven't staged it. It's not ready to be committed. So what I would then do is do a git add the changed file and my file, the file I added. Now do a git status and it knows that there are two files ready to be committed. I'll do a git commit, changes to files and now again, I do the status, there's nothing to do. I do the log, I can see both of my commits. Okay, so now I've been working with these files, they're perfect. Now I wanna share them with other people. So now I wanna take them off my machine and copy them somewhere where other people can work with them. If all I'm gonna do is work with these files myself, I can just leave them local, but I wanna share them with others. Couple places we can do this, we're gonna look in this episode both using GitHub as well as Visual Studio Team Services. GitHub is a perfect place to share code with others because it's free to create a GitHub account and it's free to create a public repository. So here's my GitHub, here's my GitHub, github.com forward slash rogreen. So here are some repositories, I like to share conference code here, talks that I've given at conferences. Gonna look at repositories I have and I'm gonna create a brand new repository to store the files we've been working with. So I'll go to new and I'll just call it foo. I'm not gonna make any other changes to it, I'm gonna create the repository and now it tells me, look if you want to push an existing repository, import code from another repository or work with this repository locally, here's some code. All right, so I have a local repository on my hard drive, that's here. I'm unable to find the one drive, yes I know. Because the one drive for business is trying to sync in the background, is trying to sync to my external hard drive which is not connected to this machine. So we'll just ignore that message. Anyway, we have our local repository here, we have our public repository in GitHub, we need to link the two together so I can then move the files from local to the GitHub repository and keep those in sync. So to do that, I could type the code or I could get clever and copy it from here. So now when I do a git remote add origin with that URL, what I'm now doing is linking up the local repository to the one sitting in GitHub. I can do a git remote-v for verify, and I can see that I'm actually linked up. Now, what I wanna do is copy these files that have already been committed locally. I wanna get those files into GitHub. So for that, I do a git push. And the comment here, this sample here tells me to do a dash u, that's optional. The dash u just has GitHub, I'm sorry, git remember where I've sent these two. So I'm gonna do a git push origin master which basically says take my local master branch and push it to the origin which is the master branch sitting up in my public repository. And when I do that, now if I go and look at code, there are the two files, okay? I can, let's see, go into these. I can look at the history, okay? These were committed, all right? So that's kinda cool. All right, so now I've got this code sitting up in git shared with others and so other people might make changes to it. So let's go into my file and let's edit this and this is an update to my updated file. I'm gonna commit that and now the version on the server is out of sync with the version locally because again, local doesn't automatically inherit these changes, okay? So now what I need to do is get the code from GitHub local so I'm in sync and there's a couple ways I can do that. The first one is using a fetch followed by a merge and then after that we're gonna see a pull. So if I say git fetch origin master, okay? Now what happens is if we look at this file, this is not the changed version. What git did was it brought down that file and it's storing it somewhere, somewhere in this .git folder but the version I'm working with hasn't been updated yet. To update it, I wanna do a git merge origin master which fails because it turns out that to do the merge you gotta say origin forward slash master, okay? Now my file, the local version has been updated to this update, okay? So you do a fetch to bring the changes down then you do a merge. Now you can short circuit this. So I'm gonna come up here and make another change to this. This is another update to my updated file. It changes. I don't have to do the fetch followed by the merge. What I could do is a pull git pull origin master which does a fetch and a merge at the same time and now this is another update to my updated file. So when would you do one versus the other? When would you fetch then merge versus pull? If you do a pull, it does a fetch and then does a merge and if there's a conflict then the pull just fails, right? If you do a fetch then you can kind of compare what's going on, if there's a conflict then you're gonna have to do a merge but you're gonna have to resolve the conflict. So if you know that there aren't any conflicts, if you just wanna get the latest version then you can just do a pull. If you think there might be conflicts or if you know there are conflicts so we'll see examples of that later on then you wanna do a fetch, resolve the conflicts and then do the merge. Okay, so and again just to review we did a git push to origin master then we did the git merge which requires the fetch, excuse me, we did a fetch which does not require, does not use the slash in between origin and master. We did the git merge which requires the slash then we did the pull which doesn't use the slash. So push, fetch, pull, don't use the slash, merge does and I actually don't know why. So if anyone out there knows why that's the case please put a comment in the show notes and educate us. Okay, so now we have a repository. We've synced the local to the one on the, in GitHub. Let's look at another way to do this. So let's go back to repositories and let's create another repository called foo2. And this time notice that while we're in here you can make private GitHub repositories but you need to have a plan with them that actually costs money, so we're just gonna stick to the public ones. So let's initialize this with a readme, right? Repos should have readme's, they should have these other things which we'll look at shortly. So let's create this with a readme. Okay, and now there's a readme file in there. Okay, so now what I wanna do is work with this same repo but I wanna have it point to the foo2 repository and not the foo repository. So what I'm gonna do, so I'm gonna say get remote remove origin and that breaks the connection between my local repository and the foo repository that we created earlier. And then what I'm going to do is do an add origin which hooks it up to the foo2 repository. Okay, so now this local repository is synced to the other repository, to the foo2 repository. Okay, so now I wanna get these files, my file and my other file up into here along with the readme. So I say get push origin master, they've already been committed and that fails, right? Rejected because the remote contains work that you do not have locally. The server version of this, the remote version of this has a readme that I don't have locally. So these two repositories, my local and the public one are out of sync. So I need to get them in sync. So I say, oh, all right, well, I'll just do a pull, right? Get pull origin master. Fatal or failed. Refusing to merge unrelated histories because these things are not in sync. The question is how do I get them in sync? They have unrelated histories. Locally I just have the two files. I have those two files but not the readme on the server and GitHub I have the readme but not these two files. They're unrelated histories. How do I marry these? And the way you do that is to do the get pull master. Two dashes allow unrelated histories. Okay, and now the readme's down. I've got the two files here and so now I can do a get push origin master. And if I come back to here, there we go. Now everything's in sync. So in a likelihood you're gonna create the repository then create the code. In this case, I was a little out of sync so I can get them back into sync by doing the allow unrelated histories. Now a third way to work with things is to clone a repository. So the repository exists in GitHub and I wanna start working with it. I don't have a local repository. So let's go to here. Let's create a third repository. We're gonna call it foo3. I'm gonna add a readme, okay? Then I'll create this. So now I'm going to clone this. So I'm going to go back up to the get repos folder and I'm going to say get clone HTTPS, R-O, green, oops, GitHub. R-O, green foo3.get. And that creates the foo3 folder and has the get folder in it and the readme. So now this repository is synced with the one on the server because that's where it came from. And so now of course I can do the things that I've always done. I can copy these into here. I can say get add my file.txt, my other file.txt. Get add, what did I do wrong? Remote, not a get, oh, of course not because I'm in the wrong place. I do this all the time, you'd think I would learn. Okay, get add, there we go. Now I do a get commit, m added files, and now get push origin, and now get add add add add add add add add add add. Master and now, and now those files get sent up to the GitHub repository. Okay, so that is at the very highest level, kind of get basics, not all of the basics of course, but those are basically basics of how get works. So we've looked at creating repositories, also known as repos. We've looked at getting files into source control. We've looked at committing and pushing things up. We've looked at pulling things down, and we now have a basic sense of how you work with GitHub to manage files. Now what we're gonna do is go into Visual Studio and see how it works inside Visual Studio because the get tooling in Visual Studio 2017, which is what I'm gonna use, is really really good. It's gotten better and better with each release. It's really good in 2017. Okay, so let's clean up a little bit here. We don't need this. We don't need this anymore because I'm done with the command thing. We're going to work with Visual Studio. All right, so let me launch Visual Studio. First thing I wanna do, I'm gonna create a new project, but the first thing I wanna do is create a get repo for it. I can do that in GitHub as we saw, but I can also do it inside Visual Studio. Okay, so what I wanna do inside Visual Studio is connect to GitHub. I do that over in the Team Explorer window, and Team Explorer is gonna connect to and give me the ability to connect to existing GitHub repos, local repos. So these are get repos that I have locally. It also shows me Visual Studio Team System projects that I belong to. All right, so what I'm going to do here is not connect to anything that currently exists. I'm going to click create under GitHub, and I'm going to create a repository called get test one, and I want this to be located in get repo so we're actually gonna need this back. I closed it a little prematurely. So we do need this, because I'm gonna create it right here, and then Visual Studio is automatically going to add for me a get ignore file. A get ignore file is a list of files that we don't want checked into source control. So anything in your bin folder or your OBJ folder, you don't necessarily want packages stored in source control. You typically just want the source. So the get ignore file is a list of things that won't get checked into source control. And then we'll choose a license. We prefer the MIT license for sharing code, so I'll use that. And now I'm going to create this repository. Okay, successfully created. Let's go out to GitHub and see if that's true. Here's get test one with a read me and a license and the get ignore. So the get ignore is just a list of all the things that aren't going to be checked individual studio, I'm sorry, checked into GitHub, and it's basically, again, the results of builds, all kinds of stuff in here. So we just want our code in there. Okay, so also Visual Studio has created the get test one folder, which is a get repo, and it has the get ignore, the license, and the read me. Okay, so now what we can do is create a new project. So I can create a new project or solution. I can click there, or sometimes what I like to do is double click on this to make sure that I really am connected to it, which I am. I'm going to create a new solution. We're going to keep this really, really simple. So let's just create a console app, and it Visual Studio knows to put it in get test one, knows to hook it up to source control. So let's say, okay, and build this. Okay, so we have program, we have nothing of terrible interest. I'm not going to add a lot to this. I just want to now commit this and get it into GitHub. So if I go to the changes tab here, I can see all of these files have been staged for committing. Now you can do everything all at once, or you could do things individually. Let's say I just wanted to stage the program file, program.cs, I can stage that, and then that will be committed, but nothing else. Or if I unstage this, now everything's ready to be committed, and that's the way I'm going to keep it for all of the demos. We're on the master branch, and I created the project. Will be my commit comment. You should always comment your commits. So I commit all, okay. Now I can see that I committed all because Visual Studio shows me that one author made a change. If I click on that, I can see this. Double click on it and go see more information on that commit. But what I want to do now is get this up into GitHub. So I will go to the sync tab. So I can do a fetch from here, I can do a pull from here, I can do a push from here, using the same commands we saw earlier. I'm just going to push this. Successfully pushed. So now if we go to GitHub, look at code. There's the solution, console one. I can look at the history and see that the commit, when I created the project, and I can come in here and I can look at all of the code in here, okay. I can also look at the history back in Visual Studio. So under actions here, I can view the history, all right, created initial commit when I created the repository, created project when I created the code and committed it. Okay, so now this code is local. It's also in GitHub and those are in sync. So what happens if somebody makes a change to this? So what we're going to do out here in GitHub is we'll edit this file. Code was added in GitHub. Gonna commit. And when I'm in GitHub, I'm always gonna not add a comment in here. Just, if I was doing this for real, I certainly would, but I'm not going to for the rest of this session. Okay, so now in Visual Studio, I of course don't see that because the local version I have does not have, my local version is what I originally created, doesn't reflect what's in up in GitHub. Okay, so now what I wanna do is a fetch. So I'm going to fetch master, which brings that down, but doesn't show it to me because again, it's sitting somewhere in that get folder. What I now wanna do is a merge. So to get to the merge, I go to the branches tab and here's the merge. So now I'm gonna merge from origin master. So this says merge, the contents of the master branch up in GitHub, which is the origin with the contents of the master branch that I have locally on my computer. And when I do that, I will see the comment here, okay? So now we go back into GitHub and make another change to this. Code was edited in GitHub. Commit that. Come back to Visual Studio. And now what I'm going to do in the sync tab is a pull. Again, that does the fetch and the merge all in one. And then of course, if I make changes, code was added in VS. Then I can do the commit and the push, which I can do from the Team Explorer, but I can also, we look down here in the status bar, this tells me that I have a change. So I can just click on that and go straight to the changes tab, edited code, do a commit. And then I can either click sync here or I can click this down here. They both do the same thing. It's just a question of my eyes are down here. I like these. If my eyes are up here, I use the shortcuts there. And then I push this and come back to GitHub. Now I've made the changes in Visual Studio. So again, if you're just working with the code yourself, you can keep it all locally. But when I put it into GitHub, it gives me the ability to work with others. I'm just sharing the source code with you guys. I may not want you guys to make changes. We'll see later on how I would allow that. But if or from working with a couple of you on a project, we could put the code in GitHub and then we'd all make changes. Typically, of course, we'd be making them from inside Visual Studio, but I didn't really want to have two different instances of Visual Studio up and running to do that. So it works just fine editing in GitHub. Okay, so now let's talk about the concept of branches. Master is a branch and a branch is typically associated with a feature or a particular grouping of code. The master branch is essentially the main version, but then we can create additional branches. So what I'm tasked with doing is adding a feature to this. So what I want to do is I want to create a branch for that feature and then that gives me the ability to work in isolation on that code until I think it's ready to be merged back into master. So to do that, I'll go to the branches tab. I'm going to right-click on master and choose new local branch from, and I'm going to give it a name, and I'm going to call it new feature one, and then create branch, and then I'm going to remember that you can't have spaces. So I'll just call this feature one. So let's create a branch called feature one. Okay, so now notice that it's highlighted. Now things I do, I'm working on that branch. So if I come into solution explorer here, and I add some code, here's feature one, and then I come back into program, and I say code to call feature one, right? Okay, so now what I want to do is commit these. I've made changes, added feature one. I commit this. I'm committing it locally to the feature one branch, and now if I push this, I've pushed this branch up to GitHub. So if we come to GitHub now, notice that in the master branch that files not in there, the feature one file's not in there, the code to call feature one's not in there, because it's not in the master branch, it's in the feature one branch, okay? So again, branches give you the ability to isolate the code you're working on, and then when you're ready, you would merge that into the master branch, and the process of merging that is called a pull request, which to me seems like an odd name since what I really want to do is push that code into the master branch, but it's actually called creating a pull request. So a pull request is a way of requesting, it is a request that I merge the contents of my local branch into the master branch in our case, or you could merge it into a different branch either way. Okay, so now in Visual Studio, I'm going to create a pull request, I will create a new pull request, I will call it feature one description, added feature one and it is spectacular. All right, so let's create the pull request. Okay, pull request has been created. Now, I go out here to GitHub and I look in pull request and indeed, there's a pull request called feature one. I can ask for reviewers, I can assign it to somebody, bunch of other things we can do, there's no problems here, there are no conflicts. So we now merge the pull request, confirm the merge, and now this has been merged into master. So again, if we're in master, we come in here, here's program.cs and here's the code, here's feature one CS and here's the code inside master to call it. So the changes I made locally in that branch have been merged into the master branch in GitHub, but they have not been merged into the master branch yet in Visual Studio. So what I now need to do is get my local master branch in sync. For example, if I come here, go to branches and go back to master, I don't have that code and I don't have the file because it's only in my feature one branch. So if I go back to feature one, there's that code. So locally, feature one has the new code. In GitHub, master has that code, but locally, master doesn't. So what I need to do is sync the two of those. All right. So what I'm going to do now is go into master, then I'm going to go to sync and I'm going to do a pull, and now I'm going to pull, I could do the fetch and the merge, but because I just made the code and I know there's no reason not to, I'll do the pull and now my master branch is in sync, local master branch is in sync with GitHub. Okay. So that's branches, that's pull requests. Now what happens if there's conflicts? There could be conflicts. Okay. So let's add some code to feature one. So I want to say public int add, and I say int x1 equals 1 and int x2 equals 2, and int sum equals x1 plus x2, and then I will return sum. Oh yeah, that's beautiful. Okay. So now let's push this. And I'm not using a separate branch right now. I will in the next demo. This is all going to be done on master. So I added the add method and I commit and then I push and life is good. So if we come out to GitHub and we look in feature one, there's the code I just wrote. Okay. So now someone else on the team comes in here and looks at this and says, hey, wait a minute. I thought we decided that we were going to use var whenever necessary, whenever possible. So changed int to var commits changes. That code is now official if you will sitting up in GitHub. In the meantime, I come in here and say, I could do way better here. So what I'm going to do is I'm going to refactor this. Let's pass this in and then let's do this. Turn that and there we go. Perfect. So now I say, let's commit that. Refactored add method. I'm going to stop worrying about typos. Commit, push, failed. What? I got output, failed with a fatal error. Now sometimes this fatal error happens because of a connectivity. That's not the error I was expecting. This is the error I was expecting. So sometimes it fails with a fatal error and that just means it couldn't connect. So try it again and we get the error we wanted. Isn't that odd? We got an error getting the error back. Rejected updates. Updates were rejected because the remote contains work that you do not have locally. There's a conflict. Git will try to do the push and to do the merging. But if it can't, if it can't figure out how in this case this conflicting code, then it fails. So now the question is, why? Why did it fail? What can I do about it? All right, well, let's see. Let's do a fetch. Let's get from GitHub the code that's up there. Well, that doesn't show me the problem because, again, the fetch just brings that code down and stores it somewhere. So what we saw earlier is we go to the branches tab and do a merge. So I'm going to merge from origin master into master and it tells me that it didn't work and then it shows me why. This is the code I wrote. This is the code somebody else wrote. They're kind of conflicting with each other. So I can click conflicts here. Double click on this and I can compare the files. So I have a choice. I can take the source and the source is what's up in GitHub. I can keep the target, which is what's local. And in this case, I'm going to say, look, my code, I'm keeping the target. Keep the target. Commit the merge. Resolve the conflict. Commit that. Sync. Push. Go to GitHub. And now I resolve the conflict by keeping my changes and completely overwriting the other person's changes. So sometimes that's how you're going to be able to resolve a conflict. One version of the code wins out over the other. But sometimes that's not going to work. So let's see an example of that. I've now been tasked with creating a new feature, feature two. So we'll come into Visual Studio. We can get rid of that. Let's go to branches. Right click on master, new local branch from master. And we're going to call it feature one. Oh, no, we're not. We're going to call it feature two. Much better plan. OK, so now we've got feature two. And I'm going to keep this nice and simple. I'm going to add code to call feature two. OK, so I'm going to commit this. Added feature two. Commit it locally. And then, of course, push it. So now what I've done is I've taken my local feature two and I've sent it up to GitHub. And there is now, I might have to refresh the page for that drop down to refresh. There we go, there's the feature two branch. Now in the meantime, somebody else has added feature three and has added code to call feature three, three. And committed that into master. So now what I want to do is a pull request. I want to get my feature two branch into master. So I come back into Visual Studio and I go to pull requests, create new, feature three, added feature three. And it is some of my best work ever. You always want to brag in the pull request. Create the pull request and that is going to work. There we go, latency. So now I come out here into pull requests. There's a pull request, feature three. This branch has conflicts that must be resolved. Conflicting files of program.cs. So you can open this in GitHub desktop or command line instructions and I don't want to do any of those. Resolve conflicts. I can see that there's a conflict. I'm not going to resolve this here. I want to resolve this in Visual Studio. The feature three was already had a pull request. So the owner of the project will come to me and say, yo, Green, fix the conflict before we do the pull request. I say, OK, let's do that. So again, what do I want to do? I want to see what the problem is. So I will come into branches. And in master, I need to get the local version of master down. So I'm going to double click on that to make that the local one. And then I'm going to do a pull, right? Is that what I want to do? Let's just make sure I get this correct, OK? No, I want to do a fetch. I want to fetch on master to bring it down, OK? Now what I want to do over in the branches tab is I want to merge from master into feature two. Because in order to send my feature to up, it needs to have the changes that were in master, OK? So I'm now going to merge from origin master, which is the updated version of what was in GitHub. Because remember, let's back up a sec. My local master did not have that change. My local feature two is exactly what I wanted. In GitHub, somebody made a change to master. So what I need to do is take that change from GitHub and get it into my local version of master so then I can then merge that into my feature two, resolve the conflict, and send it all back up. OK, so we're going to, we actually want to be in feature two here. We're going to merge from origin master into feature two. And now it tells me there's a conflict. I go to conflicts. I want to compare the files, OK? So I added code to call feature two. Somebody else added code to call feature three. I want both of this code, OK? So I can click compare files. And then I will click on the merge. And now notice there's a little check box next to this code. So I can here choose to keep both of the lines of code down into this, which is what I'll then send back. And the order I check confirms or controls the order that things get added. So I actually want the code to call feature two before the code to call feature three, right? Then I accept the merge, commit the merge, and now resolve conflict, pieces breaking out everywhere, sync, push, OK? So now the code in master, all right? Let's see what we've done. The code in master does not have my change, but the code in feature two has both of our changes. And this is what I now want to move into the master branch by the updated pull request. Or it's actually the same pull request, but now there are no conflicts. Now I can merge this, confirm the merge. And now if we go back into code, we go into master, we go into program. Now here's the code to call one, two, and three. And then all I need to do, once again, is go back into Visual Studio and go to branches. Double click on master to make sure it's the branch that I'm now working on. And then just do a pull. And now I am completely in sync. So that is kind of the next level of working with Git. We've seen how we do commits and pushes and fetch merge pull. We've seen how we deal with conflicts. We've seen pull requests and branching. We've actually covered quite a bit. We've done this all inside Visual Studio with GitHub. Now GitHub is a place that you can store code and work with Git. There are others. Because remember, Git is just plumbing. So there could be any number of public websites or private websites that use Git. GitHub is one of them. Again, it's great for sharing code with people because you can make public repos. And then people can easily view your code or download it. They just want them to look at it. Or if you want to be collaborative, they can, of course, clone the repository and then make changes to it via pull requests. So for example, the .NET core code or the entity framework core and a lot of our open source projects are run in Git. And you can do a pull request. And a pull request basically means that you copy the code down, if you will, make a change to it and then ask permission to send it back. And of course, in our case, those pull requests would be evaluated by the product team to make sure that it's code that we would want added back into the master branch. Any pull request has to be reviewed. You would have the ability to decide how rigorous you are in that. Presumably, you'd want only good code going in. Bit of a diversion. So that's GitHub. Another place to do this is Visual Studio Team Services. Visual Studio Team Services is not necessarily designed as a place that you share code with others. More designed to be a place where a particular product team collaborates and works on code. So they're more likely to be private reposed. And then there's another place, another website called Bitbucket. We're not going to talk about that here. But what I now want to do is show you how to do the exact same things we just did using Visual Studio Team Services. So if you're only going to use GitHub and you're not going to use VSTS, and you've made it this far, you can stop now. But if you're going to use VSTS, we're going to do the exact same demos. We'll go through them a little bit more quickly, because there's less explaining to do. But we now want to see how this works with VSTS. So I will go to my VSTS site, rogreen.visualstudio.com, which shows up as not authorized, because I am currently logged into this machine using my corporate account. And I created my VSTS site using my Microsoft account, which is our green 2005 at MSN.com. So I sign out as rogreen at Microsoft.com, sign in as our green 2005 at MSN.com, and now I can get to my Visual Studio Team Services sites. I have a bunch of projects in here. You can see that I've been practicing this. So we're going to create some code. Let's create a new project. Let's call it Git on Toolbox. Just to identify it. So the project name is GitDemos using VSTS. I can give it a subscription. And notice I have two choices for version control. I can continue to use Team Foundation Version Control. I can also use Git, which is now the default. So I'm going to create this team project using Git for version control. This is the equivalent step to creating the repository. Now VSTS also adds additional things like the ability to manage backlogs and queries with the Kanban board, the ability to do the DevOps stuff with build and release, continuous integration, continuous deployment. So VSTS offers out of the box quite a bit more than GitHub offers. You can get these things with GitHub, but out of the box, VSTS offers all of this stuff. OK, so now I can clone this inside Visual Studio from here. Or what I can do is pop over to Visual Studio, go to Team Explorer, go to the Connections, Manage Connections, and refresh this list. I'll have to show if it doesn't show up. So let's just go to Connect to Project. And now Visual Studio goes out and will find the Visual Studio team services projects I am part of. And it's in here. Somebody would we call it? What did we call it? Git demos using VSTS. That's the one. All right, let's connect to that. OK, we need to clone the repository. Again, we're just using Git. So all the things we do are going to be the exact same things we just looked at. So I'm going to put this in Git repos clone. And now if we come out to Git repos, there's Git demos using VSTS. And as you can see, it is, in fact, a Git repo. OK, so now we can create a new project, all right? So let's go here, go to the home page of Team Explorer. There we are. Now interestingly, this doesn't show all the same choices that we've seen before. Pull requests and other things aren't there. If I go to the home page, I'm sorry, if I go to Connections and I double click on this, Git demos using VSTS, now it looks more like what we're familiar with. OK, so now I'm going to create a new solution. Again, it's going to be a console app in the same places we did before. OK, changes, commit, created project. And again, I'm just going to go through these very quickly. Anything that's the same as we just saw, I'm going to move through fairly quickly. Sync, push. OK, now this code is sitting out in VSTS. If I go to Code, and I look at Files, there it is. Console app 1, ta-da, program.cs. OK, I can look at History. There it is, created the project. OK, I can come back into Contents and I can go into program.cs. And I can edit this. Code added in VSTS. Commit it. OK, back in Visual Studio, do a pull. I could do the fetch and the merge. I'm just going to do a pull. There we go. And of course, I can make changes in here. Code added in VSTS. All right, change. Added code. Commit, go to Sync, do a push. OK, come back to VSTS, refresh the page. There we go. OK, let's work with a branch. So let's come into Visual Studio, OK, and come into the Team Explorer, go to Branches, right-click on Master, new local branch from, call it Feature 1, create the branch. OK, now we're working in Feature 1. So I add a class, wanted to add a class, right-click, add class, thank you very much, Feature 1. OK, and then in program, code to call Feature 1. All right, so now changes have been made. Added Feature 1, do a commit, which commits again to the branch. Sync, do a push. I'm now sending my Feature 1 branch up to VSTS. So I can come out here, and there's Feature 1, which contains what I just wrote. And of course, Master does not yet, because I need to do a pull request. Come into Visual Studio, go to the home page here, create a pull request. You are not connected to a remote repository. Actually I am, do a pull request, which takes me to Visual Studio. So this is a little different linking the connection between Visual Studio and VSTS works a little bit differently here. So again, we're using the same plumbing, the same git plumbing underneath the hood, but the UI will be a little bit different. So when we were using GitHub, you created the pull request inside Visual Studio. When you're using VSTS, you create the pull request, takes you to VSTS. We'll see a couple other examples where the UI differs coming up. OK, so new pull request, added Feature 1, description added Feature 1, you can still create, you can still have reviewers, create the pull request. So now I can approve this explicitly from here, or wait for the author, approve it, suggestions, reject. These are all things that you can do in GitHub. So now we will complete this. Here's another difference. After you do a pull request, you can delete the branch. It's your choice whether you want to or whether you don't want to. When you're working with Visual Studio in GitHub, you automatically do not delete the branch. You'd have to go do it if you wanted it. In VSTS, by default, you do delete the branch. So we'll just leave this selected. We'll complete the merge. So let's just refresh the pages. Does this work? Yes, it worked. OK, excellent. It worked two minutes ago. All right, so apparently, apparently it didn't refresh the page automatically. Cool. All right, so now I go back into Visual Studio, and I move back over to master. So I've taken the feature one code, merged it into master, up in VSTS. Now I'm just going to do a pull and get that down into VSTS. So now VSTS and VSTS are in sync. Okay, what happens if there's conflicts? So let's go into feature one, and let's add that code. And I'm going to see if I can very quickly copy that, because I don't really feel like typing it all over again. It was in feature one. I like to use Visual Studio code to just look at individual files because it starts up faster than Visual Studio. Okay, so this is the old version of this. So int x1, oops, int x1 equals 1, int x2. I'm sorry, that was the new version of that, but it's still hopefully a little bit less typing. And then return sum. All right, so there's my code. Do a commit, added add method, commit sync to master push. Okay, cool. Now we come to VSTS. We go to code and in the master branch, we come down and somebody's looking at this and says, hey, I thought we decided that we were going to use var whenever possible. Okay, so I'll commit this. And the comment is changed into var, committed. All right, so now I'm back in Visual Studio, unbeknownst to me, somebody made that change at the same time that I was refactoring this, okay? And I now say, let's commit this, refactored add method. I commit, I push. Once again, the push fails. The push should fail for the exact same reason, the exact same error message comes back. Okay, so what do I do? I go here, oops, I could have done the fetch from there. I do the fetch and then I want to do the merge. So I go back to branches and I'm feature one or am I in master? I'm still in master, right? Yeah, okay, so now I do a merge from origin master to master, which fails, shows me why. I go to conflicts, do the merge, which shows the files. I say, keep the target, which is my version, commit the merge, resolve conflict, send it up, or commit it, excuse me, now do the push to send it back up. And I come up to here, do a refresh, my version goes up. Okay, and then the last demo we did was we created a pull, we created a branch, and then the pull request failed due to a conflict. So let's see that. Okay, we go to branches, right click on master, create a new local branch called feature two. Okay, and then what we did in program one code was we said code to call feature two. We commit that to two, and we pushed that branch, feature two branch up into VSTS. All right, while we were doing that in the main branch, somebody made what will wind up being a conflicting change to call feature three, commit. Okay, so now I want to create a pull request to get my feature two into the master branch, and create a pull request, added feature two, and feature two, and it is fantastic, unlike my typing abilities. Okay, create that, and no, not going to work. Conflict prevents automatic merging. Okay, so I can abandon this and ask me to go fix this. So I come back to here, what do I need to do? Again, I need to, the conflict is in the master branch in VSTS, that's origin master. So I need to get what's in origin master into local master so that I can then merge it into local feature two. Okay, so we go to branches, we go to master, we need to go to sync first and get a fetch, fetch into master, then go to branches, and then do a merge from origin master into, actually we wanted to merge that into feature two, excuse me, origin master into feature two, do the merge which fails because there's conflicting code. Conflict, click conflict, click merge, I want this code, I want this code, I accept the merge, I commit the merge, I've resolved the conflict, commit, push, up into VSTS, pop over to VSTS, reactivate the pull request, which can now be completed, there we go. And then finally, which look at the files just to make sure not that you doubted for even half a second that this didn't work perfectly, there we go. And finally, come back into Visual Studio and make sure that our master is in sync, so we change to master and we do a pull and we are good to go. So that's it, there you have it. That in a nutshell, in our long nutshell of course, is the basics of how you use Git. We looked at the basic plumbing of Git, what does it do? We looked at how you work with Visual Studio in GitHub using Git, we looked at how you use Visual Studio with Visual Studio Team Services using Git, and we saw that it's the exact same plumbing underneath, but the UI can differ as it might if you were to go use something like Bitbucket. So I hope that helps demystify Git for you, I hope you enjoyed that, and we will see you next time on Visual Studio Toolbox.