1 00:00:00,000 --> 00:00:00,620 2 00:00:00,620 --> 00:00:02,579 SPEAKER: All right, welcome to this seminar. 3 00:00:02,579 --> 00:00:05,120 It's going to be about Git and GitHub, which are technologies 4 00:00:05,120 --> 00:00:07,724 that you can use to do what's called version control, 5 00:00:07,724 --> 00:00:09,890 keeping track of different versions of your program, 6 00:00:09,890 --> 00:00:12,260 testing out new changes, et cetera. 7 00:00:12,260 --> 00:00:15,845 All right, so before we get started, we'll do a quick introduction into kind 8 00:00:15,845 --> 00:00:18,759 of what Git and GitHub it is all about, and what it can be used for, 9 00:00:18,759 --> 00:00:21,050 and then we'll go more specifically into of the command 10 00:00:21,050 --> 00:00:24,260 line commands that you would use in order to use some of this technology 11 00:00:24,260 --> 00:00:26,570 and leverage it for projects that you're working on, 12 00:00:26,570 --> 00:00:29,030 or projects that you're collaborating on with other people. 13 00:00:29,030 --> 00:00:30,680 So first of all, what is Git? 14 00:00:30,680 --> 00:00:31,820 What can it do? 15 00:00:31,820 --> 00:00:34,280 The first, and one of the most important features for Git, 16 00:00:34,280 --> 00:00:36,960 is that it can keep track of changes to your code. 17 00:00:36,960 --> 00:00:40,030 So if you have code, you create a file, and maybe you're making changes, 18 00:00:40,030 --> 00:00:42,320 Git will keep track of all of the different changes 19 00:00:42,320 --> 00:00:44,570 that you've made to your code such that, at any point, 20 00:00:44,570 --> 00:00:47,227 you can kind of go back and see the history of whatever it 21 00:00:47,227 --> 00:00:50,060 is that you've been working on to see what were your earlier changes 22 00:00:50,060 --> 00:00:51,720 and when did you make those changes. 23 00:00:51,720 --> 00:00:54,303 And that can sometimes help when you're going back, and trying 24 00:00:54,303 --> 00:00:57,890 to debug, and figure out what went wrong at some stage in the code process. 25 00:00:57,890 --> 00:01:00,567 So that's one thing that Git can be useful for. 26 00:01:00,567 --> 00:01:02,900 Another thing that it can be useful for is synchronizing 27 00:01:02,900 --> 00:01:04,509 code between different people. 28 00:01:04,509 --> 00:01:06,800 Especially when you're collaborating with other people, 29 00:01:06,800 --> 00:01:09,980 Git is valuable for trying to make sure that your code potentially 30 00:01:09,980 --> 00:01:12,662 matches the code that someone else is working on. 31 00:01:12,662 --> 00:01:15,870 And at any point, absolutely feel free to interrupt me if you have questions. 32 00:01:15,870 --> 00:01:19,380 If something doesn't make sense, I'd be happy to field questions as we go. 33 00:01:19,380 --> 00:01:22,850 So imagine that you and a collaborator are both 34 00:01:22,850 --> 00:01:26,730 trying to work together on the same piece of code at the same time. 35 00:01:26,730 --> 00:01:29,099 So maybe that code lives somewhere on some server, 36 00:01:29,099 --> 00:01:30,890 and there are a whole bunch of servers that 37 00:01:30,890 --> 00:01:33,140 can host what we call get repositories, just 38 00:01:33,140 --> 00:01:36,320 folders that contain files that are tracked via Git. 39 00:01:36,320 --> 00:01:38,580 GitHub is one example of that. 40 00:01:38,580 --> 00:01:42,350 So maybe both you and your partner need access to the same file. 41 00:01:42,350 --> 00:01:45,011 Maybe you both make changes to that same file. 42 00:01:45,011 --> 00:01:46,760 And what Git allows you to do is Git makes 43 00:01:46,760 --> 00:01:50,300 it very easy to then take those changes that you both have made independently 44 00:01:50,300 --> 00:01:53,008 and then kind of merge them back together when you push them back 45 00:01:53,008 --> 00:01:56,760 online to the same file and then pull those back down to your own computers. 46 00:01:56,760 --> 00:01:58,700 So that you both have the latest changes, 47 00:01:58,700 --> 00:02:01,010 not only what you've changed on your file, but also 48 00:02:01,010 --> 00:02:03,620 what a potential collaborator has made changes to as well. 49 00:02:03,620 --> 00:02:06,860 And you both have the most recent, up to date version of the code. 50 00:02:06,860 --> 00:02:09,229 And so synchronizing code between different people 51 00:02:09,229 --> 00:02:12,800 is another really valuable thing that Git can be used for. 52 00:02:12,800 --> 00:02:15,950 A third valuable thing that get can be fantastic for is to test 53 00:02:15,950 --> 00:02:18,890 changes your code without losing the original. 54 00:02:18,890 --> 00:02:21,320 It's all too common that, before I started using Git, 55 00:02:21,320 --> 00:02:23,870 would try making changes to code to try to make it better 56 00:02:23,870 --> 00:02:26,469 and then suddenly find out that the code no longer works. 57 00:02:26,469 --> 00:02:28,760 And so my original solution to this was to do something 58 00:02:28,760 --> 00:02:31,347 like make a copy of my original file, save the old one 59 00:02:31,347 --> 00:02:33,305 and then make changes so that, if it messed up, 60 00:02:33,305 --> 00:02:36,230 I could go back to the original one and not lose the original. 61 00:02:36,230 --> 00:02:38,000 And that ends up getting very, very messy. 62 00:02:38,000 --> 00:02:40,640 Especially if you get into larger projects, and working 63 00:02:40,640 --> 00:02:44,300 with multiple people, you'll end up with a lot of different old versions 64 00:02:44,300 --> 00:02:46,100 and it might be hard to keep track of. 65 00:02:46,100 --> 00:02:49,730 So Git makes it very easy to save an original version of your code, 66 00:02:49,730 --> 00:02:51,792 test out new changes that you might want to add, 67 00:02:51,792 --> 00:02:54,500 and, only when you're sure that you like these changes, that they 68 00:02:54,500 --> 00:02:56,960 work that you want to what's called merge them 69 00:02:56,960 --> 00:03:01,010 back in with your original file, can you merge them back with the original file 70 00:03:01,010 --> 00:03:03,230 that you were working on in the first place. 71 00:03:03,230 --> 00:03:06,170 And the fourth and very valuable thing that Git can be useful for 72 00:03:06,170 --> 00:03:09,530 is for reverting back changes to older versions of your code. 73 00:03:09,530 --> 00:03:12,410 Say you made a change to your code somewhere along the way 74 00:03:12,410 --> 00:03:15,530 and realized later on that that's not the change that you actually 75 00:03:15,530 --> 00:03:18,490 wanted to make, and that you would want to go back to an older version. 76 00:03:18,490 --> 00:03:19,580 Git makes it very easy. 77 00:03:19,580 --> 00:03:22,100 As long as you know which version you want to go back to, 78 00:03:22,100 --> 00:03:24,770 you can just go back to that old version and kind of start 79 00:03:24,770 --> 00:03:26,940 over from wherever you were previously. 80 00:03:26,940 --> 00:03:29,840 So that's sort of an overview of kind of what Git is 81 00:03:29,840 --> 00:03:33,720 and the things that Git can do for you if you leverage its functionality well. 82 00:03:33,720 --> 00:03:35,840 And now we'll begin to go into the actual commands 83 00:03:35,840 --> 00:03:38,120 that you would need to use and need to type in order 84 00:03:38,120 --> 00:03:41,450 to make all of this kind of work. 85 00:03:41,450 --> 00:03:43,920 Questions Before we go on? 86 00:03:43,920 --> 00:03:45,500 OK, fantastic. 87 00:03:45,500 --> 00:03:47,960 So first command that will be really valuable to know 88 00:03:47,960 --> 00:03:49,744 is what's called git clone. 89 00:03:49,744 --> 00:03:52,160 git clone is a command you would type at the command line, 90 00:03:52,160 --> 00:03:54,034 and I'll show you how this works in a moment. 91 00:03:54,034 --> 00:03:56,210 And essentially, what git clone does is you 92 00:03:56,210 --> 00:03:59,990 type git clone followed by some git URL where 93 00:03:59,990 --> 00:04:05,420 that URL is the address of some GitHub repository-- and remember a repository 94 00:04:05,420 --> 00:04:09,740 is just a collection of files and folders that are being tracked by Git-- 95 00:04:09,740 --> 00:04:12,724 and it'll don't make a copy of that repository that lives somewhere 96 00:04:12,724 --> 00:04:15,140 on the internet, potentially on GitHub, but there are also 97 00:04:15,140 --> 00:04:17,060 other services that do similar things. 98 00:04:17,060 --> 00:04:20,209 And it will make a copy of that repository on your computer. 99 00:04:20,209 --> 00:04:23,300 So you can begin to make changes on your own computer. 100 00:04:23,300 --> 00:04:25,460 And side note, you can also do something called 101 00:04:25,460 --> 00:04:28,700 Creating a fork of a repository, where if someone else owns 102 00:04:28,700 --> 00:04:31,640 a repository online somewhere, you can fork it, 103 00:04:31,640 --> 00:04:35,600 which just means you create kind of your own copy of that repository that 104 00:04:35,600 --> 00:04:37,400 also lives online. 105 00:04:37,400 --> 00:04:39,740 But we'll get to that potentially later. 106 00:04:39,740 --> 00:04:42,770 So if this is Github, imagine this being some kind of server, 107 00:04:42,770 --> 00:04:46,040 and this is a file that's being tracked via Git in some Git repository. 108 00:04:46,040 --> 00:04:50,000 If I were to type git clone followed by the URL of that repository, then 109 00:04:50,000 --> 00:04:52,250 this file, I would clone it, and it would 110 00:04:52,250 --> 00:04:56,780 make a copy of the entire repository that is now saved on my own computer. 111 00:04:56,780 --> 00:04:58,220 Make sense? 112 00:04:58,220 --> 00:05:00,950 OK, fantastic. 113 00:05:00,950 --> 00:05:04,950 The next thing that's important to know is a command called git add. 114 00:05:04,950 --> 00:05:08,820 So git add is what you would do after you've cloned a repository 115 00:05:08,820 --> 00:05:11,490 and so now you have a copy of that repository on your computer 116 00:05:11,490 --> 00:05:15,330 and say you're making changes to that repository, changing the files, 117 00:05:15,330 --> 00:05:20,550 changing the code, and now you want to say that the next time that git 118 00:05:20,550 --> 00:05:23,850 saves a change to this repository, you want git 119 00:05:23,850 --> 00:05:27,460 to save the change that you made to that file. 120 00:05:27,460 --> 00:05:29,259 So let's show you what I mean by this. 121 00:05:29,259 --> 00:05:31,050 Let's say that we've just cloned this file. 122 00:05:31,050 --> 00:05:33,300 So this file now exists on your computer. 123 00:05:33,300 --> 00:05:37,047 It's being tracked by a repository. 124 00:05:37,047 --> 00:05:39,630 If I make a change to the code, maybe add a line to that code, 125 00:05:39,630 --> 00:05:43,470 and I want to say that, the next time you save a change to this repository, 126 00:05:43,470 --> 00:05:45,810 I want you to track that change, you would 127 00:05:45,810 --> 00:05:49,170 say git add followed by the name of the file, whatever 128 00:05:49,170 --> 00:05:51,340 that file happens to be named. 129 00:05:51,340 --> 00:05:54,720 And then, it would, say change is to be committed. 130 00:05:54,720 --> 00:05:59,340 And it would track that this is a change that you now want to make to that code. 131 00:05:59,340 --> 00:06:02,400 So let me show you what that looks really quickly. 132 00:06:02,400 --> 00:06:04,830 I have here GitHub repository. 133 00:06:04,830 --> 00:06:07,424 So they usually live at some link, like github.com, 134 00:06:07,424 --> 00:06:10,800 slash some user name-- my user name is [? BrianU28 ?] 135 00:06:10,800 --> 00:06:13,950 slash whatever the name of the GitHub repository. 136 00:06:13,950 --> 00:06:17,010 Is in this case, this repository is just called seminar. 137 00:06:17,010 --> 00:06:19,050 Up in the upper right hand corner, you'll 138 00:06:19,050 --> 00:06:21,300 see a button that says clone or download. 139 00:06:21,300 --> 00:06:24,000 And if you click on that link, it will give you 140 00:06:24,000 --> 00:06:27,000 a link that you can copy in order to clone 141 00:06:27,000 --> 00:06:29,440 this repository to my own computer. 142 00:06:29,440 --> 00:06:30,870 And so I could copy this. 143 00:06:30,870 --> 00:06:32,910 And then I could go in to CS50 IDE. 144 00:06:32,910 --> 00:06:35,910 And then, if I were to type git clone followed by that URL, 145 00:06:35,910 --> 00:06:39,870 it would clone the repository and save it to my computer. 146 00:06:39,870 --> 00:06:42,750 In this case, I've already done it, so I'm not going to do it again. 147 00:06:42,750 --> 00:06:45,570 But you'll see, here, I have this folder called seminar. 148 00:06:45,570 --> 00:06:51,610 And that folder is just my copy of the repository that exists on GitHub. 149 00:06:51,610 --> 00:06:53,610 So we'll take a look at the file that's in here. 150 00:06:53,610 --> 00:06:54,700 There's two files in here. 151 00:06:54,700 --> 00:06:57,000 But [? swap.c ?] is the one that I'm interested in. 152 00:06:57,000 --> 00:06:59,460 You might recognize this file from a previous lecture. 153 00:06:59,460 --> 00:07:01,350 It was just the file where we kind of set 154 00:07:01,350 --> 00:07:04,751 two variables equal to two different numbers in C, and we want to swap them. 155 00:07:04,751 --> 00:07:07,250 But what you'll notice here is that this code is incomplete. 156 00:07:07,250 --> 00:07:10,840 It says swapping right now, but we don't actually swap the values just yet. 157 00:07:10,840 --> 00:07:15,240 So what I'd like to do now is I'm going to change this code 158 00:07:15,240 --> 00:07:17,220 so that it actually swaps the two numbers. 159 00:07:17,220 --> 00:07:20,310 And then I want to git add those changes so 160 00:07:20,310 --> 00:07:23,460 that git knows that this is a new version of the file 161 00:07:23,460 --> 00:07:25,000 that I want to save. 162 00:07:25,000 --> 00:07:30,540 So I'll just quickly add the necessary code, 163 00:07:30,540 --> 00:07:33,730 and those three lines are going to swap the file. 164 00:07:33,730 --> 00:07:39,690 And so now if I cd into the seminar directory, what I can do 165 00:07:39,690 --> 00:07:43,200 is I can add the changes that I just made, 166 00:07:43,200 --> 00:07:46,870 and git will then track those changes so I can save them in the future. 167 00:07:46,870 --> 00:07:49,500 And in fact, one kind of little tip that might be helpful 168 00:07:49,500 --> 00:07:52,410 is that if I ever type [? git dif ?] at the command line, 169 00:07:52,410 --> 00:07:56,370 it will show me all of the changes that I've made that I haven't tracked yet. 170 00:07:56,370 --> 00:07:58,667 So I type git dif, and it shows me down here 171 00:07:58,667 --> 00:08:01,500 that these are the three lines highlighted in green that I've added. 172 00:08:01,500 --> 00:08:04,740 I added this in temp equals x, x equals y, and y equals temp. 173 00:08:04,740 --> 00:08:08,640 And those are now changes that, the next time I add a file, 174 00:08:08,640 --> 00:08:10,810 they're going to be tracked by git. 175 00:08:10,810 --> 00:08:15,720 So I can do something like git add swap.c, 176 00:08:15,720 --> 00:08:18,540 and that will add the swap.c file as a file 177 00:08:18,540 --> 00:08:21,130 that I now want to track the next time I save a change. 178 00:08:21,130 --> 00:08:23,430 So git add swap.c. 179 00:08:23,430 --> 00:08:28,060 And so that now has been added to the changes that I want to track. 180 00:08:28,060 --> 00:08:29,680 So what's the next step? 181 00:08:29,680 --> 00:08:31,860 The next step is called git commit. 182 00:08:31,860 --> 00:08:34,650 Once I've added all the files that I now want to save, 183 00:08:34,650 --> 00:08:36,870 now I need to actually make the Save. 184 00:08:36,870 --> 00:08:39,799 So git commit you might think of as the equivalent of telling git 185 00:08:39,799 --> 00:08:42,940 to save a version of this repository. 186 00:08:42,940 --> 00:08:44,880 So the syntax looks something like this. 187 00:08:44,880 --> 00:08:48,360 You would type git commit followed by -m, and then, 188 00:08:48,360 --> 00:08:50,100 in quotation marks, some message. 189 00:08:50,100 --> 00:08:53,910 And that message is just going to be usually some summary of the changes 190 00:08:53,910 --> 00:08:56,064 that you've made in this particular change 191 00:08:56,064 --> 00:08:58,480 so that if anyone were to go back and look at what we call 192 00:08:58,480 --> 00:09:01,480 the commit history, they would be able to see all the changes, 193 00:09:01,480 --> 00:09:04,020 and when you made those changes, and what changes you made 194 00:09:04,020 --> 00:09:05,760 at any given stage in this program. 195 00:09:05,760 --> 00:09:07,260 So that's what git commit is. 196 00:09:07,260 --> 00:09:10,830 And it saves those new revisions of a repository and kind of records 197 00:09:10,830 --> 00:09:12,120 a message along with it. 198 00:09:12,120 --> 00:09:15,090 And just as a side note, if you'd like to combine the adding 199 00:09:15,090 --> 00:09:17,550 and committing steps together into one step, 200 00:09:17,550 --> 00:09:22,740 this command right here git commit -am, a for all, or a for add, 201 00:09:22,740 --> 00:09:26,070 will automatically add all the files that you've changed, 202 00:09:26,070 --> 00:09:28,350 and also commit it with a commit message. 203 00:09:28,350 --> 00:09:31,447 So you can combine both of these steps together. 204 00:09:31,447 --> 00:09:33,030 So I'll show you what this looks like. 205 00:09:33,030 --> 00:09:37,440 When I type git commit and follow it by kind of a message suggesting 206 00:09:37,440 --> 00:09:40,950 what it is that I've changed, then what git will do is it will take my file, 207 00:09:40,950 --> 00:09:42,840 and it will save kind of a new version of it. 208 00:09:42,840 --> 00:09:45,360 It'll save this version, which says that I've added a line. 209 00:09:45,360 --> 00:09:47,280 It saves the message along with the commit. 210 00:09:47,280 --> 00:09:49,634 But it also still remembers that old version. 211 00:09:49,634 --> 00:09:52,050 Such that if I ever wanted to go back to that old version, 212 00:09:52,050 --> 00:09:53,430 I could still do that. 213 00:09:53,430 --> 00:09:55,830 So I'll show you what that looks like right now. 214 00:09:55,830 --> 00:09:57,790 So I'm back here, and I've made these changes. 215 00:09:57,790 --> 00:09:58,860 I've already added them. 216 00:09:58,860 --> 00:10:02,130 So I can do git commit -m. 217 00:10:02,130 --> 00:10:06,212 And then, in quotation marks, actually swap the values. 218 00:10:06,212 --> 00:10:07,920 And that's going to be my message saying, 219 00:10:07,920 --> 00:10:12,270 here's the change that I made when I just made these changes to the code. 220 00:10:12,270 --> 00:10:16,110 And so I see this what's called a commit hash, which 221 00:10:16,110 --> 00:10:18,180 is just an identifier about the commit. 222 00:10:18,180 --> 00:10:20,154 And it says I've changed one file and added 223 00:10:20,154 --> 00:10:21,570 three lines, which is indeed true. 224 00:10:21,570 --> 00:10:24,090 I added three lines to this file in swap.c, 225 00:10:24,090 --> 00:10:28,490 and those are the changes that I have just now saved. 226 00:10:28,490 --> 00:10:31,120 So what can I do now? 227 00:10:31,120 --> 00:10:35,170 git status is a helpful command, where, at any stage in working on a git 228 00:10:35,170 --> 00:10:38,590 repository, if you ever want to see kind of what's currently going on in the git 229 00:10:38,590 --> 00:10:42,310 repository, you can use git status to gain some kind of insight 230 00:10:42,310 --> 00:10:46,030 into what's currently happening, what are the changes that I've 231 00:10:46,030 --> 00:10:47,740 made to my current repository. 232 00:10:47,740 --> 00:10:51,040 And so the way that works is that if I were to type git status 233 00:10:51,040 --> 00:10:54,310 into the command line, I would see a message show up 234 00:10:54,310 --> 00:10:57,550 that says, what is the current status of my repository, 235 00:10:57,550 --> 00:11:01,300 and the message might look something like on branch master, 236 00:11:01,300 --> 00:11:05,050 and git ads has a feature which we'll get to in a moment called branching, 237 00:11:05,050 --> 00:11:08,380 which basically lets you keep track of different versions of your code, 238 00:11:08,380 --> 00:11:10,630 so you can have kind of different separate tracks of your codes. 239 00:11:10,630 --> 00:11:13,504 So if you want to test changes, or try and to implement new features, 240 00:11:13,504 --> 00:11:16,810 you can do that separately from kind of the main part of your code, 241 00:11:16,810 --> 00:11:20,410 where master we consider to be kind of the default code. 242 00:11:20,410 --> 00:11:24,640 And the second line here says, your branch is ahead of origin master 243 00:11:24,640 --> 00:11:27,820 by one commit, which is just kind of a fancy way of saying that, 244 00:11:27,820 --> 00:11:30,520 that version up here on the server, this version 245 00:11:30,520 --> 00:11:35,020 that we have is one commit, or one version, ahead of that version. 246 00:11:35,020 --> 00:11:38,470 So we've saved one change that the server up on GitHub 247 00:11:38,470 --> 00:11:40,360 doesn't yet know about. 248 00:11:40,360 --> 00:11:41,390 Clear so far? 249 00:11:41,390 --> 00:11:42,047 OK. 250 00:11:42,047 --> 00:11:44,005 And I'll show you exactly what that looks like. 251 00:11:44,005 --> 00:11:48,230 I can type git status right now, and it will tell me that exact same thing. 252 00:11:48,230 --> 00:11:50,745 I'm currently on branch master, and CS50 IDE 253 00:11:50,745 --> 00:11:53,620 is really nice in that it actually tells me, right here in my prompt, 254 00:11:53,620 --> 00:11:54,730 what branch I'm currently. 255 00:11:54,730 --> 00:11:56,260 I'm on the master branch. 256 00:11:56,260 --> 00:11:59,500 And it says that I'm ahead of origin master, which is the version that 257 00:11:59,500 --> 00:12:01,990 lives up on GitHub by one commit. 258 00:12:01,990 --> 00:12:04,840 So one revision ahead. 259 00:12:04,840 --> 00:12:09,880 So now, now that I'm one revision ahead, how do I then take those changes 260 00:12:09,880 --> 00:12:12,850 and, what we call, push them back up to GitHub so 261 00:12:12,850 --> 00:12:16,420 that the online version that can be accessible by anyone looking online, 262 00:12:16,420 --> 00:12:19,930 or accessible by collaborators who are also using the same online repository, 263 00:12:19,930 --> 00:12:20,920 can then see? 264 00:12:20,920 --> 00:12:24,460 And that git push is the comment that we would use. 265 00:12:24,460 --> 00:12:27,070 And so the syntax for that is just git push, which 266 00:12:27,070 --> 00:12:29,500 will send whatever committed changes we've made up 267 00:12:29,500 --> 00:12:31,660 to the remote repository up on GitHub. 268 00:12:31,660 --> 00:12:35,650 I can be very explicit and state exactly what branch 269 00:12:35,650 --> 00:12:38,890 I want to push to, as in git push origin master, meaning 270 00:12:38,890 --> 00:12:40,960 push these changes to the master branch. 271 00:12:40,960 --> 00:12:46,570 But generally, you wouldn't need to do this for normal purposes. 272 00:12:46,570 --> 00:12:48,610 So I would say something like git push, and then 273 00:12:48,610 --> 00:12:51,610 this new change, the change that I made on my computer, 274 00:12:51,610 --> 00:12:55,510 would then get pushed up to GitHub so that anyone looking online 275 00:12:55,510 --> 00:12:57,940 would then be able to see those changes that I just made. 276 00:12:57,940 --> 00:13:00,106 And so I'll show you what that looks like right now. 277 00:13:00,106 --> 00:13:01,136 If I go back here. 278 00:13:01,136 --> 00:13:02,260 So again, I did git status. 279 00:13:02,260 --> 00:13:04,930 I'm ahead by 1 commit because right now I've 280 00:13:04,930 --> 00:13:07,590 added these three lines that actually perform the swap. 281 00:13:07,590 --> 00:13:12,040 And on GitHub, if I were to look at swap.c, this is online on GitHub, 282 00:13:12,040 --> 00:13:14,500 swap.c doesn't have those lines right now. 283 00:13:14,500 --> 00:13:17,530 On the online GitHub version, it just says swapping. 284 00:13:17,530 --> 00:13:21,130 But if I go back into CS50 IDE, and I type in git push, 285 00:13:21,130 --> 00:13:24,340 those will push those changes back up to GitHub. 286 00:13:24,340 --> 00:13:26,860 And if I go back to GitHub and refresh the page now, 287 00:13:26,860 --> 00:13:29,890 I'll see that, indeed, these three lines that I just added 288 00:13:29,890 --> 00:13:31,360 have now been pushed up online. 289 00:13:31,360 --> 00:13:35,110 And if you actually go to github.com slash [? brianu28 ?] slash 290 00:13:35,110 --> 00:13:37,810 this whole link, you'll be able to see this exact same thing 291 00:13:37,810 --> 00:13:40,010 because this repository is public. 292 00:13:40,010 --> 00:13:42,850 So those changes have now been pushed online. 293 00:13:42,850 --> 00:13:45,190 Questions on how that worked? 294 00:13:45,190 --> 00:13:46,540 Fantastic. 295 00:13:46,540 --> 00:13:48,220 OK. 296 00:13:48,220 --> 00:13:52,760 So now git pull is another valuable command. 297 00:13:52,760 --> 00:13:55,040 git pull is kind of the opposite of git push. 298 00:13:55,040 --> 00:13:57,910 If git push means I made changes on my computer, 299 00:13:57,910 --> 00:14:01,240 and I want to send them up to GitHub so that the online version knows about it, 300 00:14:01,240 --> 00:14:05,290 git pul is GitHub contains a more recent version of the repository 301 00:14:05,290 --> 00:14:06,950 than I have on my computer. 302 00:14:06,950 --> 00:14:09,250 And I'd like to take those changes from online 303 00:14:09,250 --> 00:14:12,130 and pull them down onto my computer so that I 304 00:14:12,130 --> 00:14:14,710 can see the most recent version of the repository that's 305 00:14:14,710 --> 00:14:16,180 currently reflected on GitHub. 306 00:14:16,180 --> 00:14:18,160 And so the way that would work is, if someone 307 00:14:18,160 --> 00:14:20,500 were to make a third change to this repository, 308 00:14:20,500 --> 00:14:24,340 and my computer only had these two revisions to the repository, 309 00:14:24,340 --> 00:14:27,540 I could say something like git pull, and this third change 310 00:14:27,540 --> 00:14:31,110 to the repository that was added would then be pulled down onto my computer 311 00:14:31,110 --> 00:14:35,710 so that my computer now has all the versions that are matched on GitHub. 312 00:14:35,710 --> 00:14:40,460 So I've actually set up a second IDE workspace. 313 00:14:40,460 --> 00:14:43,330 So this version has all the changes we just made. 314 00:14:43,330 --> 00:14:45,080 In this version of my workspace over here, 315 00:14:45,080 --> 00:14:47,770 which is a completely different workspace, inside swap.c, 316 00:14:47,770 --> 00:14:51,100 I haven't updated it to the latest changes yet. 317 00:14:51,100 --> 00:14:52,632 Because I haven't done a git pull. 318 00:14:52,632 --> 00:14:54,340 So it still says swapping, and it doesn't 319 00:14:54,340 --> 00:14:56,060 have the latest version of the code. 320 00:14:56,060 --> 00:14:59,260 So if I want to pull from GitHub, get the latest version, 321 00:14:59,260 --> 00:15:02,260 I would cd into the seminar directory. 322 00:15:02,260 --> 00:15:04,510 And then I could say git pull. 323 00:15:04,510 --> 00:15:07,300 And so it will pull the latest changes from GitHub. 324 00:15:07,300 --> 00:15:11,310 And you'll see that it says, fast forwarding this swap.c file. 325 00:15:11,310 --> 00:15:14,050 It changed one file, added three lines. 326 00:15:14,050 --> 00:15:17,410 And indeed, if I go to swap.c now, that file that I just changed, 327 00:15:17,410 --> 00:15:19,630 you'll see that those three lines that were on GitHub 328 00:15:19,630 --> 00:15:22,390 but weren't on my computer before are now on my computer 329 00:15:22,390 --> 00:15:26,770 because I did git pull, and so those changes are now reflected there. 330 00:15:26,770 --> 00:15:28,570 Clear on that? 331 00:15:28,570 --> 00:15:29,597 Fantastic. 332 00:15:29,597 --> 00:15:32,220 333 00:15:32,220 --> 00:15:34,450 All right, let's talk about merge conflicts. 334 00:15:34,450 --> 00:15:38,314 This is the part of git that can often scare a lot of people. 335 00:15:38,314 --> 00:15:38,980 But don't worry. 336 00:15:38,980 --> 00:15:40,480 It's actually quite manageable. 337 00:15:40,480 --> 00:15:43,930 So here comes the question of, Git seems to be very good at automatically 338 00:15:43,930 --> 00:15:47,050 tracking what changes I've made to a file-- where I've added new files, 339 00:15:47,050 --> 00:15:51,460 where I've removed lines, I've added new lines to code. 340 00:15:51,460 --> 00:15:55,570 But what happens if I'm working on code, on a particular line, 341 00:15:55,570 --> 00:15:59,860 and I make a change to line 28, say, and some collaborator also 342 00:15:59,860 --> 00:16:02,490 makes a change to that same line, and we both 343 00:16:02,490 --> 00:16:05,781 try and push that code up to GitHub? 344 00:16:05,781 --> 00:16:08,530 Git's not going to be able to know what to do about that situation 345 00:16:08,530 --> 00:16:13,464 because it doesn't kind of which version of the code to believe, so to speak. 346 00:16:13,464 --> 00:16:15,630 So this creates what we call a merge conflict, when, 347 00:16:15,630 --> 00:16:18,320 in trying to combine two different versions of the repository, 348 00:16:18,320 --> 00:16:21,150 there's some sort of problem that Git can't automatically resolve. 349 00:16:21,150 --> 00:16:23,370 And so you, the programmer, need to figure out 350 00:16:23,370 --> 00:16:24,950 how to resolve that conflict. 351 00:16:24,950 --> 00:16:27,190 And so here's what that might look like. 352 00:16:27,190 --> 00:16:30,630 Maybe if you try and git pull, and you're pulling in new changes 353 00:16:30,630 --> 00:16:33,990 from GitHub, but those changes conflict with changes 354 00:16:33,990 --> 00:16:36,190 that you've made on your computer, you might 355 00:16:36,190 --> 00:16:40,810 get a message that looks like this-- conflict, the merge conflict failed. 356 00:16:40,810 --> 00:16:44,804 You need to fix the conflicts and then commit the result. 357 00:16:44,804 --> 00:16:46,720 And so this might be what your file would look 358 00:16:46,720 --> 00:16:49,020 like after you get this merge conflict. 359 00:16:49,020 --> 00:16:54,360 You might get a situation where you have a whole bunch of lines of code, 360 00:16:54,360 --> 00:16:58,210 and then this weird kind of series of less than signs followed by head, 361 00:16:58,210 --> 00:17:00,900 a bunch of equal signs, and then a bunch of greater than signs, 362 00:17:00,900 --> 00:17:03,900 followed by some weird sequence of numbers and letters. 363 00:17:03,900 --> 00:17:06,480 This is what a merge conflict might actually look like. 364 00:17:06,480 --> 00:17:09,480 And just to break this down for you, here's what all this means. 365 00:17:09,480 --> 00:17:15,369 Everything between head and the set of equal signs are all of the changes 366 00:17:15,369 --> 00:17:18,720 that you made that are in conflict. 367 00:17:18,720 --> 00:17:21,160 So changes that you've made on your computer. 368 00:17:21,160 --> 00:17:23,010 Everything between all of these equal signs 369 00:17:23,010 --> 00:17:26,440 and this series of greater than signs are all of the changes 370 00:17:26,440 --> 00:17:29,620 from GitHub that you're trying to pull down that are in conflict. 371 00:17:29,620 --> 00:17:33,430 So what happened here seems to be that the online version seems 372 00:17:33,430 --> 00:17:37,470 to have said in b equals 0, but my version, on my computer, 373 00:17:37,470 --> 00:17:40,830 I've committed, that b should be equal to 2. 374 00:17:40,830 --> 00:17:42,370 And those were the same line. 375 00:17:42,370 --> 00:17:44,760 So when git tried to merge those two together, 376 00:17:44,760 --> 00:17:46,600 it didn't know which line to go with. 377 00:17:46,600 --> 00:17:49,022 And so that's why we're getting this conflict. 378 00:17:49,022 --> 00:17:50,980 And this random sequence of numbers and letters 379 00:17:50,980 --> 00:17:53,280 right there is the conflicting commit. 380 00:17:53,280 --> 00:17:56,050 Every single commit gets a unique identifier, just 381 00:17:56,050 --> 00:17:58,660 a sequence of numbers and letters, and so this 382 00:17:58,660 --> 00:18:01,570 is telling me which is the commit from GitHub that 383 00:18:01,570 --> 00:18:04,720 is causing this conflict, that is the reason why I'm not 384 00:18:04,720 --> 00:18:06,530 able to merge these two together. 385 00:18:06,530 --> 00:18:08,710 And so what do you do in a situation like this? 386 00:18:08,710 --> 00:18:11,170 To resolve this merge conflict, all you need to do 387 00:18:11,170 --> 00:18:13,720 is get rid of this head line, the equal line, the greater 388 00:18:13,720 --> 00:18:17,550 than line, and then figure out what to do about these conflicting lines. 389 00:18:17,550 --> 00:18:20,440 You might delete one set and only use the other. 390 00:18:20,440 --> 00:18:24,790 You might somehow find a way to combine the two, but, in some way, 391 00:18:24,790 --> 00:18:28,330 you need to tell git what the actual version of the code should look like. 392 00:18:28,330 --> 00:18:31,860 So in this case, we might get rid of all the lines 393 00:18:31,860 --> 00:18:36,520 except for b equals 2 because b equals 2 is the version that I know that I want. 394 00:18:36,520 --> 00:18:38,300 You can get rid of the extra space there. 395 00:18:38,300 --> 00:18:40,150 And after that, I could commit this file, 396 00:18:40,150 --> 00:18:43,194 and now that would be the version that's saved. 397 00:18:43,194 --> 00:18:45,360 I've now resolved the merge conflict by specifically 398 00:18:45,360 --> 00:18:48,837 telling Git which version of the code that I want to use. 399 00:18:48,837 --> 00:18:50,920 So let's try and create a merge conflict right now 400 00:18:50,920 --> 00:18:53,650 so we can see what that looks like. 401 00:18:53,650 --> 00:18:58,770 In one version of my IDE, I'm going to take this x, which is right now 28, 402 00:18:58,770 --> 00:19:01,270 and I'm going to set it to-- pick a number, any the number. 403 00:19:01,270 --> 00:19:02,650 51. 404 00:19:02,650 --> 00:19:03,640 51. 405 00:19:03,640 --> 00:19:07,770 And I'm going to git commit am. 406 00:19:07,770 --> 00:19:11,410 And I'll say so, what I'm doing here is I'm adding this change that I just made 407 00:19:11,410 --> 00:19:15,810 and committing it, saying I'm going to change x to 51. 408 00:19:15,810 --> 00:19:16,920 So I've made that commit. 409 00:19:16,920 --> 00:19:19,320 It notes that I've only changed one file. 410 00:19:19,320 --> 00:19:21,100 It says one insertion, one deletion. 411 00:19:21,100 --> 00:19:25,630 What that means is I deleted the line that says int x equals 28, 412 00:19:25,630 --> 00:19:27,614 and I added the line that says int x equals 51. 413 00:19:27,614 --> 00:19:29,530 It doesn't know that I changed two characters. 414 00:19:29,530 --> 00:19:32,490 It knows that I got rid of a line and replaced it with a line. 415 00:19:32,490 --> 00:19:33,730 I can git push now. 416 00:19:33,730 --> 00:19:37,740 And so that change [? pushing ?] [? changing ?] x to 51 is now online. 417 00:19:37,740 --> 00:19:41,300 So if I go to GitHub, and I refresh this, right now x is 28. 418 00:19:41,300 --> 00:19:45,970 Now I see that x is 51 because that's the change that I just pushed. 419 00:19:45,970 --> 00:19:48,130 Now, in this other version of the repository, 420 00:19:48,130 --> 00:19:51,810 where x is still 28-- why don't you pick a different number? 421 00:19:51,810 --> 00:19:53,110 AUDIENCE: 17. 422 00:19:53,110 --> 00:19:54,030 SPEAKER: 17. 423 00:19:54,030 --> 00:19:59,780 And I'm going to say git commit -am change x to 17. 424 00:19:59,780 --> 00:20:02,090 So I'm saving that change. 425 00:20:02,090 --> 00:20:05,380 And let's say now I wanted to pull the changes from GitHub, 426 00:20:05,380 --> 00:20:08,230 make sure I have the latest version of the code. 427 00:20:08,230 --> 00:20:10,320 I've changed x to 17 here. 428 00:20:10,320 --> 00:20:12,510 The version on GitHub has a recent change that says, 429 00:20:12,510 --> 00:20:15,040 we've changed x to be 51. 430 00:20:15,040 --> 00:20:17,236 So when I git pull, watch what's going to happen. 431 00:20:17,236 --> 00:20:20,520 I'll close this file for now, but I press git pull. 432 00:20:20,520 --> 00:20:24,250 And it says conflict, merge conflict in swap.c. 433 00:20:24,250 --> 00:20:28,110 The automatic merge failed, so git couldn't merge these two files 434 00:20:28,110 --> 00:20:29,070 automatically. 435 00:20:29,070 --> 00:20:32,750 I need to fix the conflicts and then commit the results. 436 00:20:32,750 --> 00:20:35,250 So let's open up swap.c and see what's going on. 437 00:20:35,250 --> 00:20:38,320 And you'll see, oh, and CS50 IDE actually 438 00:20:38,320 --> 00:20:43,320 adds some nice little markers that help us understand what's going on. 439 00:20:43,320 --> 00:20:46,189 But we see this head, and we see this commit hash, 440 00:20:46,189 --> 00:20:47,980 and we see what the different versions are. 441 00:20:47,980 --> 00:20:51,220 This is my version that says int x equals 17. 442 00:20:51,220 --> 00:20:54,430 And this is their version that says int x equals 51. 443 00:20:54,430 --> 00:20:57,020 That's the version that we just pulled down from GitHub. 444 00:20:57,020 --> 00:20:59,470 So I need to decide kind of which version of the code 445 00:20:59,470 --> 00:21:02,340 that I actually want to use. 446 00:21:02,340 --> 00:21:03,190 Maybe I don't know. 447 00:21:03,190 --> 00:21:06,148 And maybe I just want to go with, I don't know, the average of the two. 448 00:21:06,148 --> 00:21:08,200 We'll do like, what is it, 34? 449 00:21:08,200 --> 00:21:11,112 And then I would get rid of these lines that are conflicting. 450 00:21:11,112 --> 00:21:14,840 451 00:21:14,840 --> 00:21:19,180 I'm not too used to the syntax, but-- oh here we go. 452 00:21:19,180 --> 00:21:24,240 So I would just say int x equals 34. 453 00:21:24,240 --> 00:21:26,230 And I'll get rid of all those extra lines. 454 00:21:26,230 --> 00:21:29,730 And so I've now changed this code, gotten rid of all those excess lines, 455 00:21:29,730 --> 00:21:31,830 and just replaced it with kind of the line 456 00:21:31,830 --> 00:21:36,010 that I actually want-- in this case, the one that says index equals is 34. 457 00:21:36,010 --> 00:21:40,350 At this point, I can do git status, just to see what's going on. 458 00:21:40,350 --> 00:21:43,080 It says that I have unmerged paths. 459 00:21:43,080 --> 00:21:46,560 I need to fix the conflicts and run git commit. 460 00:21:46,560 --> 00:21:50,850 I will do git commit, -am, and I'll say, I'm going to commit these changes. 461 00:21:50,850 --> 00:21:54,680 I just fixed the merge conflicts. 462 00:21:54,680 --> 00:21:56,130 So now it says I fixed it. 463 00:21:56,130 --> 00:21:58,600 I can now git push, which takes these changes I just 464 00:21:58,600 --> 00:21:59,760 fixed the merge conflicts. 465 00:21:59,760 --> 00:22:01,760 I'm going to push them back up to GitHub. 466 00:22:01,760 --> 00:22:03,670 I git push. 467 00:22:03,670 --> 00:22:07,950 And now, after that's done, I can go back to GitHub, refresh the page, 468 00:22:07,950 --> 00:22:09,600 and x is now 34. 469 00:22:09,600 --> 00:22:12,910 And this is my resolution to this merge conflict. 470 00:22:12,910 --> 00:22:16,390 Kind of a lot of stuff happening simultaneously, but that makes sense? 471 00:22:16,390 --> 00:22:19,300 Any questions on how that merge complex happened, why it happened, 472 00:22:19,300 --> 00:22:22,800 or what we were able to do in order to fix it? 473 00:22:22,800 --> 00:22:23,650 All good? 474 00:22:23,650 --> 00:22:24,980 Fantastic. 475 00:22:24,980 --> 00:22:26,410 OK. 476 00:22:26,410 --> 00:22:28,590 Let's move on then. 477 00:22:28,590 --> 00:22:30,990 git log is another very useful feature. 478 00:22:30,990 --> 00:22:33,480 And git log's job is, basically, it will tell you 479 00:22:33,480 --> 00:22:37,380 kind of the history of all of the commits that you have made previously. 480 00:22:37,380 --> 00:22:40,500 So it shows the history of the commits and their messages. 481 00:22:40,500 --> 00:22:43,690 So if I do something like git log, and type that into my terminal, 482 00:22:43,690 --> 00:22:45,750 then something like this will show up, where it will show me 483 00:22:45,750 --> 00:22:47,650 a history of all the commits that I've made. 484 00:22:47,650 --> 00:22:51,700 It will show me the kind of commit ID, or the commit hash, 485 00:22:51,700 --> 00:22:53,150 that identifies that commit. 486 00:22:53,150 --> 00:22:54,400 It will tell me who made that commit. 487 00:22:54,400 --> 00:22:56,441 So if multiple people are collaborating together, 488 00:22:56,441 --> 00:22:58,369 it will tell you who made the change, when 489 00:22:58,369 --> 00:23:00,160 they made the change, on a particular date, 490 00:23:00,160 --> 00:23:03,130 and then this message here is whatever you said was the commit message. 491 00:23:03,130 --> 00:23:05,588 So that's why a commit message can be very, very important. 492 00:23:05,588 --> 00:23:09,030 Because when you use git log, you'll see all the changes that were made, 493 00:23:09,030 --> 00:23:11,650 and the message is a very good indicator as to what 494 00:23:11,650 --> 00:23:14,170 was changed in this particular version. 495 00:23:14,170 --> 00:23:18,630 So make sure you use good commit messages if you're going to use git. 496 00:23:18,630 --> 00:23:20,304 Questions on git log? 497 00:23:20,304 --> 00:23:22,720 I'll show you what that looks like in the actual terminal. 498 00:23:22,720 --> 00:23:25,740 I can type in git log at the terminal. 499 00:23:25,740 --> 00:23:28,740 And it will show me all these changes that I've made. 500 00:23:28,740 --> 00:23:33,264 So I added the swap file, changed x to 17, fixed these merge conflicts. 501 00:23:33,264 --> 00:23:36,430 Those are all the changes, and you can see kind of when I made those changes 502 00:23:36,430 --> 00:23:39,030 and who made those changes. 503 00:23:39,030 --> 00:23:40,960 Clear? 504 00:23:40,960 --> 00:23:41,846 Fantastic. 505 00:23:41,846 --> 00:23:45,070 506 00:23:45,070 --> 00:23:47,880 All right, so now let's say I made a change, 507 00:23:47,880 --> 00:23:50,920 but I didn't mean to make that change, and I want to kind of go back 508 00:23:50,920 --> 00:23:53,020 to a previous version of the code. 509 00:23:53,020 --> 00:23:54,449 That's what git reset is for. 510 00:23:54,449 --> 00:23:57,240 That allows I mean to kind of roll back, these changes didn't work, 511 00:23:57,240 --> 00:23:58,890 I want to go back to an older version. 512 00:23:58,890 --> 00:24:00,250 And here's how that works. 513 00:24:00,250 --> 00:24:03,990 So recall that every one of our commits has 514 00:24:03,990 --> 00:24:06,960 a commit hash, some unique identifier that 515 00:24:06,960 --> 00:24:10,060 says this is how we identify this particular change. 516 00:24:10,060 --> 00:24:11,880 And down here, next to the commit messages, 517 00:24:11,880 --> 00:24:17,020 I've included the first couple characters of those commit hashes. 518 00:24:17,020 --> 00:24:21,794 If I type git reset [? dash dash ?] --hard, followed by some commit hash-- 519 00:24:21,794 --> 00:24:24,960 and usually you don't need to include the entire commit hash because usually 520 00:24:24,960 --> 00:24:26,910 it's dozens upon dozens of characters. 521 00:24:26,910 --> 00:24:30,310 Usually just a couple of characters, at least enough to uniquely identify 522 00:24:30,310 --> 00:24:33,330 that commit so that no other commit has those same initial characters 523 00:24:33,330 --> 00:24:37,270 is sufficient-- if you type that, it will revert your code back 524 00:24:37,270 --> 00:24:40,000 to that previous version, and you will lose all of the changes 525 00:24:40,000 --> 00:24:41,830 that you've made sense that version. 526 00:24:41,830 --> 00:24:43,810 So do this only if you were sure that you want 527 00:24:43,810 --> 00:24:46,110 to go back to the previous version. 528 00:24:46,110 --> 00:24:50,120 In addition to going back to a previous version in your commit history, 529 00:24:50,120 --> 00:24:54,180 you can also go back to the version that currently exists on GitHub. 530 00:24:54,180 --> 00:24:56,730 So if there were a version on GitHub, which is our origin, 531 00:24:56,730 --> 00:24:59,290 in this case, the origin of the repository, 532 00:24:59,290 --> 00:25:01,600 and we've made changes on our computer, and now we 533 00:25:01,600 --> 00:25:04,433 realize those changes really don't work, and really want to go back, 534 00:25:04,433 --> 00:25:07,290 you can use git reset --hard origin slash 535 00:25:07,290 --> 00:25:12,169 master, to go back to the version that's on GitHub and its master branch. 536 00:25:12,169 --> 00:25:14,460 And again, we've only been working on the master branch 537 00:25:14,460 --> 00:25:18,930 so far, so that's the only thing that we really have to work with. 538 00:25:18,930 --> 00:25:24,630 So I can type git reset --hard followed by 476 1626, 539 00:25:24,630 --> 00:25:27,480 where that is the beginning of the commit hash 540 00:25:27,480 --> 00:25:30,870 for this version of the repository. 541 00:25:30,870 --> 00:25:33,660 And again, if I don't know what the identifier is, 542 00:25:33,660 --> 00:25:35,830 I can always use git log, that code, that command 543 00:25:35,830 --> 00:25:37,705 that shows me the history of all the comments 544 00:25:37,705 --> 00:25:40,170 that I've made along with when I made any particular commit 545 00:25:40,170 --> 00:25:42,070 and what changes were made in that commit. 546 00:25:42,070 --> 00:25:45,480 So that can give me the identifier, and if I do git reset, 547 00:25:45,480 --> 00:25:49,380 then these changes that I've made after that file will kind of go away, 548 00:25:49,380 --> 00:25:52,080 and I'll be left with this being the most recent version. 549 00:25:52,080 --> 00:25:54,870 And so that's what I'm going to have left over. 550 00:25:54,870 --> 00:25:57,640 Any questions on that? 551 00:25:57,640 --> 00:26:00,320 OK, let's get into talking about branching. 552 00:26:00,320 --> 00:26:03,800 So branching is a very, very valuable feature in git 553 00:26:03,800 --> 00:26:06,920 that basically allows you, in a single repository, 554 00:26:06,920 --> 00:26:10,040 to have a couple different kind of versions of the code that 555 00:26:10,040 --> 00:26:11,855 are going on simultaneously. 556 00:26:11,855 --> 00:26:14,480 So maybe you have one version of your code, your master branch, 557 00:26:14,480 --> 00:26:17,197 that's generally the one that works perfectly, 558 00:26:17,197 --> 00:26:19,280 or that does what you need it to do, and maybe you 559 00:26:19,280 --> 00:26:20,930 want to add new features to your program, 560 00:26:20,930 --> 00:26:23,120 or you want to add something brand new to your code, 561 00:26:23,120 --> 00:26:25,760 but you don't want to potentially mess up the master 562 00:26:25,760 --> 00:26:27,720 branch because that one you know works. 563 00:26:27,720 --> 00:26:30,410 So one thing you can do is you can kind of branch off, 564 00:26:30,410 --> 00:26:34,190 creating a new branch that you're making new changes to, 565 00:26:34,190 --> 00:26:38,489 testing out new features, while keeping your original master branch identical. 566 00:26:38,489 --> 00:26:40,530 And then you can make commits to this new branch. 567 00:26:40,530 --> 00:26:43,490 You can roll back those commits and do all the same things 568 00:26:43,490 --> 00:26:45,920 that we were just talking about previously in the seminar. 569 00:26:45,920 --> 00:26:49,670 And then only when you feel ready that this new branch has all the things 570 00:26:49,670 --> 00:26:53,480 that you want it to have and is ready to kind of become the official version, 571 00:26:53,480 --> 00:26:56,230 can you then merge it back into the master branch 572 00:26:56,230 --> 00:26:58,920 so that you then have the one working version. 573 00:26:58,920 --> 00:27:01,220 So let's explore how you do that branching. 574 00:27:01,220 --> 00:27:04,650 So just to recap, branching is a version of the repository. 575 00:27:04,650 --> 00:27:07,340 Each branch has its own commit history, and each branch 576 00:27:07,340 --> 00:27:10,700 has its own kind of most recent version of the code. 577 00:27:10,700 --> 00:27:12,950 So git branch is the command that you would 578 00:27:12,950 --> 00:27:15,950 use in order to create a new branch. 579 00:27:15,950 --> 00:27:20,990 So if I just type git branch, it will show me all of the current branches 580 00:27:20,990 --> 00:27:23,280 that I have on the repository. 581 00:27:23,280 --> 00:27:26,090 But if I want to create a new branch, I would type git branch 582 00:27:26,090 --> 00:27:27,890 followed by the name of the branch. 583 00:27:27,890 --> 00:27:29,900 And I could just make up any branch name I want, 584 00:27:29,900 --> 00:27:33,800 so long as it's not a name that already exists as a branch. 585 00:27:33,800 --> 00:27:36,080 And then, once I've created a new branch, 586 00:27:36,080 --> 00:27:40,070 if I want to switch to that new branch, I would use git checkout. 587 00:27:40,070 --> 00:27:43,130 So git checkout, followed by the name of the branch, 588 00:27:43,130 --> 00:27:45,890 will switch me to that new branch that are going 589 00:27:45,890 --> 00:27:48,300 to be working on that other branch. 590 00:27:48,300 --> 00:27:51,740 And side note, if you want to kind of combine these two steps to check out 591 00:27:51,740 --> 00:27:53,930 a new branch and create it at the same time, 592 00:27:53,930 --> 00:27:57,800 you can use git checkout -b, and then followed by a new branch name, 593 00:27:57,800 --> 00:28:01,020 and that will both create a new branch, and it will switch you to it. 594 00:28:01,020 --> 00:28:03,530 That can just be a little time saving feature. 595 00:28:03,530 --> 00:28:06,300 So right now, I just have one version of the code. 596 00:28:06,300 --> 00:28:09,090 It's the master branch, the original version, by default. 597 00:28:09,090 --> 00:28:13,190 And if I were to tight git branch tests, that would create for me 598 00:28:13,190 --> 00:28:17,360 a new branch called tests that basically will just be a copy of master, 599 00:28:17,360 --> 00:28:20,690 at least for the time being, creating that new version of the code. 600 00:28:20,690 --> 00:28:24,080 So then, I can make new changes to this test. 601 00:28:24,080 --> 00:28:25,270 I can add files to it. 602 00:28:25,270 --> 00:28:29,660 I can make commits, so saving reversions of this test branch, 603 00:28:29,660 --> 00:28:32,000 and then later, once test is the way I want it to be, 604 00:28:32,000 --> 00:28:33,870 I can merge it back in with master. 605 00:28:33,870 --> 00:28:35,450 And so we'll look at that right now. 606 00:28:35,450 --> 00:28:37,370 Git merge is the command that we would use 607 00:28:37,370 --> 00:28:40,490 to merge two different branches together, 608 00:28:40,490 --> 00:28:42,350 and the way that works is like this. 609 00:28:42,350 --> 00:28:47,540 git merge, followed by some branch name, merges that branch with whatever branch 610 00:28:47,540 --> 00:28:49,320 I am currently on. 611 00:28:49,320 --> 00:28:53,030 So what that means is that if I am currently on the master branch, 612 00:28:53,030 --> 00:28:56,134 and the tests branch now has kind of a whole bunch of versions 613 00:28:56,134 --> 00:28:59,300 to the code that have been made so it's got a whole bunch of files that have 614 00:28:59,300 --> 00:29:04,280 been changed, and I now want to take those changes and say, 615 00:29:04,280 --> 00:29:06,290 I want to bring them into the master branch. 616 00:29:06,290 --> 00:29:08,123 Then the command that I would use here would 617 00:29:08,123 --> 00:29:10,280 be something like git merge tests. 618 00:29:10,280 --> 00:29:13,130 And that would take all these changes to the test branch. 619 00:29:13,130 --> 00:29:15,650 And it would merge them with the master branch 620 00:29:15,650 --> 00:29:19,300 so that the master branch now reflects all of those changes. 621 00:29:19,300 --> 00:29:22,610 Now, there may be the possibility that, on the master branch, 622 00:29:22,610 --> 00:29:25,010 I've made changes to the same lines of code 623 00:29:25,010 --> 00:29:27,560 that the test branch also made the changes to. 624 00:29:27,560 --> 00:29:31,171 And in that case, when you try and merge tests into the master branch, 625 00:29:31,171 --> 00:29:33,170 you're going to run into another merge conflict, 626 00:29:33,170 --> 00:29:35,003 and we've talked about how to resolve those. 627 00:29:35,003 --> 00:29:37,910 But basically, it involves getting rid of those lines you don't want, 628 00:29:37,910 --> 00:29:39,320 and then figuring out how to take the two 629 00:29:39,320 --> 00:29:41,528 kind of different versions of the code and figure out 630 00:29:41,528 --> 00:29:43,440 which version you actually want. 631 00:29:43,440 --> 00:29:46,782 So that's, oftentimes, a possibility that you'll run into, especially 632 00:29:46,782 --> 00:29:49,490 on larger projects, where multiple people are working on the code 633 00:29:49,490 --> 00:29:52,280 simultaneously, and potentially working on different branches, 634 00:29:52,280 --> 00:29:54,740 it may very well be the case that merging two branches 635 00:29:54,740 --> 00:29:57,540 can result in a merge conflict. 636 00:29:57,540 --> 00:30:00,000 So let's take a look at how this might work. 637 00:30:00,000 --> 00:30:03,800 So as you can see, right now, I'm on the master branch of this repository. 638 00:30:03,800 --> 00:30:06,950 And I can see this even more clearly, if your terminal doesn't display 639 00:30:06,950 --> 00:30:09,800 what branch you're on, just by typing git branch, 640 00:30:09,800 --> 00:30:13,490 and that will tell me that there is only one branch in this repository, 641 00:30:13,490 --> 00:30:14,984 and it is called master. 642 00:30:14,984 --> 00:30:16,775 So let's say I want to create a new branch. 643 00:30:16,775 --> 00:30:20,050 644 00:30:20,050 --> 00:30:26,900 Let's say I want it to separate out this code, the code that does the swapping, 645 00:30:26,900 --> 00:30:28,142 into its own function. 646 00:30:28,142 --> 00:30:30,350 But that seems like it has the potential to go wrong. 647 00:30:30,350 --> 00:30:31,599 It might not necessarily work. 648 00:30:31,599 --> 00:30:33,440 So I don't want to just change this file. 649 00:30:33,440 --> 00:30:37,490 I want to create a new branch that will let me test out those changes 650 00:30:37,490 --> 00:30:39,790 without worrying about whatever is happening in master. 651 00:30:39,790 --> 00:30:41,915 So I'm going to create a new branch via git branch, 652 00:30:41,915 --> 00:30:45,050 and I'll call it function just because the purpose of this branch 653 00:30:45,050 --> 00:30:49,380 is I'm going to be creating a new function in order to perform the swap. 654 00:30:49,380 --> 00:30:51,420 So I type git branch function. 655 00:30:51,420 --> 00:30:54,200 And now, if I were to type git branch, you'll 656 00:30:54,200 --> 00:30:57,350 see that I have two branches going here. 657 00:30:57,350 --> 00:30:59,070 I've got a master branch, and it's green, 658 00:30:59,070 --> 00:31:00,535 so that says that's the branch I'm on right now. 659 00:31:00,535 --> 00:31:02,780 But there's also a function branch that appears now. 660 00:31:02,780 --> 00:31:04,730 That's the branch that I've just created. 661 00:31:04,730 --> 00:31:06,440 And if I want to switch to that branch, I 662 00:31:06,440 --> 00:31:10,600 would type something like git checkout function. 663 00:31:10,600 --> 00:31:13,680 And it says, switched to branch function. 664 00:31:13,680 --> 00:31:17,520 And so now, if I type git branch, I would see there are two branches still, 665 00:31:17,520 --> 00:31:21,230 function and master, but function is now the green one with the star next to it. 666 00:31:21,230 --> 00:31:23,450 That's the branch that I'm currently on. 667 00:31:23,450 --> 00:31:28,830 So now I'm on this function branch, and I can add this swap function, 668 00:31:28,830 --> 00:31:38,070 void swap, int star A, int star B, and in temp equals star a, 669 00:31:38,070 --> 00:31:41,990 star a equals star b, and star b equals temp. 670 00:31:41,990 --> 00:31:51,300 And I can now replace this with just swap address of x, address of y. 671 00:31:51,300 --> 00:31:53,180 That should work, right? 672 00:31:53,180 --> 00:31:54,110 Hopefully, it works. 673 00:31:54,110 --> 00:31:56,340 I'm going to commit those changes. 674 00:31:56,340 --> 00:32:02,790 I'm going to say add a swap function. 675 00:32:02,790 --> 00:32:05,960 And so that change was just made, and so it says one file changed, 676 00:32:05,960 --> 00:32:08,040 I added eight lines, removed three lines. 677 00:32:08,040 --> 00:32:11,660 And so that commit is there. 678 00:32:11,660 --> 00:32:16,830 But now, if I type git branch, I can say I'm currently on the function branch. 679 00:32:16,830 --> 00:32:19,250 If I were to check out the master branch, 680 00:32:19,250 --> 00:32:24,260 the git checkout master, what you'll notice is that swap.c changes. 681 00:32:24,260 --> 00:32:26,824 It changed back to the version that's on the master branch 682 00:32:26,824 --> 00:32:28,990 because the master branch doesn't have new function. 683 00:32:28,990 --> 00:32:31,350 It just has these three lines of code that 684 00:32:31,350 --> 00:32:33,540 are right inside the main function. 685 00:32:33,540 --> 00:32:36,700 Watch again, if I git checkout back to the function branch, 686 00:32:36,700 --> 00:32:39,260 watch what happens to swap.c. 687 00:32:39,260 --> 00:32:41,450 It will just immediately show me, here's the version 688 00:32:41,450 --> 00:32:43,040 that's on the function branch. 689 00:32:43,040 --> 00:32:45,090 And so those are those changes. 690 00:32:45,090 --> 00:32:46,018 Question? 691 00:32:46,018 --> 00:32:46,946 [INAUDIBLE] 692 00:32:46,946 --> 00:32:51,350 693 00:32:51,350 --> 00:32:55,040 Yeah, so on the Mac Finder, if you do a git checkout, 694 00:32:55,040 --> 00:32:57,341 and maybe this new branch has, like, has a file 695 00:32:57,341 --> 00:32:59,340 that didn't exist on the other branch, that file 696 00:32:59,340 --> 00:33:01,320 will appear in your file system. 697 00:33:01,320 --> 00:33:03,564 So it absolutely works. 698 00:33:03,564 --> 00:33:05,480 And so now maybe I'm happy with those changes, 699 00:33:05,480 --> 00:33:09,260 and I want to-- let's actually make sure it works. 700 00:33:09,260 --> 00:33:12,440 [INAUDIBLE] [? 34505034. ?] 701 00:33:12,440 --> 00:33:13,010 Fantastic. 702 00:33:13,010 --> 00:33:14,040 That did in fact work. 703 00:33:14,040 --> 00:33:18,160 So now I feel comfortable merging those changes back into the master branch. 704 00:33:18,160 --> 00:33:22,604 So I'm going to go to the master branch via git checkout master, and notice, 705 00:33:22,604 --> 00:33:25,520 once again, this is the version that's currently in the master branch, 706 00:33:25,520 --> 00:33:28,730 and my function branch has that new commit that I want to merge in. 707 00:33:28,730 --> 00:33:32,820 If I type git merge function, what that's going to do 708 00:33:32,820 --> 00:33:36,260 is it's going to take the changes on the function branch, 709 00:33:36,260 --> 00:33:38,390 and it will merge them into the master branch 710 00:33:38,390 --> 00:33:41,820 so that that new commit, that version where I made the new function, 711 00:33:41,820 --> 00:33:43,310 will now become part of master. 712 00:33:43,310 --> 00:33:45,060 And there shouldn't be any merge conflicts 713 00:33:45,060 --> 00:33:46,650 because I haven't changed master. 714 00:33:46,650 --> 00:33:48,152 So I press Return. 715 00:33:48,152 --> 00:33:49,110 It makes those changes. 716 00:33:49,110 --> 00:33:52,290 And now this is my master branch, and I have that swap function. 717 00:33:52,290 --> 00:33:56,390 And you can show, if I type git branch, I'm still on the master branch. 718 00:33:56,390 --> 00:33:59,070 But that new function that I created in the function branch 719 00:33:59,070 --> 00:34:02,084 now exists in master. 720 00:34:02,084 --> 00:34:05,000 And at this point, if I wanted to, I could delete the function branch, 721 00:34:05,000 --> 00:34:06,166 because I no longer need it. 722 00:34:06,166 --> 00:34:11,480 And the command to do that is git branch dash-- capital -D, for delete, 723 00:34:11,480 --> 00:34:12,949 followed by the name of the branch. 724 00:34:12,949 --> 00:34:15,930 So git branch dash -d function deleted branch function. 725 00:34:15,930 --> 00:34:20,420 So now, if I type git branch again, I only have the master branch, 726 00:34:20,420 --> 00:34:24,020 and if I were to git log to look at all the commits that I've made, 727 00:34:24,020 --> 00:34:27,459 I would see that out of swap function is now 728 00:34:27,459 --> 00:34:30,000 there as a commit in the master branch because I merged those 729 00:34:30,000 --> 00:34:33,600 commits into that particular branch. 730 00:34:33,600 --> 00:34:35,632 Any questions on how that works? 731 00:34:35,632 --> 00:34:38,340 And so merging and having branches is a very, very powerful tool. 732 00:34:38,340 --> 00:34:41,464 And I would highly recommend it when you're working on your final projects. 733 00:34:41,464 --> 00:34:44,120 Because if you want to kind of be a little bit ambitious 734 00:34:44,120 --> 00:34:46,270 and potentially test new changes to the code, 735 00:34:46,270 --> 00:34:48,600 this can be a good way of making sure that you still 736 00:34:48,600 --> 00:34:50,808 hold on to the original while still allowing yourself 737 00:34:50,808 --> 00:34:54,060 the creative freedom to experiment, and make changes, and mess with the stuff 738 00:34:54,060 --> 00:34:55,226 that you've already written. 739 00:34:55,226 --> 00:34:57,520 740 00:34:57,520 --> 00:35:00,620 All right, and last thing I'll kind of briefly touch on 741 00:35:00,620 --> 00:35:04,020 but won't do a demonstration of something called pull requests. 742 00:35:04,020 --> 00:35:07,230 This happens very frequently in open source projects, especially. 743 00:35:07,230 --> 00:35:12,600 But if you've made a change to a repository, either in a separate branch 744 00:35:12,600 --> 00:35:15,600 or potentially in a fork, like I mentioned earlier, where a fork is just 745 00:35:15,600 --> 00:35:18,540 kind of your version of someone else's repository, 746 00:35:18,540 --> 00:35:23,000 sometimes you may want to request to kind of merge those changes back 747 00:35:23,000 --> 00:35:24,400 into the original version. 748 00:35:24,400 --> 00:35:26,730 And so this would be when you would submit a pull 749 00:35:26,730 --> 00:35:28,229 request, as the terminology goes. 750 00:35:28,229 --> 00:35:30,270 And so if you hear that, know that all that means 751 00:35:30,270 --> 00:35:33,090 is that you've made changes to some repository, 752 00:35:33,090 --> 00:35:36,560 either in a different branch, or in a different forked repository altogether, 753 00:35:36,560 --> 00:35:38,810 and you would like to then kind of merge it back 754 00:35:38,810 --> 00:35:40,880 into whatever the original version was. 755 00:35:40,880 --> 00:35:43,310 And this is typically done via a pull request. 756 00:35:43,310 --> 00:35:47,250 And GitHub has functionality built into it to allow for pull requests 757 00:35:47,250 --> 00:35:51,080 to happen and to allow for whoever owns the repository to kind of review pull 758 00:35:51,080 --> 00:35:53,750 requests, look at the changes that people have made, 759 00:35:53,750 --> 00:35:57,970 and either decide to approve or reject those changes. 760 00:35:57,970 --> 00:36:00,354 So once again, Git is a very valuable tool 761 00:36:00,354 --> 00:36:02,270 that helps you keep track of different changes 762 00:36:02,270 --> 00:36:05,000 your code, makes sure different collaborators can work together 763 00:36:05,000 --> 00:36:08,390 on the same repository, makes sure you can be ambitious and test 764 00:36:08,390 --> 00:36:11,270 new changes without losing the original copy of your code, 765 00:36:11,270 --> 00:36:13,670 and also allows you to, if you ever do make a mistake, 766 00:36:13,670 --> 00:36:16,140 to go back to a previous version. 767 00:36:16,140 --> 00:36:19,140 So as long as you are kind of frequently making commits, saving the work 768 00:36:19,140 --> 00:36:21,514 that you're doing, this can be a very, very valuable tool 769 00:36:21,514 --> 00:36:23,960 for keeping track of the different versions of your code 770 00:36:23,960 --> 00:36:27,980 and making sure that your project is under control. 771 00:36:27,980 --> 00:36:31,680 I'll take any questions now, but that's what I had for you today. 772 00:36:31,680 --> 00:36:32,220 All good? 773 00:36:32,220 --> 00:36:35,730 All right, fantastic thank you both for coming. 774 00:36:35,730 --> 00:36:36,730 AUDIENCE: Oh, question. 775 00:36:36,730 --> 00:36:37,730 [INAUDIBLE] 776 00:36:37,730 --> 00:36:42,141 777 00:36:42,141 --> 00:36:42,890 SPEAKER: Oh, yeah. 778 00:36:42,890 --> 00:36:48,890 So submit 50 is-- OK, let me make sure I'm remembering this correctly. 779 00:36:48,890 --> 00:36:51,810 Submit 50 is, basically what that's happening is, 780 00:36:51,810 --> 00:36:57,270 every time you submit 50 something, you are submitting kind of a new branch 781 00:36:57,270 --> 00:36:59,712 to your submit 50 repository. 782 00:36:59,712 --> 00:37:01,420 So when you type in something like submit 783 00:37:01,420 --> 00:37:04,520 50 p set 7, what was happening is, behind the scenes, 784 00:37:04,520 --> 00:37:07,190 we were creating a new branch called p set 7. 785 00:37:07,190 --> 00:37:09,810 And we were kind of pushing all of those changes 786 00:37:09,810 --> 00:37:11,460 to GitHub as a brand new branch. 787 00:37:11,460 --> 00:37:15,920 So if you were ever to go to GitHub.com slash submit 50, slash your username, 788 00:37:15,920 --> 00:37:17,770 that, in itself, is a repository. 789 00:37:17,770 --> 00:37:19,830 Each student in the class has a repository. 790 00:37:19,830 --> 00:37:23,250 And within that repository, there are branches for each 791 00:37:23,250 --> 00:37:25,500 of the different times you submit 50. 792 00:37:25,500 --> 00:37:29,875 So there's a submit 50 for Mario, there's a image 50 for 15, 793 00:37:29,875 --> 00:37:31,250 there's a submit 50 for the test. 794 00:37:31,250 --> 00:37:33,440 And each one of those are just different branches 795 00:37:33,440 --> 00:37:35,760 that are named with whatever the name of the problem is 796 00:37:35,760 --> 00:37:38,980 and the name of the problem set, or the name of the test. 797 00:37:38,980 --> 00:37:42,270 And so whenever you do a Submit 50, it pushes those to a new branch. 798 00:37:42,270 --> 00:37:45,932 And then what we do is we, like, tag those changes as a new release 799 00:37:45,932 --> 00:37:48,890 such that it makes it easy for us to kind of look at all of the changes 800 00:37:48,890 --> 00:37:49,950 that you've made. 801 00:37:49,950 --> 00:37:53,111 We didn't go into tagging and releases in this seminar. 802 00:37:53,111 --> 00:37:55,110 But it's just yet another way of kind of keeping 803 00:37:55,110 --> 00:37:58,193 track of different versions of code and keeping track of different changes 804 00:37:58,193 --> 00:37:58,960 to it. 805 00:37:58,960 --> 00:37:59,960 AUDIENCE: [INAUDIBLE] 806 00:37:59,960 --> 00:38:05,667 807 00:38:05,667 --> 00:38:06,500 SPEAKER: Yeah, yeah. 808 00:38:06,500 --> 00:38:07,520 That's typically what it would be used for. 809 00:38:07,520 --> 00:38:07,990 Exactly. 810 00:38:07,990 --> 00:38:09,864 And so when you submit something, that's kind 811 00:38:09,864 --> 00:38:13,982 of our semantic equivalent of saying that you've now supposedly gotten 812 00:38:13,982 --> 00:38:16,940 your problem set working, and this is the version that you want graded. 813 00:38:16,940 --> 00:38:18,520 And if so, we'll tag those. 814 00:38:18,520 --> 00:38:20,250 That's kind of the way it works. 815 00:38:20,250 --> 00:38:22,440 Good question, though. 816 00:38:22,440 --> 00:38:24,640 OK, thank you so much. 817 00:38:24,640 --> 00:38:26,785