Description
Key Learnings
- Learn how to create a repository for code projects
- Learn how to commit code and resolve conflicts
- Learn how to compare previous versions of files to see changes
- Learn how to create and merge branches while maintaining working code
Speaker
- BRBen RandBen Rand has been using AutoCAD software since Release 12. He learned to program using LISP in AutoCAD, worked his way up through VBA to VB.NET, and now spends most of his days programming in C# (occasionally still in AutoCAD!). He has worked in the Industrial Engineering field for more than 18 years as a CAD Manager, developer and IT Director. In 2013, he was the Top DAUG overall winner at AU, and he served as a mentor for the AutoCAD Mentor All-Star team. Ben has been presenting at AU since 2015, and was honored to appear on the Top Rated Speaker list in 2017 and 2018, and is a Pluralsight Author. Ben is the proud father of four children and enjoys reading and playing a variety of sports including pickleball, volleyball, and tennis. In 2018, Ben was a member of a USTA men's league team that placed 1st in the entire country.
BEN RAND: All right, I think it's time to get started. First of all, welcome to AU. I am thrilled to be speaking again this year. This is my third year of speaking. And I get to do it three times this year, so I'm pretty excited.
What I'm really thrilled about is how many of you signed up for this class. I really was not expecting this big of a turnout. So I'm really excited that you're here and interested in this topic.
So the topic is "Control Your Code-- Introduction to Source Control for CAD Managers and Programmers." My name is Ben Rand. I'm the Director of IT and CAD Manager and developer for Job Industrial Services. We do industrial engineering. So if you put a roof on it and walls, we probably don't design it. We just do all the ugly refinery and mining facility type stuff.
So lots and lots of stuff about me that you don't really care about-- I've been using AutoCAD since Release 12. I've started programming in LISP a long, long time ago. And I've moved my way up through all the variations of VB to C#. And that's what I primarily program in today.
The thing that will make me probably most memorable to you is three weeks ago, I was down in Florida with my USTA Men's League team. We were competing for a national championship. And we came in third.
[APPLAUSE]
Thank you, thank you. We were very proud of ourselves. We lost by two points in a third set tiebreak that would have got us into the finals, but anyway.
OK, so course objectives today-- we're going to learn all of the basics of source control, so that you can go back to your offices next week and get started doing this. Source control has been-- I didn't start out with using source control when I started programming. And it took me a long, long time to get to it, and to get it, and to understand why it's so important. But it's really a critical aspect. If you're writing code, and you're being paid to write that code, and it has any importance to you whatsoever, you should have it in source control.
So we're going to learn today how to create repositories for our code projects. We'll learn how to commit our code to the repository and resolve conflicts when we have other developers working with us, or even when we conflict with ourselves, which can happen. We are going to learn how to compare previous versions of the files and also how to create and merge branches. And I'll talk about more of what that means.
But my goal for you is to give you enough information that you will be able to go back to your office next week, and within about 15 to 20 minutes of getting some software installed, you can be ready to start using source control. All of the software that we're going to use today is free. And it's really easy to get started.
At the back of your handout, there's several appendices that walk through the installation of each of the applications that I'm going to be using. But they're all really very straightforward. So you shouldn't have any problem with that.
So let's start out with a little definition of what source control is. And I think the best definition is that it's a software system that keeps track of our files and folders, keeps track of changes to a set of files and folders over time. It is not language-- sorry, it is language agnostic. It does not matter what language you choose to program in. Whether you're a LISP programmer, whether you're doing C#, Java, it just doesn't matter.
What does matter a little bit is that, depending on the platform, whether you're using Windows or Mac, you may need to look at some different tools or different ones than I'm going to show. The tools I'm showing are specific to Windows platform primarily. And we're going to see the AnkhSVN plugin, which works inside of Visual Studio. But there are other Subversion plugins for Eclipse if you happen to program in that environment. There are tools out there for whatever your language and your IDE of choice is.
You could say that source control is a form of backup. But I think that's a really limited term for it. I certainly sleep safer at night knowing that if my laptop crashed and burned, died, all I have to do is download another version from the repository, and I'm going to get all my files back. So in that case, yes, it is a backup. But it does far more than that.
It allows us to "rewind" our entire folder system to any previous version of the file or the entire system. We can compare versions. We'll see some of that in the demo.
And one of the most important things is, if you're working in a team of developers, it allows you to synchronize changes between multiple developers. It gives us some capability to see who made a particular change. And also, it gives us tools to avoid and resolve conflicts.
So these are all important things. Another thing that it allows us to do is branch development. And we're going to talk about that, I think, in the next slide or in a couple of sides.
So some terminology that we'll need to understand. The repository is the central location that we're going to store our code in. So it's, again, kind of like a database, but not really.
But it's the central place that our code gets checked in to and checked out from. Preferably, that lives somewhere out on the network or definitely on a computer that gets backed up regularly. Because even though repository is a form of backup, we're still going to backup the repository itself.
A working copy is a copy that I would have on my desktop. And each developer in my team would also have their own working copy. So we can all be simultaneously working on the same codebase at the same time. And that's what we'll refer to as a working copy.
The trunk is-- if you think of your application and how you're developing it, you start out with a folder and a file in that folder. And eventually it grows to more files and maybe more subfolders. The trunk is just, basically, the whole line of development of your application over time.
So as you develop that, you have a release-- you know, like a release for production-- that occurs off of this trunk. And it just continues over time. And I've got a little animation that will hopefully help explain that.
A branch is a split-off of that trunk of development. So that we can do something, like explore development of a new feature, or do some kind of architectural rewrite that we know is going to take a long time-- several days, several weeks. Maybe there's some risk involved in trying to develop that particular feature.
Meanwhile, the trunk of our code, our application, may already be out in production. It has been released. And we have to do maintenance. We may add minor features to it. We might need to do bug fixes.
But we don't want the branch development to interfere with the main production code that we have out there in the wild. So a branch lets us explore that kind of stuff. And eventually, we can merge that back into the trunk when we're ready for the feature to be integrated.
A tag is-- I kind of refer to it as a twig rather than a branch. So a tag is, basically, just a kind of a copy within the repository of the code at a particular time. It's a snapshot, if you will.
And frequently, you'll see these associated with an actual version release, like version 1.0 of your app, or 1.1, or 1.2. But it's not intended for development. It's just intended as a snapshot-- here's how the system was when we released as version 1.0, in case we need to come back and take a look at the code at that particular moment in time.
So there are different terminologies depending on the type of source control system that you use. Update is the one that we'll use with Subversion, which we're going to use for the demos here. If you use Git as your repository of choice, fetch or pull might be the other terms. But they basically mean the same thing-- we're going to update the latest version of the code from the repository to our working copy. And then a commit is going the other direction-- or a push, in Git terms-- it's taking the changes that we've made in our working copy and committing those back into the repository.
So some common source control systems-- I'll just go really briefly through these. Git is extremely popular. There's a very good chance that you'll wind up using Git at some point. ADN team releases all of their demo samples through Git.
Subversion I have involved here just because that's what we're going to be using. I've just found it to be easy to use, easy to get started. The tools are all free. And so that's what we'll use here.
CVS is one of the oldest source control systems. Microsoft has Team Foundation Server and Visual Studio Team Services integrated with Visual Studio. Mercurial is another option. I think, as far as I know, Facebook uses Mercurial for their source control.
Autodesk Vault is the type of source control system. I don't know if it's particularly applicable for programmers. But it is a source control system for drawings, and Inventor assemblies, and that kind of stuff. So there is some cross over there.
So for this class, we're going to be concentrating on three pieces of software-- VisualSVN Server, which is our Subversion server; TortoiseSVN, which is a set of Windows shell extensions, that just plugs right in. You never actually run Tortoise. There's a bunch of Tortoise commands available any time you right-click in Windows Explorer or on your desktop. And we'll see lots of that.
AnkhSVN is a Visual Studio plugin. So it provides us the same Subversion commands right inside of Visual Studio and just gives us very nice integrated experience. So that's where we're going to be working on.
OK, so just a little bit about how trunks, commits, branches, and tags work. So if you think about how you develop an application, it, of course, happens over time. So the trunk, again, is our main set of of project files as we develop that over time.
As we go along and work with source control, we're going to be committing revisions to our source control system, to our repository. Each of these revisions gets marked with a number. The number isn't particularly important. They don't align with the release version of your software. It's just a number that signifies a change has been made to the system.
And it doesn't necessarily indicate that it's a change to a single file. You can certainly commit each file as its own commit to the repository. But if I go in and I'm working on a particular-- I work in WPF lot, so I might have a view and a view model that get created together. So that's at least two files that I would be committing into the repository. It's the entire set of changes that you've made since the last time you committed that gets put into the repository.
So as we go along, we might have multiple commits. At some point, we release version 1.0. We might create a tag there at this point. The tag, again, is not something that we develop off of. It's just a snapshot-- here's how the code was at version 1.0.
Meanwhile, we continue on the trunk committing changes, bug fixes, other maintenance. And at some point, we decide that we're going to start developing a new feature. But it's going to take us a few weeks to work out how this new feature is going to work. And so we might elect to create a branch.
So we can actually develop on the branch and the trunk in parallel. So we'll have commits kind of bouncing back and forth along there. We might have again a minor release back on the branch at version 1.1.
The branch continues to get developed. We do some more bug fixes in revision 10. And we can even do things like branch off of a branch if we have a complicated pipeline or some software that we really have to plan way out ahead of time.
At some point, we decide that the new feature branch is finished and we want to integrate that with the trunk and merge it back in. And then we'll release version 2.0 off of the trunk again. And that just goes on, and on, and on.
So I think the key thing with commits is once you start using source control, you really can't commit too often. I commit every single day. At the end of the day, all my code gets committed, no matter what.
Sometimes, if I have fixed a particularly nasty bug, I might commit a couple of times during the day. But at least, once every day. Because I always want to walk away from work knowing my code is in the repository.
I've had a situation where I had a contract developer working with me. And for some reason, he was really reluctant to commit code. And so he would go two weeks without committing code.
And by the time he committed his changes, I'd stomped all over half the files that he had worked on. And so we had major problems with conflicts when he would do that. And you really eliminate a lot of that if you do frequent updates and commits from the repository. So personally, I don't think you can commit too often.
One last concept I want to cover before we get into the demo is the HEAD revision. So each source control system has this concept of a HEAD-- I call it a marker-- that just keeps getting pushed to the latest commit in the repository. So as we move to commit, the HEAD marker moves along.
And when you download a copy or check out a copy from the repository, you're always going to be asked what version, what revision of the code do you want to copy to your machine. And almost always, it's going to default to the HEAD revision. Because that's the latest thing that's in the repository.
As we move along and get to a branch, something interesting happens in that the branch gets its own HEAD marker. So once you create a branch, those two lines of development really kind of operate on their own. Each one has its own HEAD version. And that just continues to alternate up until-- and that continues to function on the branch until we merge it back into the trunk.
OK, so we're going to go through a series of demos. The first half of the demos, I'm going to just be doing a LISP-based example. So how many of you have a folder called LISP out there on your network that's just crammed full of all the LISP files you've ever found in the last 30 years? I do too.
So we're going to work with a very simplified version of that. But I think it will be pretty applicable for you. And we'll learn how to create a repository, import the code into the repository, check that back out so we can work on it. I mean, I'd just go through these demo slides because I'll forget to come back. We're going to learn how to make changes, commit code, and then resolve conflicts, and look at how we can compare versions, what the log does for us, and how we can then export code out of the repository.
The second half of the demo will switch to Visual Studio, because I want to show the rest of you developers that are doing C# plugins or doing whatever other programming you're doing that we can use this on any other language. Again, it's language agnostic. It really doesn't care what the language is.
So we'll see the AnkhSVN plugin at work. And in the Visual Studio solution, we'll learn how to create a branch, do something called externals, and performing merges. OK, so let's switch over to demo time.
OK, so I have a folder on my desktop called LISP and SharedProject. We're going to import both of these into the repository to get started. And I'm going to use VisualSVN Server, which is just this little piece of software.
VisualSVN Server is, again, free to download. You can install this on a regular Windows machine. I would recommend in a regular Windows network environment that you put it on a server.
But it really consumes very few resources, so it shouldn't be a big deal. You do need some storage space for the repository. But it shouldn't be an overwhelming ask of your IT group.
So the first thing I'm going to do is create a repository for the code. So I'll just right-click on the Repositories node, maybe. OK, come on, demo.
OK, and we'll create a new repository. There's just a couple of questions about the repository type. We're going to go with the regular FSFS repository.
I need a repository name. The name of the repository can't have spaces in it. I don't know why it can't have spaces. But it can have non-file name characters. So underscores, dashes are OK.
This question is a little bit important-- do you want an empty repository or a single project repository? This might take you a little bit of experimentation to figure out what you like. Empty repositories, the recommendation-- I've done both. And personally, I would recommend going with the empty repository as well.
It just de-complicates how many repositories you're kind of juggling. But some of you may have an environment-- like if you are creating projects for multiple clients-- it might make sense for you to have a different repository for each client or something of that nature. But really, either way, it will work fine.
So Subversion has its own built-in permission settings. You can use Windows Active Directory groups and users if you want to. We'll just go with the default of using built-in Subversion users.
So create the repository. And it gives us a little URL that you can see up there on the screen. That URL is going to be important as we get into Tortoise because we need to connect Tortoise to that repository. But it's pretty easy to work out. It's just https followed by the name of your server, followed by SVN, followed by the name of your repository.
OK, so we have a repository, not very exciting. And basically, we're almost done with how much we need to interact directly with VisualSVN Server. Almost everything else we do from here on out will be done via Tortoise or the plugin in Visual Studio.
But there is one command that I kind of like inside of VisualSVN Server. And that is if I right-click and choose New, I can create a project structure. And the thing that I like about the project structure is that it will add branches, trunk, and tag folder just all automatically, so I don't have to go add that later on.
So I'm going to call this project Lisp. I'm going to move this down a little bit. Can you still hear me? Yeah, OK. Hopefully, that's not so much for the feedback.
So if I double click on Lisp, you can see branches, tag, trunk. Great, I'm going to create one more project folder in my repository. This is going to be for something we'll use later on, which is going to be the SharedProject.
OK, so at this point, I'm really, basically done with my interaction with VisualSVN Server. Under Users, I have a user set up, which is me. Creating a user in here is super easy. You just provide a username and password, really easy to do.
You can assign different permissions for a particular project. So if you have a large group of developers, and you want to assign some of them access to one project and other ones access to a different project, you can certainly control that. So there's that kind of control.
OK, so the next thing I need to do is we need to get code into the repository. So I'm going to right-click on the Lisp folder. And you'll see that my right-click menu has been customized because of Tortoise.
So I've got some options on here-- SVN Checkout and TortoiseSVN. So I'm going to go down to TortoiseSVN, and we're going to do an import. I apologize for the delays. I am running in a VM. And most of the time, it works great, and sometimes, it decides not to.
OK, so the URL of the repository-- I need to browse into the repository that I've set up. And I just need to select the project and the trunk. So all of the contents of my Lisp folder, whatever they are, they don't have to be LISP files.
It can be all those bitmap images that you have from your menu files and-- what else do you guys have in there-- [? CY ?] files and all that kind of stuff. All that can go into the repository, and it all can be source controlled. We can't necessarily do all of the things that we can do with some of the file types. But all of that stuff can get in there and be source controlled.
So we're going to copy the contents of the Lisp folder to the trunk, and we'll click OK. This message box-- every time we make a commit to the repository, you're going to be prompted for a message. It is not required, but I strongly recommend that you put some kind of a message in there indicating what it is that you're doing with that commit.
So I'll just put in "Initial import of lisp files" and say OK. And we'll get a little bit of feedback here saying that two files were added to the repository. And now in the repository, we're at revision 3.
I'm going to do one more import with SharedProject because I'll need this later. So we'll do the same thing. The only difference is that I'm going to navigate to the SharedProject trunk this time and give that a message.
So this is a little more extensive because this is a full C# solution. And so it's copied a lot, there's a lot more structure in there that has been copied up. Subversion doesn't care what it is you're copying in there. It's just files and folders.
OK, so the next thing that we need to do is we want to start working on a version to copy a working copy of the files that we put in the repository. So even though I just imported the files from my Lisp folder, they're not under version control yet. So in order to do that, I need to do SVN Checkout. I'm going to check out to a different folder. But I could check out into the same folder.
Now, you guys that are going to go home and grab your LISP folder and throw it into source control, I'm going to make a recommendation. Don't do this on the network copy that is in production. Make a copy on your desktop, import that into your repository, and then check out a working copy on your desktop, so you can test on your desktop and not infect everybody else with whatever you're doing. And I'll show you the end process of this when we want to check that out and put it back to the network.
So I'm going to do SVN Checkout. We're going to check this out to-- oh, and I need to change the repository. I just touched SharedProject last, so that's why it wanted to go there.
We're going to go to Lisp and then trunk, click OK. And we can give this a name. It doesn't have to be the same name as the project. So I can go in and say, I want this to be Lisp-star or whatever.
Notice here, under revision, that it's defaulted to the HEAD revision. So that's just the latest version that's in the repository, which is normally what you want. Click OK, and it's going to copy this out to a folder on my desktop.
You'll notice that it gets a little green check mark. That green check is Tortoise telling you, good job, you have all your code, it matches what's in the repository. And that will change as we start making changes to our code.
OK, so I'm going to open the folder up, hopefully today. OK, so the only thing that really changes here is you'll notice there's a .svn folder in there. So that's Subversion's way of keeping a copy. It's, basically, what Tortoise is going to use to check against to see if any files have changed.
It's actually a hidden folder. So I've got my hidden folders turned on. I highly recommend that you don't go in there and just don't touch anything.
If you really want to know what's going on, you can start looking around on those files. But I can promise you, it's not what you expect. It's really weird. Just leave it alone. It'll be happy, and you guys can get along.
OK, so we're going to go [? JIS Common ?] and make a small change. I've set my default editor to be Notepad++, which, if you're not familiar with that, it's a great editor for Windows platform. And I warned you this is not a coding class. So I'm not going to do anything very exciting, except change a comment.
OK, so we've made a change. I'm going to hit Save. And you'll notice that in my folder, all of a sudden, I've got a red exclamation mark on my file. That just means that I've modified a file, and it needs to be committed so that the repository is now up-to-date. So commits are pretty easy.
I'm going to strongly recommend and encourage you, number one, before you start the code every day, do an update. Before you commit your code, do an update. It will help you minimize the chance of having conflicts. Not eliminate them, but minimize them.
So I'm going to do an SVN Update. Nobody else has checked anything into the repository, so nothing really changes. Then I'm going to right-click and do an SVN Commit to commit my change back to the repository. So "Fixed ugly comment formatting."
OK, we'll say OK, and we'll get a little message indicating that one modified file has been sent back to the repository. And we're now at revision 5. So that's the basic sequence-- make a change; do an update, just in case there's a change; and commit that back to the repository.
Now, I want to take you through a little bit of a more advanced situation where I have two developers working on the project at the same time. So to kind of fake this situation, I'm going to make two more working copies to Lisp/dev1 and Lisp/dev2 Oops, sorry, that's really not a good option to click on the wrong thing.
OK, so I've got these two folders here. Let's open those up. And you're going to have to kind of pretend to imagine that I am two different people at the same time.
So we've got dev1 in the top, dev2 at the bottom. What we're going to do now is dev1 and dev2 are going to go into [? JIS Toolbox. ?] And they're going to make changes to the same file at the same time. But they're just going to happen to work on different lines of code.
Meanwhile, dev2 is also going to create a new file and add it to her working copy. So let's open these up. dev1 is there, dev2 is there.
OK, so dev1 is going to go in, and on line 48, we're going to do something like "Welcome to AU." And dev2 is going to make a change to a different line-- "Hello from the Venetian." So they both made a change, different lines in the same file.
And dev2 is going to go in and create a brand new file. And we're going to call this AuTools.lisp. And let's edit that and give it some copy-and-paste love. So this is just a little LISP function that toggles the wipeout frame on and off.
OK, so somebody in this scenario has to commit first. We'll say that one is going to commit first. So dev1 goes in, does an update, just in case.
Nothing's been committed to the repository yet. We'll right-click and choose Commit. And we'll say "dev1 made a change."
OK, so normally, in the messages, I would not include the developer name because Subversion is going to capture that already. That's going to be part of the data that gets sent to the repository. I'm just doing it here so we can keep track of what's going on, since I'm schizophrenic.
OK, so dev1 makes a change. That modified file gets sent up and committed. We'll right-click in here. And again, remember I recommend you always update before you commit. So let's see what happens. We're going to update.
The version that we have in dev2 is out of date. And it says that it's merged those files together, which is kind of interesting. So let's go back to Notepad++. And one of the things I really like about Notepad++ is that if a file gets changed on disk that you have open, it detects that change and says, do you want to open the new file? Sure.
So let's look at it. And you can see that line 48, the change from dev1, gets merged right in. So one of the powerful things about using source control is it's smart enough to recognize-- if you have changes on different lines of code within the same file, you can just merge them together, no problem. So that's pretty cool.
AUDIENCE: It's kind of scary at the same time.
BEN RAND: We'll see the scary part. The scary part is when you have changes to the same line that conflict. So we're going to see that. Hang on.
OK, so I need to commit the change-- "dev2 made a change." Now, there is a difference though here because dev2 added a new file to the system. So you notice that I have that box showing version files is checked on. So it's showing me the AuTools tools is a non-version file.
I want to get that to be a version file. So I'm going to check on that box next to it and click OK. And now it's a version file. So we can see that it added the new file, AuTools, at the top, it modified [? JIS Toolbox, ?] sent both of those modifications. And we're now at revision 7.
dev1 doesn't know about these changes yet. So dev1 needs to do an update. And as soon as dev1 does that, they get the modification for [? JIS Tookbox ?] and the new file, AuTools.
And if we go look in Notepad++, dev1's copy of [? JIS Toolbox ?] that I happen to have open at this time has been modified. So we'll click Yes. And we can see all the files have been merged together, and they're happy. That was the happy path.
Now we're going to do the conflicting path. So let's open up AuTools on both developers. And we're going to make a change to line 7 for both of them.
So dev1 is going to say, let's see, "Loaded AuTools." dev2 is going to say "AU is awesome." Whoops, that's not very LISP-friendly.
So both developers have made a change on the same line of code in the same file. That's not going to lead to good situations. OK, so we're going to save both.
Again, somebody's got to commit first. We'll just make dev1 the Guinea pig. So dev1 is going to go in, do an update, just in case. We're good, commit. And we're going to say "dev1 made a change again," not a very helpful message.
dev2 is going to do an update. And this time-- bam-- red text. Is there anything scarier than red text? No-- conflict, that's bad.
So we need to resolve the conflict. Subversion is going to see the same lines in two different files have been changed. And it is going to punt. It's up to you to fix your problem.
OK, so we need to have a way to resolve the conflict. Well, interestingly enough, Tortoise has tools built-in to do that. I can simply right-click right here in the results file, right-click on the red line of text. That's really scary.
I can right-click there and choose Edit Conflicts. And this is the preferable way to do this. But I want to show you what's going on behind the scenes. So I'm going to close this dialog box so you can see what else happened.
So if we look in dev2's copy, you'll notice that there's that file, AuTools.lisp, that has a yellow exclamation mark on it. Gasps of horror. But you'll also notice that there's these other three files in there-- AuTools.lisp.mine, and lisp.r7, and lisp.r8. So Subversion has copied these files in here so that we have some different files to work with and compare against.
So again, I'm just going to show you. This isn't really the way to resolve this problem. But if I go into AuTools, you can see that a bunch of weird garbage has been added in.
So there's this marker that's identifying what my change was, which is all of this stuff to there. And then there's a marker for r7, and then there's a marker for r8. So this looks ugly. You don't want to resolve conflicts using this. You could, but it's nasty.
What we do want to do is use some tools that Tortoise provides. So I'm going to right-click here and choose TortoiseSVN, Edit Conflicts. That's going to open up a program called TortoiseMerge, which is going to show us on the left side of the screen the last committed version-- theirs, whoever theirs refers to.
On the right side is my change. And at the bottom is the merged file that we're going to eventually wind up with. So it makes it very graphical, easy to use.
I've got to make a decision here whose code am I going to keep at this point. So we have a lot of options in here. But one of them is we could decide, OK, I like to have 2's changes better.
So I'm going to select that code in the mine file, right-click, and you'll see some of the options. So I can use that text block, I could use the whole file. I can use mine and then theirs, or theirs and then mine if we happen to make a change that we really do need both bits of the change. So we have options to do that.
I'm going to choose to use this text block this time. And you'll see that that gets copied down into the merged file. And then we'll hit Save, and it's going to prompt us that there's no more conflicts. So I'm going to mark that as resolved and close out of TortoiseMerge.
And when we do that, you can see that those other files get deleted right out of the system. They're no longer needed. But I do have a modified file that I now need to commit back to the repository. So we'll right-click and do a commit-- "dev2's changes when."
OK, we need to get that change into dev1's hands. So we'll do an update. And that's been successfully merged together, so everybody's happy.
So couple other things-- so we've learned how to resolve conflicts. At this point, I just want to take a look at a few other things that you can do with Subversion and looking at the log. So if I right-click in either working copy-- it doesn't really matter. In fact, I can just close out a dev2.
So if I right-click in the folder, go to TortoiseSVN, and choose Show Log, it will give me a log of all of the changes that have been made. And what's really great about this is there's a ton of information in there,. You can see in the author column who made the change. You can see in the message column what those messages are.
Again, I really recommend that you add a message every time you commit. It's really easy not to. But it's really helpful to have that message there.
There's a date and time stamp. So you can filter these by a particular date range. And as we click through on the different revisions in the log, you can see exactly what happened at each stage of the repository, so all of those changes through time. And you can see which files were affected.
Another thing that you can do is if you're more interested in one particular file, if you right click on that file, like AuTools, and go to the log, it will show you just the revisions in which that file participated. So you can see up here, in revision 7, that's the first time AuTools ever appeared in the repository. And then dev1 made a change in revision 8, dev2 reverted that change in revision 9. So some really powerful and nice stuff that you can do in there.
We can also at any point right-click and go to TortoiseSVN, and choose "Diff with the previous version." So we can see the differences between the file as it is now and the previous revision or any other version of it. So this gets really helpful, particularly if you have a code base that you may have released several months ago, and then you need to come back into it. And you don't really understand or remember what you did, or what some other developer did, and you want to see what those changes are, this gives you a really good way to do that. And it's incredibly helpful and powerful.
OK, so that ends the LISP portion of the discussion. And we'll go on to Visual Studio project. OK, so in here, I'm going to create a brand new project. This is going to be just a basic .NET plugin using C#, but it could be in VB.NET.
Sorry about this. OK, so we're going to create class library. I'm going to call the project or the solution MyPlugin. Did I say it slow enough? OK, so MyPlugin. I'm going to create a directory for the solution.
I do have a checkbox option here. This is part of AnkhSVN's integration with Visual Studio that I can add this directly to Subversion at this point. I don't want to do it right now, but I do recommend. And typically, you would want to just go ahead and add that to Subversion. I'm just going to show you a different route to get there.
But I do recommend that whatever project you start working on-- again, if you're being paid to produce that code or if it's of any importance to you, you need to get it in a source control as soon as possible. There's no downside to it, and there's really only upside. So we'll get it in there in just a minute.
So it'll create the solution, hopefully sooner rather than later. And this is really killing my timing. You would think for an empty project this wouldn't take that long.
Project created successfully. Let's see it in Solution Explorer. OK, we're almost there. OK, we're going to have to go fast for this.
So we're going to add some reference. So this is a .NET plugin for AutoCAD. I'm going to add some references.
My references are from the ObjectARX SDK. They're just the standard stuff. If you've done AutoCAD plugin programming before, it's the same stuff. So AcDbMgd, AcMgd, AcCore-- those were just pretty typical. Click OK.
When the references get added in, I need to set the property Copy Local to false. And we'll copy and paste some code. OK, you know you're in trouble when pasting half a page of code gets you in that much trouble.
OK, so just the brief highlights of this-- again, we're not really concentrating on C# or anything else, but just the basics of the plugin. It's a command method. So we've marked it with the attributes, so I can type in "Hello" at the command prompt to get this to run.
I access the editor, the command prompt, so I can write a message "HelloWorld." And then we'll prompt the user for a center point and the radius. And-- surprise, surprise-- we're going to use that information inside of the transaction with model space, and we're going to draw a circle, super exciting.
OK, so we've made these changes. I've set this project, the solution up. I now want to get this into source control.
So I'm going to right-click on the solution node in Solution Explorer. And we'll see that AnkhSVN, the plugin for Visual Studio, has added some right-click menu options. So I'm going to add this solution to Subversion.
It will prompt for the repository URL. So we'll select AU2017. That's the repository I created. I'm going to select that as my target. It's going to take this project name, MyPlugin, and appends that to the repository. You can see that down here.
And then I'm going to check that box at a trunk folder. So AnkhSVN recognizes that trunk, branches, tag thing. It's not something I just made up. And we'll add the solution into the trunk folder in the repository, click OK. Here's our "Initial import of MyPlugin" message.
OK, so the files get committed. There's a Pending Changes window. That is also part of AnkhSVN. It has a message box here, and the Commit and Update commands. So this makes it really easy to access.
I am not exactly sure why-- somehow, after we committed this solution file, it gets updated. And I'm not exactly sure why that didn't get committed. But we'll just say "Changes to SLN file."
And we'll go ahead and commit that. Oh, you guys are leaving right before the most exciting part-- the branch. You're going to miss out.
All right, OK, so we're about to start a branch. We're going to do something-- oh, wow, I'm going to have to really hurry. So we're going to do something kind of-- it's not dangerous. It's going to take a little bit of effort.
We're going to merge that SharedProject. So SharedProject has a library of little tools that I want to use in multiple AutoCAD projects. So I like to reuse my code as much as possible. And we want to get that project into the solution and then integrate some of the tools within that project within this amazing method HelloWorld that I just wrote.
So to do that, we're going to create a branch. Because we don't know how this is really going to turn out. We don't want to mess up our trunk, main line of development, until we've tested it and really made sure.
So I'm going to right-click on the solution, go to Subversion. Oh, actually, I'm doing OK. We're going to create branch solution or select branch solution.
We're going to go-- there's a couple of things that are important. So the folder just defaults to the folder where the solution is, my working copy. The URL we're branching off of is the trunk.
We're going to go from the HEAD version. And we're going to put this in a folder called branches. Again, not something I made up. But I do need to provide a folder name for this branch because I may have more than one branch.
So I'm going to do-- I don't think this is any kind of standard other than my own. I'm going to just put a number on there for branch number 1. And we'll call this ExternalProject. The message is "Branch to integrate SharedProject."
And I'm going to check this box "Switch to branch after creation." So what that's going to do is change my working copy from the trunk to the branch so I can just go right to work on my branch, really helpful. We'll click OK.
Nothing much happens because I haven't really done a lot. But you'll notice that in my Pending Changes window-- and let's keep this pinned for a little bit. So in my Pending Changes window, you can see that the URL to the repository is now switched over to that branch.
Nothing's really changed as far as the solution is concerned yet. But we are working on the branch. And when we commit, those commits we'll go to the branch.
So I'm going to right-click on the solution. So now what I want to do is I want to integrate SharedProject, which is its own solution project inside the repository. And I want to get that integrated with this other project that I have going on.
So I'm going to right-click and go to Subversion, and go to Solution Properties. And we're going to do something, and I don't really even know how to describe this. We're going to add this thing called externals. It's basically a way to reference something from another repository or another part of the repository and get that to merge in with another project.
The URL-- I need to go find my repository. I'm telling you, you guys are missing the most exciting part. I don't know why you keep leaving.
OK, we're going to go SharedProject, trunk. Now, I don't want the entire solution copied into my solution. I just want the SharedProject project, the .csproj part of it, merged in.
So I'm going to actually go down one step lower than the trunk to the SharedProject part. Does that makes sense? It's a Visual Studio thing. So click OK.
And the revision, if I leave that blank, is just going to default to the HEAD revision. So I don't really need to do anything, unless I wanted to go to a particular version. The name is going to be the name of the folder that shows up in MyProject solution. So we'll say SharedProject, and we'll click OK, and click OK.
Again, nothing actually happens until I click on Update. When I click on Update, it's going to copy SharedProject into MyPlugin solution. So if I go to File Explorer, you can see that SharedProject is in there. And it's even checked with the green checkbox because it's source control and we just copied the latest version.
My solution doesn't recognize it yet because I need to add the project, the existing project, to the solution. So I'm going to right-click on solution-- this is Visual Studio stuff-- and we'll choose Add Existing Project. Timing, timing, computer. I'm on the clock
AUDIENCE: He probably knows that.
BEN RAND: Yeah, I'm sensing it. So far we haven't crashed. We could throw that into the mix.
AUDIENCE: [INAUDIBLE]
BEN RAND: Ha-ha, I practiced this so many times. Hell, every time I need to hit Windows Explorer, it's just going crazy. OK, so Add Existing Project.
We're going to drill down into SharedProject to find the .csproj file. This is really just-- OK, so I just need to pick the .csproj file. That didn't have to be that much. And we should see that show up in Solution Explorer. There it is.
I do need to fix up some references. When I created this source file, these were pointed to my location on that machine. And when you guys download these sample projects, you'll need to do the same thing and point it to your version of the SDK.
So I'm going to remove those, add them back in. Come on. OK, add those back in. Oops, put it, pff.
[LAUGHTER]
Set those Copy Local to false. SharedProject should build at this point. I'm afraid to do that because of timing.
OK, so now I want to integrate the stuff that I have in my SharedProject with MyPlugin. So I'm going to right-click and add a reference. And we'll go to Projects, and there's SharedProject.
The code that we have in SharedProject is just one class called active. And this is something I took from Scott McFarlane's AU 2015 class. I highly recommend if you're doing AU plugin programming, go watch this class. It was awesome.
AUDIENCE: What class was that again?
BEN RAND: It's AU 2015. I have a link right in the sample file that will take you right to it. So there's just some static methods in here that gives us access to the editor of the document, the database, and most importantly, a couple of functions that, basically, set up the framework for using a transaction and sending any arbitrary code that we want to operate within that transaction. And then it will do all the commit stuff.
So it just takes a lot of boilerplate that every time you see a sample of AutoCAD code, you have to do the same thing with the transaction. And it gets really tedious. So this takes all the pain out of that.
And you'll see what a nice edit this makes. So I'm going to go back to my class. And so I need to add a using statement to use the SharedProject. OK, come on, editor, we got to fly. Let's go.
OK, so first edit, I can go down here to this editor line. Any time I need to use the editor, instead of remembering Application.DocumentManager.MdiActiveDocument, I can just say Active.Editor. Isn't that nice? Yes? Yes, that's really nice.
[APPLAUSE]
Thank you. I wish I'd invented it. OK, we will now go down to here. And this is probably the most amazing part.
So the thing that I want to have happened starts in that using bar circle equals new AutoCAD circle. All this other stuff is just fluff for starting up a transaction. So we can replace all of that with the call to Active.UsingModelSpace because I want to draw on model space.
And then we have to pass in a variable to hold the transaction and a variable for model space. And then we're just going to use a lambda function here. And I can get rid of those two nasty lines of code. And here is the block that I want. I don't even need these because these are already pre-baked into the UsingModelSpace method, also awesome.
We're going to append to model space and add to the transaction. And I don't need the transaction commit because that's already in there. The one thing I do have to do is because of the way I have the UsingModelSpace method set up, it opens up model space as read-only. And I need to do an ms.UpgradeOpen so that I can actually write to it. Oops, that's the method call.
OK, so that's the change. And then I've got to close my lambda call, and we're done. So you can see that that little modification just makes everything a lot cleaner. It still does all the same stuff. It's just wrapped up under UsingModelSpace, pretty cool.
OK so we need to commit that change. Remember, we're still on the branch. We can see down here in-- I guess, I should have just left that open. OK, so we can see all the files that have been changed.
So I'm going to say, "Integration of SharedProject." We'll click on-- we should do an update, just in case somebody modified the branch, which they haven't. And we'll click on Commit.
So very important-- before we commit or before we merge back onto the trunk, there's a few things that we need to do. We need to make sure that our changes are committed on the branch. OK, there we go. There is our first error.
OK, so we've committed our changes on the branch. We're done with the branch. We now want to merge it back into the trunk.
This is the most important thing if you're working with branches. We now need to switch back to the latest version of the trunk before we do the integration. We're not integrating from the branch to the trunk. We need to go from the trunk, pull the branch back in.
So Ankh makes this super easy because we have this little Switch Solution right here. So I click on Switch Solution, and we'll go to the trunk. Click OK, OK again.
It just basically replaces my working copy with the trunk copy. And you'll see, as soon as it gets done doing this, that the solution is going to change. SharedProject will disappear. And all my changes to class1 are going to disappear. They'll be reverted back to the way they were on the trunk, hopefully, in the next three minutes before class is over.
OK, so you can see that my project, my whole solution has been reverted back. So now I'm going to go to Update, click on the little arrow next to Update, and choose Merge Solution. It gives us a nice graphic, and a big explanation, and a lot of options.
The option we want here is to re-integrate a branch. We'll click Next. We're going to merge from the branch. So I have to switch this from the branch ExternalProject-- sorry, branch01. We're going to merge that into the working copy, which is right now on the trunk.
There's a bunch of options here for how you want to resolve conflicts. I'm just going to let it prompt for each and every conflict, if there are any. Hopefully, there are not.
We'll click on Next. We get a review. We'll click on Finish. And it's integrated all of those files, all of those changes back into the trunk.
Solution has changed because there's that new project in there. So I want to Reload All. And we'll see that the new version should show up in Solution Explorer. It does. And we're basically all done.
Now, we've merged the branch into the trunk. But now the trunk has been changed from the repository. We have changes there. So we need to do one last commit to get the trunk part of the repository updated with all of our changes. So "Reintegration of branch01 is complete."
OK, we'll commit that, and we're done. And we have one minute for questions. Let me put up some resources on here. OK, you've learned a whole bunch of stuff. Ready to go back to work next week, yes?
AUDIENCE: Yes.
BEN RAND: OK, awesome. See? OK, there's a bunch of links here and in the back of your handout. Those will get you started with VisualSVN, TortoiseSVN, and AnkhSVN.
There's a couple of resources on how Subversion works. If you want a really great course on how Git works, and I think by pretty close proximity how Subversion also works, there's a Pluralsight course called "How Git works." OK, I might be an ultra nerd in a room full of nerds, but it was fascinating. It's a really good course and really helped me understand how it works under the covers because it's kind of a mystery.
Please be sure-- my email address is out there-- please be sure if you have questions about any of this stuff, contact me whenever. David knows. He did the same thing last year, and he loved it.
AUDIENCE: Yes, I do.
BEN RAND: Please don't forget to fill out your survey after class. Thank you for coming.
[APPLAUSE]