1 00:00:00,000 --> 00:00:02,700 2 00:00:02,700 --> 00:00:04,690 BERNIE LONGBOY: Good afternoon, everyone. 3 00:00:04,690 --> 00:00:07,780 Welcome from Cambridge, Massachusetts. 4 00:00:07,780 --> 00:00:13,350 Welcome to today's seminar on collaboration and version control 5 00:00:13,350 --> 00:00:15,090 with Git. 6 00:00:15,090 --> 00:00:19,440 Today we have Tarun Prasad, a junior and computer science major 7 00:00:19,440 --> 00:00:22,350 and one of our CS50 teaching fellows. 8 00:00:22,350 --> 00:00:26,990 I'm Bernie Longboy, one of the staff members and your moderator for today. 9 00:00:26,990 --> 00:00:29,715 Welcome, and thank you, to Tarun. 10 00:00:29,715 --> 00:00:32,820 TARUN PRASAD: Thanks so much, Bernie, and thank you all for joining. 11 00:00:32,820 --> 00:00:36,000 Very good afternoon to all of you. 12 00:00:36,000 --> 00:00:39,420 So like Bernie said, the topic that we'll be talking about today 13 00:00:39,420 --> 00:00:43,500 is using this command-line tool called Git 14 00:00:43,500 --> 00:00:48,330 for version control and collaboration. 15 00:00:48,330 --> 00:00:52,140 So before we start talking about Git is or what we can do with it, 16 00:00:52,140 --> 00:00:55,850 consider the following two scenarios. 17 00:00:55,850 --> 00:00:59,320 The first scenario is that you're working on a CS50 problem set, 18 00:00:59,320 --> 00:01:00,687 say Finance. 19 00:01:00,687 --> 00:01:03,520 And you're able to get some portions of the P set working perfectly, 20 00:01:03,520 --> 00:01:06,640 so things like register, and quote, and buy. 21 00:01:06,640 --> 00:01:09,370 But you're confused as to how to complete index and display 22 00:01:09,370 --> 00:01:12,680 a table of stocks that the user owns. 23 00:01:12,680 --> 00:01:14,960 And while attempting to make more progress, 24 00:01:14,960 --> 00:01:18,180 you accidentally mess up the working code that you already had. 25 00:01:18,180 --> 00:01:21,350 And so now all that you see are internal server errors everywhere, 26 00:01:21,350 --> 00:01:23,543 no matter what you try to do. 27 00:01:23,543 --> 00:01:25,460 So in hindsight, what are some things that you 28 00:01:25,460 --> 00:01:27,050 could have done to prevent this? 29 00:01:27,050 --> 00:01:30,500 And feel free to use the chat to send in your answers, 30 00:01:30,500 --> 00:01:34,010 and we can talk about some of them. 31 00:01:34,010 --> 00:01:44,030 32 00:01:44,030 --> 00:01:47,280 What are some things that you could have done to prevent this from happening? 33 00:01:47,280 --> 00:01:50,460 How could you have? 34 00:01:50,460 --> 00:01:53,760 You could have used some sort of version control, the version control. 35 00:01:53,760 --> 00:01:57,240 Yes, use Git. 36 00:01:57,240 --> 00:01:59,040 You could have made some backups. 37 00:01:59,040 --> 00:02:01,330 Some of you are suggesting using some sort of backup, 38 00:02:01,330 --> 00:02:02,760 so that could be a good idea. 39 00:02:02,760 --> 00:02:08,190 You could have copied over your entire codebase, zip it into a ZIP file, 40 00:02:08,190 --> 00:02:09,320 store it on your desktop. 41 00:02:09,320 --> 00:02:11,820 And full disclosure-- I've definitely done this in the past. 42 00:02:11,820 --> 00:02:14,390 43 00:02:14,390 --> 00:02:18,350 You could absolutely do that, and maybe you would do that once every day. 44 00:02:18,350 --> 00:02:23,732 At the end of every day, you just create a ZIP backup of your entire code space. 45 00:02:23,732 --> 00:02:25,690 The main problem with doing something like that 46 00:02:25,690 --> 00:02:29,770 is, especially if your codebase is really large-- 47 00:02:29,770 --> 00:02:34,120 imagine you have a really large number of images and videos 48 00:02:34,120 --> 00:02:36,190 within your codebase-- 49 00:02:36,190 --> 00:02:38,870 you would have to make multiple copies of that. 50 00:02:38,870 --> 00:02:44,140 And so this can very quickly become very large and take up a lot of space 51 00:02:44,140 --> 00:02:46,640 unnecessarily. 52 00:02:46,640 --> 00:02:50,330 Now, one of you is suggesting that you can take a note of the changes 53 00:02:50,330 --> 00:02:51,380 that we made. 54 00:02:51,380 --> 00:02:53,220 So that could be another really good idea. 55 00:02:53,220 --> 00:02:54,650 Maybe we just open a Google Doc. 56 00:02:54,650 --> 00:03:01,470 And maybe every single day, we write down, OK, I added lines 23 to 30 57 00:03:01,470 --> 00:03:04,580 as these specific lines of code. 58 00:03:04,580 --> 00:03:07,580 I deleted line 15, and then I modified line 14 59 00:03:07,580 --> 00:03:09,838 by adding a semicolon at the end. 60 00:03:09,838 --> 00:03:11,630 And that could be another really useful way 61 00:03:11,630 --> 00:03:15,710 of managing this sort of a situation, where we don't actually 62 00:03:15,710 --> 00:03:16,670 use up as much space. 63 00:03:16,670 --> 00:03:20,810 64 00:03:20,810 --> 00:03:24,290 So thank you for the ideas, and let's go on to scenario two. 65 00:03:24,290 --> 00:03:27,100 66 00:03:27,100 --> 00:03:30,880 So let's say you decide to team up with a friend for your CS50 final project, 67 00:03:30,880 --> 00:03:33,153 and you want to build a web app. 68 00:03:33,153 --> 00:03:35,570 The two of you are trying to decide how to split up tasks. 69 00:03:35,570 --> 00:03:38,970 You really want to design the home page, using HTML and CSS, 70 00:03:38,970 --> 00:03:42,922 including the fonts, the styles, the colors, the text, et cetera. 71 00:03:42,922 --> 00:03:44,630 But your friend really wants to implement 72 00:03:44,630 --> 00:03:47,390 the sign-up and log-in workflow, so the HTML form, 73 00:03:47,390 --> 00:03:52,720 as well as some of the JavaScript, as well as the Flash backend. 74 00:03:52,720 --> 00:03:56,218 So given that you both want to edit the same files, but in different ways, 75 00:03:56,218 --> 00:03:57,760 what are some ways to deal with this? 76 00:03:57,760 --> 00:04:01,937 77 00:04:01,937 --> 00:04:05,270 And again, feel free to send messages in the chat, and we can talk through them. 78 00:04:05,270 --> 00:04:12,050 79 00:04:12,050 --> 00:04:14,900 You can use an IDE that has real-time collaboration. 80 00:04:14,900 --> 00:04:16,189 Yeah, that absolutely works. 81 00:04:16,189 --> 00:04:20,700 82 00:04:20,700 --> 00:04:22,364 Communication before doing any changes. 83 00:04:22,364 --> 00:04:24,435 84 00:04:24,435 --> 00:04:27,560 Some of you are suggesting Git branches, which is a really good idea, which 85 00:04:27,560 --> 00:04:28,670 we'll come to later today. 86 00:04:28,670 --> 00:04:39,560 87 00:04:39,560 --> 00:04:41,090 Any other thoughts? 88 00:04:41,090 --> 00:04:41,750 Git branches? 89 00:04:41,750 --> 00:04:48,800 90 00:04:48,800 --> 00:04:49,520 Using Replit. 91 00:04:49,520 --> 00:04:51,950 Yeah, using some sort of a collaborative code writer. 92 00:04:51,950 --> 00:04:55,220 Maybe even in the worst case, Google Docs, maybe 93 00:04:55,220 --> 00:04:58,100 copying over your entire file into Google Docs, 94 00:04:58,100 --> 00:05:00,650 and manually spacing everything and typing everything 95 00:05:00,650 --> 00:05:02,443 until everything looks OK. 96 00:05:02,443 --> 00:05:03,110 That might work. 97 00:05:03,110 --> 00:05:09,880 But I mean, some other ideas might also be using something like-- 98 00:05:09,880 --> 00:05:12,620 or just taking turns sitting at the same device. 99 00:05:12,620 --> 00:05:16,270 And maybe one person types code first, and then the other person takes over. 100 00:05:16,270 --> 00:05:19,750 And again, you can see that many of these have disadvantages. 101 00:05:19,750 --> 00:05:24,160 Either these ideas are somewhat slow, or maybe two people 102 00:05:24,160 --> 00:05:26,750 work on the two different things simultaneously. 103 00:05:26,750 --> 00:05:31,390 And then one person sends over their changes to the other person via email, 104 00:05:31,390 --> 00:05:34,870 and the other person then merges them in by going through it line by line 105 00:05:34,870 --> 00:05:38,210 and seeing what changed. 106 00:05:38,210 --> 00:05:40,580 Yeah, so thanks again for the great ideas. 107 00:05:40,580 --> 00:05:43,850 108 00:05:43,850 --> 00:05:46,160 A lot of these involve a lot of manual work 109 00:05:46,160 --> 00:05:49,520 and can often be slow or time-consuming. 110 00:05:49,520 --> 00:05:52,430 And that's where this command-line tool called Git comes in. 111 00:05:52,430 --> 00:05:55,560 112 00:05:55,560 --> 00:05:58,990 Git is essentially a command-line version control system, 113 00:05:58,990 --> 00:06:01,500 which means it automates a lot of the ideas 114 00:06:01,500 --> 00:06:04,020 that we just spoke about, storing differences 115 00:06:04,020 --> 00:06:08,160 between different versions of your codebase, 116 00:06:08,160 --> 00:06:13,020 or allowing collaboration, allowing different people to work 117 00:06:13,020 --> 00:06:16,200 on the same files in different locations, 118 00:06:16,200 --> 00:06:20,160 and enabling you to merge them together in a very easy and straightforward way. 119 00:06:20,160 --> 00:06:23,690 120 00:06:23,690 --> 00:06:28,760 So in Git, each project is stored as a repository. 121 00:06:28,760 --> 00:06:34,160 And each saved version of the repository is called a commit. 122 00:06:34,160 --> 00:06:37,010 A local repository on your device can be associated 123 00:06:37,010 --> 00:06:40,580 with other repositories hosted elsewhere, like on GitHub and GitLab. 124 00:06:40,580 --> 00:06:46,650 And these repositories hosted on other servers are called remotes. 125 00:06:46,650 --> 00:06:50,740 So your repository consists of both a history of the commits that you made, 126 00:06:50,740 --> 00:06:54,180 so all of the previous versions of your codebase, 127 00:06:54,180 --> 00:06:55,440 as well as the latest version. 128 00:06:55,440 --> 00:06:58,550 129 00:06:58,550 --> 00:07:01,460 Each commit stores the changes made since the previous commit, 130 00:07:01,460 --> 00:07:04,215 and is identified through a commit hash. 131 00:07:04,215 --> 00:07:06,590 And so I'm sure most of you have heard of hash functions, 132 00:07:06,590 --> 00:07:09,290 and so that's essentially what's used over here. 133 00:07:09,290 --> 00:07:13,250 Each commit stores what changes you've made since the previous commit. 134 00:07:13,250 --> 00:07:15,530 And then that information is somehow hashed 135 00:07:15,530 --> 00:07:19,448 to give you a hexadecimal number. 136 00:07:19,448 --> 00:07:21,240 And any time you want to refer to a commit, 137 00:07:21,240 --> 00:07:25,728 you can identify it, using this commit hash. 138 00:07:25,728 --> 00:07:28,770 The normal directory structure on your local system, along with the files 139 00:07:28,770 --> 00:07:34,760 it contains, as opposed to previous versions, is called a working copy. 140 00:07:34,760 --> 00:07:37,580 The set of tracked changes that will be saved in the next commit 141 00:07:37,580 --> 00:07:38,750 is called the staging area. 142 00:07:38,750 --> 00:07:41,700 143 00:07:41,700 --> 00:07:45,470 And so this is a diagram from another class called CS61. 144 00:07:45,470 --> 00:07:49,820 And this gives you an example of what the repository contains. 145 00:07:49,820 --> 00:07:53,060 It contains what's called the version repository, which 146 00:07:53,060 --> 00:07:55,470 consists of all of the commits that you made previously, 147 00:07:55,470 --> 00:07:57,740 so all of the previous versions of your codebase, 148 00:07:57,740 --> 00:08:00,160 along with the version that you are working on right now, 149 00:08:00,160 --> 00:08:01,160 called the working copy. 150 00:08:01,160 --> 00:08:04,150 151 00:08:04,150 --> 00:08:07,720 So I know these were a lot of terms just forced onto you, 152 00:08:07,720 --> 00:08:12,940 but hopefully, this will be useful in understanding how Git works. 153 00:08:12,940 --> 00:08:16,525 And we go through the details of how exactly to use Git next. 154 00:08:16,525 --> 00:08:21,500 155 00:08:21,500 --> 00:08:23,340 A quick note on the installation. 156 00:08:23,340 --> 00:08:27,228 If you're using Codespaces, like you do for your CS50 problem sets, 157 00:08:27,228 --> 00:08:29,270 then you don't actually have to install anything. 158 00:08:29,270 --> 00:08:31,310 Git should come pre-installed. 159 00:08:31,310 --> 00:08:35,720 If you do want to develop locally, then you can install it, 160 00:08:35,720 --> 00:08:37,340 using this link on Windows. 161 00:08:37,340 --> 00:08:40,110 Or in MacOS, it should probably be installed, but if it's not, 162 00:08:40,110 --> 00:08:44,890 then you can run git --version and it should prompt the installation. 163 00:08:44,890 --> 00:08:49,520 These links are in the slides, so you can definitely 164 00:08:49,520 --> 00:08:51,400 download the slides from the CS50 website, 165 00:08:51,400 --> 00:08:53,650 and you can download Git if you want to. 166 00:08:53,650 --> 00:08:57,800 167 00:08:57,800 --> 00:08:59,795 Now let's go on to the Git commands. 168 00:08:59,795 --> 00:09:02,598 169 00:09:02,598 --> 00:09:04,640 The first set of commands that are useful to know 170 00:09:04,640 --> 00:09:06,680 are the getting-started commands. 171 00:09:06,680 --> 00:09:10,050 So how do you get started with a Git repository? 172 00:09:10,050 --> 00:09:11,430 There are a couple of ways. 173 00:09:11,430 --> 00:09:13,770 And which one you use depends on whether you're 174 00:09:13,770 --> 00:09:16,890 working with an existing repository that someone's already published, 175 00:09:16,890 --> 00:09:21,220 or if you're creating a new code space completely from scratch. 176 00:09:21,220 --> 00:09:24,850 For your final project, you probably will use the latter 177 00:09:24,850 --> 00:09:27,910 because you will be starting a new project from scratch. 178 00:09:27,910 --> 00:09:31,100 And in such cases, you will use the command, git init, 179 00:09:31,100 --> 00:09:34,000 which means just initialize the folder that you're in right now 180 00:09:34,000 --> 00:09:36,570 as a Git repository. 181 00:09:36,570 --> 00:09:40,080 On the other hand, if you want to download an existing remote 182 00:09:40,080 --> 00:09:43,890 repository-- for example, something that you found on GitHub for whatever 183 00:09:43,890 --> 00:09:44,670 reason-- 184 00:09:44,670 --> 00:09:47,297 then you can use git clone. 185 00:09:47,297 --> 00:09:49,130 I show you a demo of all of this at the end. 186 00:09:49,130 --> 00:09:52,540 But the idea is to just copy the URL. 187 00:09:52,540 --> 00:09:56,080 You git clone URL, and then it'll download the entire repository 188 00:09:56,080 --> 00:09:58,368 and all of the files and directories into the folder 189 00:09:58,368 --> 00:09:59,410 that you're in right now. 190 00:09:59,410 --> 00:10:04,900 191 00:10:04,900 --> 00:10:07,500 The next set of commands that we're going to go over 192 00:10:07,500 --> 00:10:09,510 are for saving changes. 193 00:10:09,510 --> 00:10:13,290 And these three commands, in my opinion, are by far the most important commands 194 00:10:13,290 --> 00:10:15,695 in today's seminar. 195 00:10:15,695 --> 00:10:17,820 So even if you don't get anything else out of this, 196 00:10:17,820 --> 00:10:20,730 I want you to take back this one slide. 197 00:10:20,730 --> 00:10:26,830 The first one is git add, which specifies which files to track. 198 00:10:26,830 --> 00:10:30,780 And so it tracks these files by adding them to what we call the staging area. 199 00:10:30,780 --> 00:10:32,970 And like we mentioned before, the staging area 200 00:10:32,970 --> 00:10:38,580 is what controls the files and changes that will be saved in the next commit 201 00:10:38,580 --> 00:10:41,060 that you make. 202 00:10:41,060 --> 00:10:47,500 So you can specify, for example, git add hello.py, or git add mario.c. 203 00:10:47,500 --> 00:10:50,740 And you can list out the files, separated by spaces, 204 00:10:50,740 --> 00:10:55,710 and this will track those files by adding them to the staging area. 205 00:10:55,710 --> 00:10:57,680 So the next commit that you make will then 206 00:10:57,680 --> 00:11:00,750 save the changes that have been specified by git add. 207 00:11:00,750 --> 00:11:05,520 So for example, if you change two files, but you only git added one file, 208 00:11:05,520 --> 00:11:08,220 then only that one file will be saved in the next commit. 209 00:11:08,220 --> 00:11:12,946 And so this is useful for specifying exactly what goes into each commit. 210 00:11:12,946 --> 00:11:14,930 The second command for saving changes-- 211 00:11:14,930 --> 00:11:17,030 and this is, arguably, the most important-- 212 00:11:17,030 --> 00:11:21,050 is git commit, which actually creates the commit by saving the track 213 00:11:21,050 --> 00:11:24,140 changes in the form of a commit. 214 00:11:24,140 --> 00:11:27,500 The -m flag specifies a commit message, and so you 215 00:11:27,500 --> 00:11:31,730 can say git commit, -m, and then whatever commit message 216 00:11:31,730 --> 00:11:33,750 that specifies what changes you made. 217 00:11:33,750 --> 00:11:37,820 So for example, this could be something like fix x bug, 218 00:11:37,820 --> 00:11:43,590 or implement y feature, or something like that. 219 00:11:43,590 --> 00:11:47,780 And finally, the last saving-changes command that you need to know 220 00:11:47,780 --> 00:11:49,820 is git push. 221 00:11:49,820 --> 00:11:53,090 So technically, git push is an optional command, 222 00:11:53,090 --> 00:11:55,100 because if you're working entirely locally, 223 00:11:55,100 --> 00:11:58,885 if you don't have a remote associated with your Git repository, 224 00:11:58,885 --> 00:12:01,010 then you can absolutely just do git add and commit, 225 00:12:01,010 --> 00:12:04,083 and everything will be saved in your device. 226 00:12:04,083 --> 00:12:07,250 But if, for whatever reason, let's say, you want to collaborate with someone 227 00:12:07,250 --> 00:12:12,980 and you want somebody else to have access to your git repository, 228 00:12:12,980 --> 00:12:16,160 then you would add a remote, maybe on GitHub or something, 229 00:12:16,160 --> 00:12:20,720 and push your commits, your changes, onto the remote repository. 230 00:12:20,720 --> 00:12:22,340 And you would do that, using git push. 231 00:12:22,340 --> 00:12:27,960 232 00:12:27,960 --> 00:12:28,590 OK. 233 00:12:28,590 --> 00:12:31,590 And if you have any questions, please send them in the chat, and Bernie 234 00:12:31,590 --> 00:12:36,650 will stop and let me know if there are any questions. 235 00:12:36,650 --> 00:12:39,170 Undoing changes. 236 00:12:39,170 --> 00:12:41,330 The most important command for undoing changes 237 00:12:41,330 --> 00:12:46,190 is git revert, which lets you undo a commit by essentially creating 238 00:12:46,190 --> 00:12:49,610 a new commit that does exactly the opposite of what 239 00:12:49,610 --> 00:12:52,090 the incorrect commit did. 240 00:12:52,090 --> 00:12:57,580 So for example, if you decided to make some design changes to your web app 241 00:12:57,580 --> 00:13:02,040 that you were building, and so you add a bunch of CSS, 242 00:13:02,040 --> 00:13:03,590 maybe you create a new CSS file. 243 00:13:03,590 --> 00:13:06,580 And you add a bunch of CSS that specifies the fonts, and the styles, 244 00:13:06,580 --> 00:13:09,180 and the colors, and stuff like that. 245 00:13:09,180 --> 00:13:12,860 But then you decide to talk about this design with the other people 246 00:13:12,860 --> 00:13:16,070 in your group, and then you realize that, OK, maybe this 247 00:13:16,070 --> 00:13:19,410 isn't the best way forward for your website. 248 00:13:19,410 --> 00:13:21,485 And so you want to undo the changes. 249 00:13:21,485 --> 00:13:23,360 So one way to undo it would be to manually go 250 00:13:23,360 --> 00:13:26,030 back and see what changes you made, and then 251 00:13:26,030 --> 00:13:29,750 manually delete those lines and each of the files that you made the changes in. 252 00:13:29,750 --> 00:13:33,470 But the advantage of using Git is that, because each of these sets of changes 253 00:13:33,470 --> 00:13:37,040 is stored in a commit, you can directly undo all of those changes 254 00:13:37,040 --> 00:13:42,410 by just doing exactly the opposite of what that previous commit did. 255 00:13:42,410 --> 00:13:46,040 Now, how do you specify this commit in the command? 256 00:13:46,040 --> 00:13:50,870 So like I said earlier, each commit has associated with it 257 00:13:50,870 --> 00:13:55,500 a commit hash, which is basically a big hexadecimal number. 258 00:13:55,500 --> 00:13:58,775 And so you can specify this commit by using the commit hash. 259 00:13:58,775 --> 00:14:01,400 In fact, you don't even need to specify the entire commit hash. 260 00:14:01,400 --> 00:14:03,290 Usually, the first, say, five or six digits 261 00:14:03,290 --> 00:14:09,050 will suffice, because that's enough to uniquely identify this commit. 262 00:14:09,050 --> 00:14:16,550 You can also specify the commit by using the HEAD~n syntax. 263 00:14:16,550 --> 00:14:21,870 HEAD represents the latest commit, so HEAD~n would be the nth last commit. 264 00:14:21,870 --> 00:14:23,870 So let's say you wanted to get rid of the commit 265 00:14:23,870 --> 00:14:25,770 that you did five commits ago. 266 00:14:25,770 --> 00:14:27,200 Then you would just say HEAD~file. 267 00:14:27,200 --> 00:14:30,890 268 00:14:30,890 --> 00:14:35,170 And that's how you undo changes, using Git. 269 00:14:35,170 --> 00:14:38,440 And there are some other general, useful commands-- git 270 00:14:38,440 --> 00:14:42,740 status, which displays the state of the repository and the staging area, git 271 00:14:42,740 --> 00:14:45,700 log, which displays a log of the previous commits in the currently 272 00:14:45,700 --> 00:14:46,900 checked-out branch. 273 00:14:46,900 --> 00:14:50,260 And we'll talk about branches in a bit, but just 274 00:14:50,260 --> 00:14:54,350 think of this as a log of the previous commits that you made. 275 00:14:54,350 --> 00:14:57,710 And finally, git diff displays the changes that you've made. 276 00:14:57,710 --> 00:15:01,030 So for example, if you just do git diff, then it'll show you-- 277 00:15:01,030 --> 00:15:05,410 using the appropriate colors, green or red-- 278 00:15:05,410 --> 00:15:08,660 what changes that you've made since the last commit. 279 00:15:08,660 --> 00:15:12,940 You can also specify the commit hashes of new commits 280 00:15:12,940 --> 00:15:15,172 to ask for the changes between two commits. 281 00:15:15,172 --> 00:15:17,380 So maybe you want to go back and look at what changes 282 00:15:17,380 --> 00:15:19,630 that you made in a specific commit. 283 00:15:19,630 --> 00:15:24,070 You just specify git diff, the first commit hash, the second commit hash, 284 00:15:24,070 --> 00:15:28,566 and it'll show you whatever changes you made. 285 00:15:28,566 --> 00:15:32,230 BERNIE LONGBOY: I'll go ahead and read a couple of questions, Tarun. 286 00:15:32,230 --> 00:15:36,550 So first is, do I need to download anything on Mac to have Git? 287 00:15:36,550 --> 00:15:37,855 Actually, you don't, correct? 288 00:15:37,855 --> 00:15:38,710 Is that correct? 289 00:15:38,710 --> 00:15:40,418 TARUN PRASAD: You don't need to download, 290 00:15:40,418 --> 00:15:45,490 but you can double-check that you have it installed, using git --version. 291 00:15:45,490 --> 00:15:48,910 So just run this in your command line, and it should probably say something 292 00:15:48,910 --> 00:15:51,345 like Git Version 2.25 or something. 293 00:15:51,345 --> 00:15:52,220 BERNIE LONGBOY: Yeah. 294 00:15:52,220 --> 00:15:52,540 TARUN PRASAD: And-- 295 00:15:52,540 --> 00:15:54,010 BERNIE LONGBOY: And I think you answered this one, 296 00:15:54,010 --> 00:15:56,500 but does GitHub count with a visual aid to understand 297 00:15:56,500 --> 00:15:58,120 how many commits we're using? 298 00:15:58,120 --> 00:16:02,688 I'm finding the timeline branches a little confusing. 299 00:16:02,688 --> 00:16:03,480 TARUN PRASAD: Yeah. 300 00:16:03,480 --> 00:16:10,860 I mean, both Git and GitHub do have a list of commits. 301 00:16:10,860 --> 00:16:14,930 You can do this locally without even using GitHub, using git log. 302 00:16:14,930 --> 00:16:17,430 And so that'll give you a list of the commits that you made, 303 00:16:17,430 --> 00:16:24,480 along with a timestamp of when you made the commit, who made the commit, 304 00:16:24,480 --> 00:16:28,500 and other information, what changes were actually made in that commit. 305 00:16:28,500 --> 00:16:31,650 About branches, we will talk about that in about 5 or 10 minutes, 306 00:16:31,650 --> 00:16:32,340 after this demo. 307 00:16:32,340 --> 00:16:34,590 So hopefully, that will clear things up a little more. 308 00:16:34,590 --> 00:16:41,198 309 00:16:41,198 --> 00:16:42,190 BERNIE LONGBOY: OK. 310 00:16:42,190 --> 00:16:44,327 Those were-- 311 00:16:44,327 --> 00:16:45,410 TARUN PRASAD: OK, awesome. 312 00:16:45,410 --> 00:16:46,972 BERNIE LONGBOY: --good questions they had. 313 00:16:46,972 --> 00:16:47,764 TARUN PRASAD: Yeah. 314 00:16:47,764 --> 00:16:51,560 We will go ahead to a demo right now, so that I can just 315 00:16:51,560 --> 00:16:53,305 show you the basics of what we covered. 316 00:16:53,305 --> 00:16:55,430 And then we'll come back and talk a little bit more 317 00:16:55,430 --> 00:16:56,638 about some of these commands. 318 00:16:56,638 --> 00:17:11,869 319 00:17:11,869 --> 00:17:14,270 OK. 320 00:17:14,270 --> 00:17:16,609 So what I'm going to do here is, I am going 321 00:17:16,609 --> 00:17:22,300 to create a new folder, which I will call Git Seminar. 322 00:17:22,300 --> 00:17:25,470 This is just CS50 Codespaces, so feel free to pull it up and follow along, 323 00:17:25,470 --> 00:17:27,400 if you like. 324 00:17:27,400 --> 00:17:30,670 You may have to create this folder in the workspace directory, 325 00:17:30,670 --> 00:17:34,120 so you might have to go up one directory to avoid 326 00:17:34,120 --> 00:17:41,180 messing up CS50's own Git commands or the Git repositories that they have. 327 00:17:41,180 --> 00:17:44,070 But feel free to follow along, if you'd like. 328 00:17:44,070 --> 00:17:46,310 So I have what I call Git Seminar, so presumably, 329 00:17:46,310 --> 00:17:52,850 you could be using this folder for keeping track of your final project. 330 00:17:52,850 --> 00:17:56,040 Go ahead, whatever work that you do for your final project. 331 00:17:56,040 --> 00:17:59,690 So let me cd and do git-seminar. 332 00:17:59,690 --> 00:18:01,010 And let's see. 333 00:18:01,010 --> 00:18:04,190 This is currently an empty folder. 334 00:18:04,190 --> 00:18:08,920 So what I'm going to do now is, I'm going to create a file called hello.py 335 00:18:08,920 --> 00:18:11,640 and open that up. 336 00:18:11,640 --> 00:18:16,020 And let's say I do print Hello World. 337 00:18:16,020 --> 00:18:21,040 338 00:18:21,040 --> 00:18:24,390 So let's say this represents some set of initial changes 339 00:18:24,390 --> 00:18:26,310 that I made to my codebase. 340 00:18:26,310 --> 00:18:28,590 And now I realize, OK, this might be a good point 341 00:18:28,590 --> 00:18:32,480 to stop and save my work, using a commit. 342 00:18:32,480 --> 00:18:35,570 So right now, this codebase is just a directory. 343 00:18:35,570 --> 00:18:38,480 It doesn't have a Git repository associated with it. 344 00:18:38,480 --> 00:18:40,760 So how do I get started? 345 00:18:40,760 --> 00:18:50,240 How do I begin by initializing this repository as a Git repository? 346 00:18:50,240 --> 00:18:53,120 And feel free to send in what you think in the chat. 347 00:18:53,120 --> 00:18:53,845 git init. 348 00:18:53,845 --> 00:18:54,345 Yes. 349 00:18:54,345 --> 00:18:58,450 350 00:18:58,450 --> 00:18:59,950 OK. 351 00:18:59,950 --> 00:19:02,050 So it says, initialized empty Git repository, 352 00:19:02,050 --> 00:19:05,250 in the folder that I'm in right now. 353 00:19:05,250 --> 00:19:07,070 So before I do anything else, let me just 354 00:19:07,070 --> 00:19:11,360 run git status, which is one of the final commands that we saw. 355 00:19:11,360 --> 00:19:14,090 And this tells me the status of the repository. 356 00:19:14,090 --> 00:19:16,380 It says that there are no commits yet. 357 00:19:16,380 --> 00:19:21,412 And there is one unchecked file called hello.py. 358 00:19:21,412 --> 00:19:23,620 There's also nothing that's been added to the commit, 359 00:19:23,620 --> 00:19:25,610 but untracked files are, in fact, present. 360 00:19:25,610 --> 00:19:28,990 361 00:19:28,990 --> 00:19:36,160 So now that I have this information, how do I begin by creating a commit? 362 00:19:36,160 --> 00:19:39,340 What do I need to do to actually set up before I can create a commit? 363 00:19:39,340 --> 00:19:43,090 364 00:19:43,090 --> 00:19:47,657 And in fact, the git status output itself gives you some advice. 365 00:19:47,657 --> 00:19:48,490 You can use git add. 366 00:19:48,490 --> 00:19:49,810 Yes. 367 00:19:49,810 --> 00:19:51,743 So I'm going to do git add. 368 00:19:51,743 --> 00:19:53,660 Now, there are a couple of ways I can do this. 369 00:19:53,660 --> 00:19:57,940 I could do git add hello.py to specify or delegate 370 00:19:57,940 --> 00:20:01,550 that I want to track this one file called hello.py. 371 00:20:01,550 --> 00:20:04,300 But very often, you might have made changes across multiple files, 372 00:20:04,300 --> 00:20:06,310 and maybe you just want to track everything. 373 00:20:06,310 --> 00:20:08,470 And so another thing that you could do is just 374 00:20:08,470 --> 00:20:12,188 git add dot, which would add everything in the current folder. 375 00:20:12,188 --> 00:20:14,230 Dot just refers to the current directory, the one 376 00:20:14,230 --> 00:20:15,620 that you're in right now. 377 00:20:15,620 --> 00:20:19,590 And so git add dot just adds everything in the current directory, all 378 00:20:19,590 --> 00:20:24,240 the untracked changes, into the staging area. 379 00:20:24,240 --> 00:20:26,950 Let me run git status again really quick. 380 00:20:26,950 --> 00:20:31,530 There's still no commits, but now it is tracking this one file called hello.py. 381 00:20:31,530 --> 00:20:35,110 And this is the change that will be committed in the next one. 382 00:20:35,110 --> 00:20:37,870 And so like somebody sent in the chat, the next command 383 00:20:37,870 --> 00:20:41,840 is just git commit -m, commit message. 384 00:20:41,840 --> 00:20:45,520 And so let me say hi. 385 00:20:45,520 --> 00:20:50,860 OK, and doing this commit then returns some output. 386 00:20:50,860 --> 00:20:54,130 These few digits that you see over here are the first few digits 387 00:20:54,130 --> 00:20:57,370 of the commit hash. 388 00:20:57,370 --> 00:20:59,530 And you can see the commit message over here, 389 00:20:59,530 --> 00:21:04,540 the author, and other information about what the changes you made were. 390 00:21:04,540 --> 00:21:07,480 391 00:21:07,480 --> 00:21:14,430 Let me run git log, just to show you what the output of this looks like. 392 00:21:14,430 --> 00:21:18,540 Git log specifies a list of the previous commits that you made. 393 00:21:18,540 --> 00:21:22,980 Right now, there exists only one commit, and this is the entire commit hash 394 00:21:22,980 --> 00:21:25,140 of that commit that we just made. 395 00:21:25,140 --> 00:21:27,390 This is the commit message, say hi. 396 00:21:27,390 --> 00:21:30,930 And it also specifies the author, their email, the date, and so on. 397 00:21:30,930 --> 00:21:34,960 398 00:21:34,960 --> 00:21:35,460 OK. 399 00:21:35,460 --> 00:21:38,220 400 00:21:38,220 --> 00:21:42,690 So that hopefully gives you an idea of how to add in commit, 401 00:21:42,690 --> 00:21:50,410 but now let me try the very last step of saving changes, which is git push. 402 00:21:50,410 --> 00:21:53,960 But if I try to do that, it gives me an error. 403 00:21:53,960 --> 00:21:54,830 It says, fatal. 404 00:21:54,830 --> 00:21:57,110 No configured push destination. 405 00:21:57,110 --> 00:21:59,270 Either specify the URL from the command line, 406 00:21:59,270 --> 00:22:03,450 or configure a remote repository, using git remote add. 407 00:22:03,450 --> 00:22:06,200 So the reason for this is that, so far, everything that we've done 408 00:22:06,200 --> 00:22:11,360 lives entirely on our own device, on our local codebase. 409 00:22:11,360 --> 00:22:16,140 So far, we haven't associated this with anything on GitHub at all. 410 00:22:16,140 --> 00:22:19,620 And so what I'm going to do right now is exactly that. 411 00:22:19,620 --> 00:22:21,860 I'm going to show you to create a GitHub repository 412 00:22:21,860 --> 00:22:25,160 and then associate the two things so that whenever you make commits, 413 00:22:25,160 --> 00:22:28,230 you can then push them to the remote repository. 414 00:22:28,230 --> 00:22:33,710 The main advantage of doing this is that, one, if your own device crashes, 415 00:22:33,710 --> 00:22:36,210 like if you're developing locally, but your device crashes-- 416 00:22:36,210 --> 00:22:37,840 maybe your hard drive fails-- 417 00:22:37,840 --> 00:22:41,310 you will still have a backup of everything stored on GitHub. 418 00:22:41,310 --> 00:22:43,890 And perhaps more importantly, storing it on GitHub 419 00:22:43,890 --> 00:22:48,100 will allow other people, maybe your team members, to look at it. 420 00:22:48,100 --> 00:22:51,240 Or maybe if you're working on an open-source project, maybe somebody 421 00:22:51,240 --> 00:22:54,540 else looking, Googling something, might end up on your repository 422 00:22:54,540 --> 00:22:58,440 and may want to use your code, or download or contribute to it. 423 00:22:58,440 --> 00:23:01,090 424 00:23:01,090 --> 00:23:05,010 So how do we create a repository? 425 00:23:05,010 --> 00:23:10,400 So just go on to GitHub.com, and again, feel free to follow along if you want. 426 00:23:10,400 --> 00:23:15,060 You should see a New Repository button on the left sidebar, so just click 427 00:23:15,060 --> 00:23:15,560 on that. 428 00:23:15,560 --> 00:23:20,080 429 00:23:20,080 --> 00:23:21,890 I can specify a repository name. 430 00:23:21,890 --> 00:23:23,020 This can be anything. 431 00:23:23,020 --> 00:23:26,420 In my case, I'm just going to call it git-seminar. 432 00:23:26,420 --> 00:23:28,670 You can choose whether you want to release it publicly 433 00:23:28,670 --> 00:23:30,860 or you want to keep it private. 434 00:23:30,860 --> 00:23:34,010 I will choose private in this case. 435 00:23:34,010 --> 00:23:36,800 And I'm going to leave all of this unchecked, 436 00:23:36,800 --> 00:23:38,982 and I'm going to click Create Repository. 437 00:23:38,982 --> 00:23:42,760 438 00:23:42,760 --> 00:23:45,400 OK, so now it's created this repository. 439 00:23:45,400 --> 00:23:47,530 You can look at the URL. 440 00:23:47,530 --> 00:23:51,490 It has my username, followed by git-seminar. 441 00:23:51,490 --> 00:23:54,280 And it also provides some setup commands, 442 00:23:54,280 --> 00:23:58,840 which tell you how to link the two repositories together. 443 00:23:58,840 --> 00:24:01,690 And again, there are a couple of ways of doing this, depending on 444 00:24:01,690 --> 00:24:05,350 whether you're creating a new repository or linking an existing one. 445 00:24:05,350 --> 00:24:07,600 In our case, we're just pushing an existing repository 446 00:24:07,600 --> 00:24:12,040 from the command line because we already have a Git repository set up locally. 447 00:24:12,040 --> 00:24:16,570 You would follow these commands if you wanted to start one from scratch, 448 00:24:16,570 --> 00:24:20,530 but in our case, we just need to do these three things. 449 00:24:20,530 --> 00:24:22,870 While you're doing this, make sure you choose the SSH 450 00:24:22,870 --> 00:24:27,670 option if you set up with SSH, which most of you on Codespaces 451 00:24:27,670 --> 00:24:28,510 probably have. 452 00:24:28,510 --> 00:24:31,165 453 00:24:31,165 --> 00:24:33,860 But the first command that you need to put in 454 00:24:33,860 --> 00:24:39,200 is the command that adds this GitHub URL. 455 00:24:39,200 --> 00:24:42,200 And let me paste that in here. 456 00:24:42,200 --> 00:24:45,190 457 00:24:45,190 --> 00:24:49,260 So it adds this remote, which I'm calling origin, 458 00:24:49,260 --> 00:24:52,567 and it's linking it to this URL on GitHub, 459 00:24:52,567 --> 00:24:57,780 github.com slash my username slash git-seminar.git. 460 00:24:57,780 --> 00:25:00,300 So now the two repositories have been linked, 461 00:25:00,300 --> 00:25:03,020 and now I can specify the name of the main branch. 462 00:25:03,020 --> 00:25:06,270 And again, we'll talk about branches in a bit, so don't worry about this right 463 00:25:06,270 --> 00:25:09,040 now. 464 00:25:09,040 --> 00:25:11,790 And finally, I can do a git push. 465 00:25:11,790 --> 00:25:14,880 Now, if I just do git push on its own, it again 466 00:25:14,880 --> 00:25:18,270 will complain because GitHub doesn't already know 467 00:25:18,270 --> 00:25:20,470 there exists this branch called main. 468 00:25:20,470 --> 00:25:22,950 And so the very first time that you push, 469 00:25:22,950 --> 00:25:26,770 you'll have to do the set-upstream flag. 470 00:25:26,770 --> 00:25:30,470 You have to use the set-upstream flag. 471 00:25:30,470 --> 00:25:36,380 And so I will copy that in, paste that in, and hit Enter. 472 00:25:36,380 --> 00:25:38,307 And that's about it. 473 00:25:38,307 --> 00:25:40,640 Once it's done pushing, it'll tell you that a new branch 474 00:25:40,640 --> 00:25:42,290 has been created on GitHub. 475 00:25:42,290 --> 00:25:46,070 And this branch has been set up to track this remote branch called main 476 00:25:46,070 --> 00:25:47,860 from origin. 477 00:25:47,860 --> 00:25:52,940 And again, origin is the name of the remote, which is the remote on GitHub. 478 00:25:52,940 --> 00:25:59,060 So let me go back to the GitHub repository and refresh this page. 479 00:25:59,060 --> 00:26:02,710 And now you can see that it looks more familiar, like something that most 480 00:26:02,710 --> 00:26:04,930 GitHub repositories usually look like. 481 00:26:04,930 --> 00:26:07,150 It gives you a list of whatever folders and files 482 00:26:07,150 --> 00:26:11,480 that exist in your repository, along with the commit history. 483 00:26:11,480 --> 00:26:14,450 And so clicking on one commit, for example, will show you 484 00:26:14,450 --> 00:26:17,070 a list of commits that you made so far. 485 00:26:17,070 --> 00:26:19,280 And you can then click on any specific commit 486 00:26:19,280 --> 00:26:22,835 to have a visual representation of the changes that you made. 487 00:26:22,835 --> 00:26:24,710 And in this case, the only change that I made 488 00:26:24,710 --> 00:26:29,970 was to add this one line that says, print Hello World. 489 00:26:29,970 --> 00:26:31,560 And now I can go back to Code. 490 00:26:31,560 --> 00:26:35,190 I can also see I can open up any file and look at the existing 491 00:26:35,190 --> 00:26:36,690 version of that file on GitHub. 492 00:26:36,690 --> 00:26:44,120 493 00:26:44,120 --> 00:26:44,620 OK. 494 00:26:44,620 --> 00:26:46,745 Again, if you had any questions about that process, 495 00:26:46,745 --> 00:26:51,712 feel free to send it in the chat, and we can go over it in more detail. 496 00:26:51,712 --> 00:26:59,030 BERNIE LONGBOY: So Tarun, one of the questions early on was about-- 497 00:26:59,030 --> 00:27:04,670 although I believe one of our audience-- difference between GitHub and git 498 00:27:04,670 --> 00:27:06,040 clone. 499 00:27:06,040 --> 00:27:09,290 I think you might have mentioned that, if you want to just go over that again? 500 00:27:09,290 --> 00:27:10,850 TARUN PRASAD: Yes. 501 00:27:10,850 --> 00:27:14,300 So I guess I'll talk about the difference between Git and GitHub 502 00:27:14,300 --> 00:27:15,920 first. 503 00:27:15,920 --> 00:27:20,510 Git is a command line tool that lives entirely locally on your device, 504 00:27:20,510 --> 00:27:23,480 or in this case, it's on Codespaces. 505 00:27:23,480 --> 00:27:27,470 So Git is just the name of the command-line tool itself. 506 00:27:27,470 --> 00:27:31,730 And GitHub is essentially the name of a website or a company 507 00:27:31,730 --> 00:27:34,520 which provides some services, which lets you store these Git 508 00:27:34,520 --> 00:27:38,360 repositories on their server. 509 00:27:38,360 --> 00:27:43,370 And so when you do git clone, git clone is a very specific Git command 510 00:27:43,370 --> 00:27:47,760 which lets you download an existing GitHub repository, 511 00:27:47,760 --> 00:27:53,020 because GitHub repositories don't live on your device unless you created them. 512 00:27:53,020 --> 00:27:59,130 So maybe if you wanted to look at the GitHub repository of a classmate, 513 00:27:59,130 --> 00:28:03,090 maybe a classmate has been working on a personal project, 514 00:28:03,090 --> 00:28:04,680 and maybe you want to check it out. 515 00:28:04,680 --> 00:28:06,430 Maybe you want to look at the code. 516 00:28:06,430 --> 00:28:11,820 So what you can do is then is go onto the GitHub.com link, the URL, 517 00:28:11,820 --> 00:28:17,010 and then use git clone along with this URL. 518 00:28:17,010 --> 00:28:19,890 So if you click on the green Code button on GitHub, 519 00:28:19,890 --> 00:28:23,280 it'll specify a URL for the repository. 520 00:28:23,280 --> 00:28:28,740 And again, it's preferable to use SSH. 521 00:28:28,740 --> 00:28:31,950 And you can basically download this, using the command, git clone, 522 00:28:31,950 --> 00:28:33,600 so git clone, followed by the URL. 523 00:28:33,600 --> 00:28:36,222 524 00:28:36,222 --> 00:28:37,920 BERNIE LONGBOY: OK. 525 00:28:37,920 --> 00:28:39,810 Next question is from Daniel. 526 00:28:39,810 --> 00:28:42,090 Just to be clear, the command line refers 527 00:28:42,090 --> 00:28:47,640 to the Terminal on MacOS and PowerShell on Windows, correct? 528 00:28:47,640 --> 00:28:48,450 TARUN PRASAD: Yes. 529 00:28:48,450 --> 00:28:52,620 On Windows, you can use either PowerShell or Command Prompt. 530 00:28:52,620 --> 00:28:54,855 But on Mac, it is the Terminal, yes. 531 00:28:54,855 --> 00:28:56,310 BERNIE LONGBOY: OK. 532 00:28:56,310 --> 00:29:00,180 And Amy asks, so will our files be saved on our computer and GitHub, 533 00:29:00,180 --> 00:29:02,438 or only on GitHub? 534 00:29:02,438 --> 00:29:04,480 TARUN PRASAD: Yes, that's a really good question. 535 00:29:04,480 --> 00:29:06,983 And again, that brings up the distinction between using-- 536 00:29:06,983 --> 00:29:07,900 BERNIE LONGBOY: Local. 537 00:29:07,900 --> 00:29:11,100 TARUN PRASAD: --git locally and pushing things to GitHub. 538 00:29:11,100 --> 00:29:14,230 So as long as you just do git add and git commit and git add and git 539 00:29:14,230 --> 00:29:17,880 commit and make changes, it's only going to be saved on your computer. 540 00:29:17,880 --> 00:29:21,120 But as soon as you do git push, after you add the remote and the URL 541 00:29:21,120 --> 00:29:25,470 and everything, then all of your changes are going to be pushed to GitHub. 542 00:29:25,470 --> 00:29:29,496 And then it'll be stored on both the local device, your computer, 543 00:29:29,496 --> 00:29:31,786 and on GitHub. 544 00:29:31,786 --> 00:29:35,280 BERNIE LONGBOY: And then this question came up from Austin, 545 00:29:35,280 --> 00:29:38,640 and I believe Anjalee also asked it. 546 00:29:38,640 --> 00:29:43,020 Why SSH and not HTTPS? 547 00:29:43,020 --> 00:29:45,180 TARUN PRASAD: Yeah, also a good question. 548 00:29:45,180 --> 00:29:52,020 So far, I think GitHub has been allowing both HTTPS and SSH as possible ways 549 00:29:52,020 --> 00:29:55,230 of downloading code and authenticating. 550 00:29:55,230 --> 00:29:57,780 So essentially, they're both means of authenticating yourself 551 00:29:57,780 --> 00:30:00,750 to allow you to, for example, push to a repository 552 00:30:00,750 --> 00:30:03,920 or to download a repository and so on. 553 00:30:03,920 --> 00:30:07,520 But recently, I think GitHub has decided for security reasons 554 00:30:07,520 --> 00:30:09,110 to switch entirely to SSH. 555 00:30:09,110 --> 00:30:14,630 It's supposed to be more secure than using HTTPS. 556 00:30:14,630 --> 00:30:17,720 So that's the reason we're also pushing towards SSH these days as well. 557 00:30:17,720 --> 00:30:38,210 558 00:30:38,210 --> 00:30:38,710 OK. 559 00:30:38,710 --> 00:30:43,045 If there are no other questions, we can continue. 560 00:30:43,045 --> 00:30:44,185 BERNIE LONGBOY: Let's see. 561 00:30:44,185 --> 00:30:49,470 562 00:30:49,470 --> 00:30:53,084 What is SHH and HTTPS? 563 00:30:53,084 --> 00:30:55,830 564 00:30:55,830 --> 00:30:56,700 TARUN PRASAD: Yeah. 565 00:30:56,700 --> 00:30:58,200 So SSH and HTTPS-- 566 00:30:58,200 --> 00:30:59,700 I might have mentioned this before-- 567 00:30:59,700 --> 00:31:02,730 are essentially ways of authenticating yourself. 568 00:31:02,730 --> 00:31:07,380 And they specify different protocols for authentication 569 00:31:07,380 --> 00:31:11,322 as well as downloading, and pushing forward, and so on. 570 00:31:11,322 --> 00:31:14,850 BERNIE LONGBOY: And can we just take this last one, 571 00:31:14,850 --> 00:31:16,840 and then we'll go into the next part? 572 00:31:16,840 --> 00:31:19,120 And then I will come back to the questions again. 573 00:31:19,120 --> 00:31:22,620 We could see your first line of code in the first commit. 574 00:31:22,620 --> 00:31:26,550 Did you create the file with no code in it and pushed it, 575 00:31:26,550 --> 00:31:29,400 or with the included line of code? 576 00:31:29,400 --> 00:31:30,180 And that was-- 577 00:31:30,180 --> 00:31:30,435 TARUN PRASAD: So I-- 578 00:31:30,435 --> 00:31:31,643 BERNIE LONGBOY: --from Bruno. 579 00:31:31,643 --> 00:31:32,940 TARUN PRASAD: Yeah. 580 00:31:32,940 --> 00:31:35,370 I created the file, and then included the line of code, 581 00:31:35,370 --> 00:31:38,110 and then pushed the two things together. 582 00:31:38,110 --> 00:31:40,830 And so that was the order I did it in. 583 00:31:40,830 --> 00:31:43,410 I created the file, included the line of code, 584 00:31:43,410 --> 00:31:46,920 then did the whole git add, git commit, git push. 585 00:31:46,920 --> 00:31:50,580 And then that change, the change where I essentially created the file 586 00:31:50,580 --> 00:31:53,340 and added the line of code, was represented on GitHub. 587 00:31:53,340 --> 00:32:00,940 588 00:32:00,940 --> 00:32:04,680 BERNIE LONGBOY: OK, Tarun. 589 00:32:04,680 --> 00:32:06,370 TARUN PRASAD: OK, awesome. 590 00:32:06,370 --> 00:32:10,330 So let's go on to the next portion of today's seminar. 591 00:32:10,330 --> 00:32:15,320 And this is the main portion which actually focuses on collaboration. 592 00:32:15,320 --> 00:32:20,900 So so far, we've seen that we can save changes, and track changes, and undo 593 00:32:20,900 --> 00:32:23,393 commits, revert changes, and so on. 594 00:32:23,393 --> 00:32:26,060 And that's all well and good when you're the only person working 595 00:32:26,060 --> 00:32:27,817 on your repository. 596 00:32:27,817 --> 00:32:30,650 But in most of your projects, you're probably working with a partner 597 00:32:30,650 --> 00:32:33,060 or with a team member. 598 00:32:33,060 --> 00:32:36,240 And in such cases, it's very useful to know 599 00:32:36,240 --> 00:32:40,230 of ways which will help you collaborate together, 600 00:32:40,230 --> 00:32:44,860 pushing different code to different files, 601 00:32:44,860 --> 00:32:49,000 so even modifying the same lines of code in different ways. 602 00:32:49,000 --> 00:32:53,710 And Git allows you to do all of this in a very seamless way. 603 00:32:53,710 --> 00:32:57,680 The first command that's very useful for this is git pull. 604 00:32:57,680 --> 00:33:00,290 So git pull downloads changes and commits 605 00:33:00,290 --> 00:33:03,650 that have been pushed by others to the remote, 606 00:33:03,650 --> 00:33:06,820 and merges them into your own local repository. 607 00:33:06,820 --> 00:33:09,570 And this is very useful when collaborating with others because you 608 00:33:09,570 --> 00:33:12,450 won't be the only one pushing code. 609 00:33:12,450 --> 00:33:16,710 So for example, let's say you're the one who did the git init, 610 00:33:16,710 --> 00:33:19,530 you made some changes, you added the remote, 611 00:33:19,530 --> 00:33:23,400 you created the GitHub repository, and you push all of your changes. 612 00:33:23,400 --> 00:33:28,610 But in the meanwhile, let's say that your group member 613 00:33:28,610 --> 00:33:33,080 decided to go onto your GitHub URL, your GitHub repository. 614 00:33:33,080 --> 00:33:36,410 They decided to do a git clone, so they downloaded all of the files 615 00:33:36,410 --> 00:33:39,350 that you pushed, and then they made their own changes. 616 00:33:39,350 --> 00:33:42,500 And they also did the whole git add, git commit, git push, 617 00:33:42,500 --> 00:33:47,720 and now their changes have also been pushed into the GitHub repository. 618 00:33:47,720 --> 00:33:51,890 In such a case, GitHub knows about these changes because they pushed it. 619 00:33:51,890 --> 00:33:55,610 But the local version of the code that lives in your device 620 00:33:55,610 --> 00:33:58,940 or that lives on Codespaces doesn't know of those changes 621 00:33:58,940 --> 00:34:02,040 because all of these changes are only on GitHub. 622 00:34:02,040 --> 00:34:06,630 But how do you sync your version of the code, your local version of the code, 623 00:34:06,630 --> 00:34:08,820 with the changes that have been pushed by others? 624 00:34:08,820 --> 00:34:11,492 Well, you use git pull. 625 00:34:11,492 --> 00:34:13,909 So what git pull does is it downloads all of these changes 626 00:34:13,909 --> 00:34:18,020 and then merges them, adds those commits on top of whatever commits you already 627 00:34:18,020 --> 00:34:21,900 made, and then merges them together. 628 00:34:21,900 --> 00:34:24,679 So technically, git pull is actually a combination 629 00:34:24,679 --> 00:34:29,210 of two other commands called a fetch and a merge. 630 00:34:29,210 --> 00:34:31,610 We won't be talking about that in too much detail today, 631 00:34:31,610 --> 00:34:34,550 but do feel free to look that up if you want to learn more about this. 632 00:34:34,550 --> 00:34:39,110 633 00:34:39,110 --> 00:34:43,580 OK, coming to possibly one of the more important topics and very useful topics 634 00:34:43,580 --> 00:34:45,907 of today's seminar, branches. 635 00:34:45,907 --> 00:34:48,449 And there were some questions earlier about branches as well, 636 00:34:48,449 --> 00:34:52,540 so hopefully this will clear things up a little bit. 637 00:34:52,540 --> 00:34:55,480 So what exactly are branches? 638 00:34:55,480 --> 00:34:59,650 Like in the XKCD comic at the very beginning, it's really pretty simple. 639 00:34:59,650 --> 00:35:04,390 Just think of branches as pointers to commits. 640 00:35:04,390 --> 00:35:05,520 So what does that mean? 641 00:35:05,520 --> 00:35:09,360 I think this illustration will help clear things up a little bit. 642 00:35:09,360 --> 00:35:13,530 Each of these hexadecimal numbers that you see in these white boxes, each 643 00:35:13,530 --> 00:35:15,780 of those represents a commit. 644 00:35:15,780 --> 00:35:19,600 And each commit points to the previous one. 645 00:35:19,600 --> 00:35:24,630 So maybe the 98ca9 commit was made first, and then the 34ac2 commit, 646 00:35:24,630 --> 00:35:27,735 then f30ab, and then 87ab2. 647 00:35:27,735 --> 00:35:30,440 648 00:35:30,440 --> 00:35:34,580 But you also see these other red boxes, which point at commits. 649 00:35:34,580 --> 00:35:39,870 And these red boxes are essentially what branches are. 650 00:35:39,870 --> 00:35:42,180 In most cases, you'll have some default branch, 651 00:35:42,180 --> 00:35:44,520 usually called something like main. 652 00:35:44,520 --> 00:35:47,190 But you can also create other branches, which 653 00:35:47,190 --> 00:35:50,280 will be very useful when testing experimental features 654 00:35:50,280 --> 00:35:54,790 or when fixing a bug, because you don't want to mess up the main branch. 655 00:35:54,790 --> 00:35:58,890 So for example, if you have a working version on your main branch, which 656 00:35:58,890 --> 00:36:01,830 other people who are also working on this project are using, 657 00:36:01,830 --> 00:36:07,730 then you don't want to push potentially buggy commits onto the main branch. 658 00:36:07,730 --> 00:36:11,620 What you can do instead is create a separate branch. 659 00:36:11,620 --> 00:36:13,940 I will see the commands to do that in a minute. 660 00:36:13,940 --> 00:36:18,400 But you can create a separate branch, commit to that branch, 661 00:36:18,400 --> 00:36:22,590 and then push those commits to that branch on GitHub. 662 00:36:22,590 --> 00:36:25,180 And so the main default branch will be unaffected, 663 00:36:25,180 --> 00:36:27,137 and anybody else can also clone the repository 664 00:36:27,137 --> 00:36:29,470 and pull code and all of that onto their own main branch 665 00:36:29,470 --> 00:36:31,900 without it affecting anything. 666 00:36:31,900 --> 00:36:34,600 But then once you're completely done with your feature, 667 00:36:34,600 --> 00:36:37,390 once you're sure that everything works in your feature branch, 668 00:36:37,390 --> 00:36:41,230 then you can decide to merge it back into the main branch. 669 00:36:41,230 --> 00:36:44,500 And in fact, this is a very common workflow, as we will see in a second 670 00:36:44,500 --> 00:36:46,080 as well. 671 00:36:46,080 --> 00:36:48,270 Any time you work on a big project, especially when 672 00:36:48,270 --> 00:36:50,152 you're collaborating with many other people, 673 00:36:50,152 --> 00:36:52,110 this is a very common workflow that you'll use. 674 00:36:52,110 --> 00:36:55,240 675 00:36:55,240 --> 00:37:00,210 Now, what are the actual commands to work with branches? 676 00:37:00,210 --> 00:37:04,510 The first one that's very useful is, how do you create a branch. 677 00:37:04,510 --> 00:37:09,360 So for example, let's say I want to create a branch called feature. 678 00:37:09,360 --> 00:37:13,470 Then I can do that by running the command, git branch, 679 00:37:13,470 --> 00:37:18,490 followed by feature or whatever branch name you want to specify. 680 00:37:18,490 --> 00:37:21,000 So git branch feature creates that branch 681 00:37:21,000 --> 00:37:26,210 and makes the branch point to the commit that you're at right now. 682 00:37:26,210 --> 00:37:29,200 So for example, let's say that the latest commit 683 00:37:29,200 --> 00:37:33,090 that I made was this f30ab commit. 684 00:37:33,090 --> 00:37:36,780 And that's what main is pointing at because that's 685 00:37:36,780 --> 00:37:38,930 where the main branch was. 686 00:37:38,930 --> 00:37:42,470 But now, if I create a new branch by using git branch feature, 687 00:37:42,470 --> 00:37:50,050 then feature will also point to f30ab over here. 688 00:37:50,050 --> 00:37:53,000 But any further commits that I make will be associated 689 00:37:53,000 --> 00:37:55,000 with the main branch and not the feature branch, 690 00:37:55,000 --> 00:37:57,460 because git branch doesn't actually change or switch 691 00:37:57,460 --> 00:38:00,190 which branch you're in right now. 692 00:38:00,190 --> 00:38:02,320 If you do want to switch the branch as well, 693 00:38:02,320 --> 00:38:06,940 then you use what's called git checkout, so git checkout with the -b flag, 694 00:38:06,940 --> 00:38:08,430 followed by the branch name. 695 00:38:08,430 --> 00:38:14,130 -b just specifies that you're creating a new branch. 696 00:38:14,130 --> 00:38:18,030 So git checkout, -b, followed by feature, and that'll do the same thing, 697 00:38:18,030 --> 00:38:19,860 but also, any further commits that you make 698 00:38:19,860 --> 00:38:24,730 will be associated with the feature branch and not the main branch. 699 00:38:24,730 --> 00:38:29,540 Once you've created a branch, each time you create a new commit, 700 00:38:29,540 --> 00:38:33,740 the pointer will also advance, along with the commits themselves, 701 00:38:33,740 --> 00:38:37,477 the pointer of whatever branch that you're in right now. 702 00:38:37,477 --> 00:38:39,310 So for example, if I'm in the feature branch 703 00:38:39,310 --> 00:38:43,300 and it's pointing to the f30ab commit, then creating a new commit 704 00:38:43,300 --> 00:38:46,330 will essentially result in what it looks like right now. 705 00:38:46,330 --> 00:38:50,620 It'll create this 87ab2 commit, and then it'll also move the feature branch 706 00:38:50,620 --> 00:38:53,120 to point at the latest commit. 707 00:38:53,120 --> 00:38:56,058 Now, notice that the main branch pointer doesn't actually move, 708 00:38:56,058 --> 00:38:58,100 and that's because you're not in the main branch. 709 00:38:58,100 --> 00:39:00,470 And so if you go back and look at the main branch, 710 00:39:00,470 --> 00:39:06,200 it'll still look exactly like what the repository looked like when you last 711 00:39:06,200 --> 00:39:08,280 made the f30ab commit. 712 00:39:08,280 --> 00:39:10,297 And so the changes in this last 87ab2 commit 713 00:39:10,297 --> 00:39:12,380 will not actually be reflected in the main branch, 714 00:39:12,380 --> 00:39:16,125 and that's exactly what we want because we don't want to mess with the working 715 00:39:16,125 --> 00:39:17,750 version of the code in the main branch. 716 00:39:17,750 --> 00:39:23,050 717 00:39:23,050 --> 00:39:25,740 You can also switch between branches, using just git checkout 718 00:39:25,740 --> 00:39:28,327 without the -b flag. 719 00:39:28,327 --> 00:39:30,910 And you can just do git checkout, followed by the branch name, 720 00:39:30,910 --> 00:39:34,850 and that'll change the branch you're in right now. 721 00:39:34,850 --> 00:39:38,150 You can also push a new branch to GitHub, 722 00:39:38,150 --> 00:39:42,350 and we saw this earlier with the main branch. 723 00:39:42,350 --> 00:39:44,150 But the way you do it the very first time 724 00:39:44,150 --> 00:39:47,900 is, you use this -u or this set-upstream flag, 725 00:39:47,900 --> 00:39:51,090 which tells GitHub that a new branch is coming in. 726 00:39:51,090 --> 00:39:54,920 And so you can use git push, -u, origin space, the branch name. 727 00:39:54,920 --> 00:39:57,802 728 00:39:57,802 --> 00:39:59,760 So hopefully that makes sense, but again, we'll 729 00:39:59,760 --> 00:40:01,890 see a demo of this in a bit. 730 00:40:01,890 --> 00:40:06,108 731 00:40:06,108 --> 00:40:08,400 This is a term that you would have heard of very often, 732 00:40:08,400 --> 00:40:10,800 any time you look at a GitHub repository, 733 00:40:10,800 --> 00:40:15,515 or maybe if you've done an internship in the past, or something like that, 734 00:40:15,515 --> 00:40:17,356 pull requests. 735 00:40:17,356 --> 00:40:20,030 So pull requests are not a Git feature, which 736 00:40:20,030 --> 00:40:24,120 means they're not something that you would work with on the command line. 737 00:40:24,120 --> 00:40:27,890 But rather, they're a feature that's specific to GitHub, but very useful 738 00:40:27,890 --> 00:40:30,600 in collaborative repositories. 739 00:40:30,600 --> 00:40:34,230 And so other remote providers like GitLab or Bitbucket 740 00:40:34,230 --> 00:40:37,740 might also have analogous features, but possibly with different names. 741 00:40:37,740 --> 00:40:39,570 I think GitLab calls it a merge request. 742 00:40:39,570 --> 00:40:42,140 743 00:40:42,140 --> 00:40:46,910 So a pull request is essentially a request to merge in the changes 744 00:40:46,910 --> 00:40:50,480 that you've pushed to a branch back into the main branch, or any other branch, 745 00:40:50,480 --> 00:40:53,540 but usually the main branch. 746 00:40:53,540 --> 00:40:57,380 So for example, once you've completed the changes 747 00:40:57,380 --> 00:40:59,480 that you want to make in your feature branch, 748 00:40:59,480 --> 00:41:03,080 you can push your feature branch, then go into GitHub, 749 00:41:03,080 --> 00:41:04,970 and you'll see a Pull Request tab. 750 00:41:04,970 --> 00:41:08,690 And over there, you can click on the Create Pull Request button, 751 00:41:08,690 --> 00:41:11,000 and then choose which branch you are merging from 752 00:41:11,000 --> 00:41:13,620 and which branch you're merging into. 753 00:41:13,620 --> 00:41:16,130 And then what that will do is it'll create a request 754 00:41:16,130 --> 00:41:18,636 to merge those changes in. 755 00:41:18,636 --> 00:41:21,080 And so a very common workflow when working in a group 756 00:41:21,080 --> 00:41:24,800 is to always commit to a feature branch and never directly to main, 757 00:41:24,800 --> 00:41:27,920 and then to push the branch to the remote, open up a request, 758 00:41:27,920 --> 00:41:30,440 have somebody else in the team review the pull request, 759 00:41:30,440 --> 00:41:33,485 and either approve it or request changes. 760 00:41:33,485 --> 00:41:35,360 And then once the changes have been approved, 761 00:41:35,360 --> 00:41:38,540 you can then merge it into main, and you can usually do this directly 762 00:41:38,540 --> 00:41:39,470 on GitHub itself. 763 00:41:39,470 --> 00:41:42,000 764 00:41:42,000 --> 00:41:45,240 And again, we'll see how exactly to do that in a minute. 765 00:41:45,240 --> 00:41:48,452 766 00:41:48,452 --> 00:41:50,660 BERNIE LONGBOY: Tarun, is this a good break to take-- 767 00:41:50,660 --> 00:41:50,750 TARUN PRASAD: Yeah. 768 00:41:50,750 --> 00:41:52,876 BERNIE LONGBOY: --a couple of questions from the audience? 769 00:41:52,876 --> 00:41:53,780 TARUN PRASAD: Yeah, we can take-- 770 00:41:53,780 --> 00:41:54,170 BERNIE LONGBOY: OK. 771 00:41:54,170 --> 00:41:54,470 TARUN PRASAD: --those questions. 772 00:41:54,470 --> 00:41:55,553 BERNIE LONGBOY: All right. 773 00:41:55,553 --> 00:41:59,940 So, our fantastic audience, I did not forget you here. 774 00:41:59,940 --> 00:42:03,200 So I am going now to-- 775 00:42:03,200 --> 00:42:05,480 let's see. 776 00:42:05,480 --> 00:42:07,880 I think, Leo, we answered yours. 777 00:42:07,880 --> 00:42:09,500 Bruno. 778 00:42:09,500 --> 00:42:10,910 This question comes from Bruno. 779 00:42:10,910 --> 00:42:14,180 I'm trying to use Git in VS Code, but it appears you 780 00:42:14,180 --> 00:42:16,670 are in a repository managed by CS50. 781 00:42:16,670 --> 00:42:18,300 Git is disabled. 782 00:42:18,300 --> 00:42:21,620 So that's not really a question, but the more I think, 783 00:42:21,620 --> 00:42:24,020 is that problem still going on? 784 00:42:24,020 --> 00:42:24,770 TARUN PRASAD: Yes. 785 00:42:24,770 --> 00:42:27,978 If you face that, one thing that I would suggest is just going up one folder, 786 00:42:27,978 --> 00:42:29,067 so maybe using cd.. 787 00:42:29,067 --> 00:42:31,970 788 00:42:31,970 --> 00:42:34,560 And then you'll be in your workspaces folder. 789 00:42:34,560 --> 00:42:37,250 And then you can essentially create a new folder altogether, 790 00:42:37,250 --> 00:42:41,048 so make something else, like make the project or something. 791 00:42:41,048 --> 00:42:42,090 BERNIE LONGBOY: This is-- 792 00:42:42,090 --> 00:42:42,290 TARUN PRASAD: And once-- 793 00:42:42,290 --> 00:42:42,380 BERNIE LONGBOY: --something else-- 794 00:42:42,380 --> 00:42:43,010 TARUN PRASAD: --you do that-- 795 00:42:43,010 --> 00:42:44,990 BERNIE LONGBOY: --that our students always-- 796 00:42:44,990 --> 00:42:47,882 so it's common, common. 797 00:42:47,882 --> 00:42:49,290 TARUN PRASAD: Yeah. 798 00:42:49,290 --> 00:42:50,890 BERNIE LONGBOY: OK. 799 00:42:50,890 --> 00:42:51,400 Let's see. 800 00:42:51,400 --> 00:42:52,540 What else do we have here? 801 00:42:52,540 --> 00:42:55,700 802 00:42:55,700 --> 00:42:56,200 Let's see. 803 00:42:56,200 --> 00:43:02,350 From Leo, so is commit 87ab2 just a copy of f30ab 804 00:43:02,350 --> 00:43:06,400 to create a new branch with feature, or are they 805 00:43:06,400 --> 00:43:09,160 actually based on different versions? 806 00:43:09,160 --> 00:43:11,090 TARUN PRASAD: Yeah, good question. 807 00:43:11,090 --> 00:43:15,410 So let me go back to that slide. 808 00:43:15,410 --> 00:43:19,522 So when you create a new branch, there are no new commits that are created. 809 00:43:19,522 --> 00:43:21,730 So the first time that you create the feature branch, 810 00:43:21,730 --> 00:43:26,120 it will still point only at the f30ab, and this 87ab2 commit 811 00:43:26,120 --> 00:43:28,880 doesn't exist yet. 812 00:43:28,880 --> 00:43:31,730 What happens is that if you're on the feature branch, 813 00:43:31,730 --> 00:43:37,340 and you then do a new commit, like you actually make some changes 814 00:43:37,340 --> 00:43:39,590 and you actually do git commit, that's when 815 00:43:39,590 --> 00:43:42,590 this 87ab2 commit might be created. 816 00:43:42,590 --> 00:43:44,540 And then the feature branch moves forward 817 00:43:44,540 --> 00:43:48,730 to point at that commit instead of the original commit. 818 00:43:48,730 --> 00:43:55,140 BERNIE LONGBOY: OK, and this one is just a good one to probably clarify, Tarun. 819 00:43:55,140 --> 00:43:59,250 I did it in a direct message, but it's probably good for the entire audience 820 00:43:59,250 --> 00:44:02,640 to know. git clone is a part of GitHub. 821 00:44:02,640 --> 00:44:05,340 822 00:44:05,340 --> 00:44:09,510 I believe the question was, do we require an account on git clone, 823 00:44:09,510 --> 00:44:14,700 like we need a GitHub account, or we are just using it online? 824 00:44:14,700 --> 00:44:18,510 So it's really the same account, but I'll let Tarun go ahead 825 00:44:18,510 --> 00:44:22,125 and maybe further elaborate on that one. 826 00:44:22,125 --> 00:44:22,980 TARUN PRASAD: Yeah. 827 00:44:22,980 --> 00:44:26,700 If I understood that question correctly, you 828 00:44:26,700 --> 00:44:31,920 don't generally need a GitHub account to do a git clone. 829 00:44:31,920 --> 00:44:35,400 You should be able to usually just do git clone if it's 830 00:44:35,400 --> 00:44:38,580 a public, open-source repository. 831 00:44:38,580 --> 00:44:40,830 But you may need a GitHub account if you want 832 00:44:40,830 --> 00:44:44,040 to clone a private repository that only you have access to. 833 00:44:44,040 --> 00:44:47,700 Maybe if it's a repository that your project partner created and you decided 834 00:44:47,700 --> 00:44:54,300 to make it private, then you would need to log in, authenticate using GitHub, 835 00:44:54,300 --> 00:44:58,110 and then once you do that, you can then do git clone, whatever URL, 836 00:44:58,110 --> 00:45:02,450 and that should download everything. 837 00:45:02,450 --> 00:45:05,280 Let me know if I didn't answer the question correctly, 838 00:45:05,280 --> 00:45:07,640 but I will try again. 839 00:45:07,640 --> 00:45:12,909 840 00:45:12,909 --> 00:45:15,490 BERNIE LONGBOY: This question is from Sarah. 841 00:45:15,490 --> 00:45:19,330 Actually, she asks, could you please repeat what branches do? 842 00:45:19,330 --> 00:45:21,280 TARUN PRASAD: Yes, of course. 843 00:45:21,280 --> 00:45:25,420 Branches are one of the more confusing features in Git. 844 00:45:25,420 --> 00:45:29,470 So branches, again, are essentially pointers to commits, 845 00:45:29,470 --> 00:45:35,340 and the point of using branches is to separate different things 846 00:45:35,340 --> 00:45:37,500 that you're working on currently. 847 00:45:37,500 --> 00:45:40,890 So for example, let's say that, simultaneously, you 848 00:45:40,890 --> 00:45:45,182 have some existing working version of your entire codebase. 849 00:45:45,182 --> 00:45:46,890 So let's say you're working on a web app, 850 00:45:46,890 --> 00:45:49,500 and you have some preliminary version ready to go 851 00:45:49,500 --> 00:45:51,495 and working on the main branch. 852 00:45:51,495 --> 00:45:53,460 And you're afraid that any time you push some 853 00:45:53,460 --> 00:45:57,220 commits to that, you might mess it up, things might stop working, 854 00:45:57,220 --> 00:46:00,940 and so don't want to push anything to the main default branch. 855 00:46:00,940 --> 00:46:08,640 So what you can do to get past this is, essentially, create a new branch 856 00:46:08,640 --> 00:46:11,850 and do all of your work in this experimental branch. 857 00:46:11,850 --> 00:46:16,470 So think of this as sort of copy-pasting your entire codebase in a completely 858 00:46:16,470 --> 00:46:21,810 different directory and just messing with whatever 859 00:46:21,810 --> 00:46:25,380 changes that you want to make, whatever box you want to fix in the copied, 860 00:46:25,380 --> 00:46:26,390 duplicate version. 861 00:46:26,390 --> 00:46:28,140 And then, once everything is working, then 862 00:46:28,140 --> 00:46:31,710 you go back to your original directory and copy over the changes. 863 00:46:31,710 --> 00:46:35,104 That's essentially what you're doing with the branches workflow. 864 00:46:35,104 --> 00:46:37,520 BERNIE LONGBOY: And just to keep things moving forward, 865 00:46:37,520 --> 00:46:41,150 I just want to reiterate that we will have a recording available, 866 00:46:41,150 --> 00:46:45,930 so the questions that were answered previously. 867 00:46:45,930 --> 00:46:46,790 And let's see. 868 00:46:46,790 --> 00:46:50,240 869 00:46:50,240 --> 00:46:51,260 Let's see. 870 00:46:51,260 --> 00:46:52,580 Oh, thanks, Anais. 871 00:46:52,580 --> 00:46:55,850 She just put in a great resource there. 872 00:46:55,850 --> 00:46:57,422 OK. 873 00:46:57,422 --> 00:46:58,850 Tarun, do you want to continue? 874 00:46:58,850 --> 00:46:59,678 We're in our last-- 875 00:46:59,678 --> 00:47:00,470 TARUN PRASAD: Yeah. 876 00:47:00,470 --> 00:47:01,250 BERNIE LONGBOY: --few minutes here. 877 00:47:01,250 --> 00:47:01,490 TARUN PRASAD: Thank you. 878 00:47:01,490 --> 00:47:03,273 We have about 10 minutes left. 879 00:47:03,273 --> 00:47:06,520 880 00:47:06,520 --> 00:47:09,190 So I'll talk through this very quickly, but because this 881 00:47:09,190 --> 00:47:12,490 is something that many people often have trouble working 882 00:47:12,490 --> 00:47:14,950 with when they're first doing Git. 883 00:47:14,950 --> 00:47:17,050 So usually, when you try to pull code or try 884 00:47:17,050 --> 00:47:20,780 to merge in one branch with another, it will work completely fine, 885 00:47:20,780 --> 00:47:24,453 especially if the changes are in completely different portions 886 00:47:24,453 --> 00:47:25,120 of the codebase. 887 00:47:25,120 --> 00:47:27,890 They're completely different files, for example. 888 00:47:27,890 --> 00:47:30,710 But occasionally, you'll encounter that you've 889 00:47:30,710 --> 00:47:34,100 made some changes to a specific file, but maybe somebody else 890 00:47:34,100 --> 00:47:37,800 has also made some different changes with the same lines in those files, 891 00:47:37,800 --> 00:47:40,430 but in some sort of a different way. 892 00:47:40,430 --> 00:47:43,810 So Git in such cases won't know how to automatically pull the code 893 00:47:43,810 --> 00:47:45,310 or to automatically merge them. 894 00:47:45,310 --> 00:47:49,280 And this results in what's called a merge conflict. 895 00:47:49,280 --> 00:47:53,240 So this is a code sample from, I believe, CS61. 896 00:47:53,240 --> 00:47:56,060 CS61 also has a very useful Git tutorial available 897 00:47:56,060 --> 00:47:58,980 online, so you should definitely check that out, if you can. 898 00:47:58,980 --> 00:48:00,980 And this is a code sample from there. 899 00:48:00,980 --> 00:48:04,940 And you can see that there are two very similar lines over here. 900 00:48:04,940 --> 00:48:08,180 This pointers of i equals malloc of i or 1, 901 00:48:08,180 --> 00:48:12,280 and pointers i equals malloc of i plus 1. 902 00:48:12,280 --> 00:48:17,860 So in particular, the version of the code between these left-angle brackets 903 00:48:17,860 --> 00:48:20,032 and the equals is one version. 904 00:48:20,032 --> 00:48:22,240 And the incoming version is what's between the equals 905 00:48:22,240 --> 00:48:25,600 and the right-angle bracket, so essentially between these two lines 906 00:48:25,600 --> 00:48:28,240 and between these two lines. 907 00:48:28,240 --> 00:48:30,510 And so when you encounter a merge conflict, 908 00:48:30,510 --> 00:48:33,390 it will essentially insert these angle brackets and equals 909 00:48:33,390 --> 00:48:36,940 lines into whatever files have those merge conflicts. 910 00:48:36,940 --> 00:48:40,050 And then it's up to you to manually resolve them. 911 00:48:40,050 --> 00:48:41,980 And how you do that is actually very simple. 912 00:48:41,980 --> 00:48:45,240 You just get rid of these three lines, these three angle-bracket, equals, 913 00:48:45,240 --> 00:48:46,830 angle-bracket lines. 914 00:48:46,830 --> 00:48:50,118 And then you decide which of the two versions of the code to keep, 915 00:48:50,118 --> 00:48:52,410 or in some cases, you might want to merge them together 916 00:48:52,410 --> 00:48:54,783 in some more elaborate way. 917 00:48:54,783 --> 00:48:57,450 And this is usually a good point to talk to the other person who 918 00:48:57,450 --> 00:49:01,590 made the other changes and decide, OK, how exactly should we merge these two 919 00:49:01,590 --> 00:49:03,840 changes together, like why did you make those changes, 920 00:49:03,840 --> 00:49:05,400 why did I make those changes. 921 00:49:05,400 --> 00:49:08,920 Maybe the actual one we want is some sort of a combination of the two. 922 00:49:08,920 --> 00:49:13,100 923 00:49:13,100 --> 00:49:16,760 And if you're using an editor like VS Code or Codespaces on the browser, 924 00:49:16,760 --> 00:49:19,970 then it should also have very convenient graphical UI 925 00:49:19,970 --> 00:49:22,290 elements that make this even easier. 926 00:49:22,290 --> 00:49:26,150 So it'll show you the changes, using the appropriate colors, green or red, 927 00:49:26,150 --> 00:49:30,820 and then you can choose one or the other, depending on which one you want. 928 00:49:30,820 --> 00:49:34,260 And once the conflicts have been resolved, 929 00:49:34,260 --> 00:49:36,820 just commit your resolved changes, using git commit as usual. 930 00:49:36,820 --> 00:49:39,960 931 00:49:39,960 --> 00:49:40,460 OK. 932 00:49:40,460 --> 00:49:44,030 Let's very quickly go through a quick demo of this workflow 933 00:49:44,030 --> 00:49:47,940 as well, just so we know what it looks like. 934 00:49:47,940 --> 00:49:53,490 So let's say, hypothetically, I'm going to clear the commands. 935 00:49:53,490 --> 00:49:56,930 So let's say that I'm not the person who made the original commits, 936 00:49:56,930 --> 00:50:01,110 and maybe I'm somebody else in the same group. 937 00:50:01,110 --> 00:50:02,540 So maybe I just did a git clone. 938 00:50:02,540 --> 00:50:05,900 Maybe I just downloaded the entire codebase. 939 00:50:05,900 --> 00:50:08,720 Maybe I do a git log to see the status right now. 940 00:50:08,720 --> 00:50:11,310 I see that it's exactly one commit. 941 00:50:11,310 --> 00:50:15,240 So let's say that I want to push another commit. 942 00:50:15,240 --> 00:50:20,450 So let's, for example, make some changes here. 943 00:50:20,450 --> 00:50:24,830 Before I do that, I don't want to push these changes to the main branch. 944 00:50:24,830 --> 00:50:31,410 And so what I want to do instead is make the changes to some different branch. 945 00:50:31,410 --> 00:50:37,640 So let's say I do git checkout -b, followed by whatever branch name. 946 00:50:37,640 --> 00:50:41,150 In my case, I'm going to call the branch name add-comments. 947 00:50:41,150 --> 00:50:44,060 948 00:50:44,060 --> 00:50:47,270 So I switched to a new branch called add-comments, and maybe the changes 949 00:50:47,270 --> 00:50:49,400 that I want to make involve just adding a comment. 950 00:50:49,400 --> 00:50:53,930 So maybe I say, say hello. 951 00:50:53,930 --> 00:50:59,400 And now let me run git status, just to show you what the status is right now. 952 00:50:59,400 --> 00:51:04,060 So now I'm on branch add-comments, not on branch main. 953 00:51:04,060 --> 00:51:06,700 And again, I have this modified file, hello.py. 954 00:51:06,700 --> 00:51:08,560 I can do a git add. 955 00:51:08,560 --> 00:51:12,370 I can do a git commit with some commit message, maybe add a comment. 956 00:51:12,370 --> 00:51:14,880 957 00:51:14,880 --> 00:51:15,660 OK. 958 00:51:15,660 --> 00:51:18,180 And then, finally, I can do a git push. 959 00:51:18,180 --> 00:51:20,890 Now, when I do a git push, again, it's going to give me an error. 960 00:51:20,890 --> 00:51:23,700 It says, no, you'll have to do the set-upstream flag, 961 00:51:23,700 --> 00:51:33,160 so I will use that flag and push it to GitHub. 962 00:51:33,160 --> 00:51:36,910 So let me quickly go into GitHub, and I see here itself, 963 00:51:36,910 --> 00:51:40,550 add-comments had recent pushes less than a minute ago. 964 00:51:40,550 --> 00:51:44,687 And on GitHub, it also prompts me to compare create a pull request. 965 00:51:44,687 --> 00:51:47,270 And that is what I want to do in this case, so let me go ahead 966 00:51:47,270 --> 00:51:48,140 and click on this. 967 00:51:48,140 --> 00:51:52,570 968 00:51:52,570 --> 00:51:56,100 So I can open a pull request, which is basically a request 969 00:51:56,100 --> 00:51:59,910 to merge in the changes in this branch called add-comments back 970 00:51:59,910 --> 00:52:01,770 into the main branch. 971 00:52:01,770 --> 00:52:03,508 And it says that this is able to merge. 972 00:52:03,508 --> 00:52:05,550 These branches can be automatically merged, which 973 00:52:05,550 --> 00:52:07,890 means there are no merge conflicts. 974 00:52:07,890 --> 00:52:10,140 And on GitHub, I can specify a title. 975 00:52:10,140 --> 00:52:13,393 I can specify any comments, if I have any. 976 00:52:13,393 --> 00:52:14,935 And then I can create a pull request. 977 00:52:14,935 --> 00:52:17,710 978 00:52:17,710 --> 00:52:21,530 Once I do that-- and this might seem familiar if you've seen your feedback 979 00:52:21,530 --> 00:52:26,350 pull requests in problem sets, because those use pull requests as well-- 980 00:52:26,350 --> 00:52:29,200 I can see in this pull request a list of the commits that 981 00:52:29,200 --> 00:52:32,830 will be merged into the main branch when the merge happens. 982 00:52:32,830 --> 00:52:35,620 And I can also see the changes that have been made. 983 00:52:35,620 --> 00:52:38,080 In this case, there's only one change, the line 984 00:52:38,080 --> 00:52:41,740 highlighted in green, which just adds this comment, saying, say hello. 985 00:52:41,740 --> 00:52:44,560 986 00:52:44,560 --> 00:52:48,020 Now, hypothetically, I could assign a reviewer for this pull request. 987 00:52:48,020 --> 00:52:51,878 So maybe I want my team members to go through this code 988 00:52:51,878 --> 00:52:54,670 and make sure that everything looks good before it gets merged back 989 00:52:54,670 --> 00:52:56,420 into the main branch. 990 00:52:56,420 --> 00:52:58,630 So if somebody else is also in your group, 991 00:52:58,630 --> 00:53:01,100 you can specify their GitHub username over here. 992 00:53:01,100 --> 00:53:03,340 You can ask them to review it. 993 00:53:03,340 --> 00:53:07,040 And once everything has been reviewed, once everything looks good, 994 00:53:07,040 --> 00:53:10,340 once you've tested everything and it's good to go, 995 00:53:10,340 --> 00:53:13,900 you can then click on the Merge Pull Request button. 996 00:53:13,900 --> 00:53:19,102 And you can optionally add a comment, and you can confirm merge. 997 00:53:19,102 --> 00:53:21,940 So pull request successfully merged and closed. 998 00:53:21,940 --> 00:53:24,920 The add-comments branch can be safely deleted. 999 00:53:24,920 --> 00:53:27,940 So now you no longer need this pointer because the main branch 1000 00:53:27,940 --> 00:53:32,560 contains these commits that you added to this add-comments branch. 1001 00:53:32,560 --> 00:53:37,450 So I can safely delete this branch, and now if I go back into my main branch 1002 00:53:37,450 --> 00:53:42,403 and click on hello.py, I will see the changes over here. 1003 00:53:42,403 --> 00:53:45,570 Now, of course, you don't have to go through this entire process of creating 1004 00:53:45,570 --> 00:53:47,910 branches and pull requests and so on. 1005 00:53:47,910 --> 00:53:51,153 You could technically just directly push everything to the main branch. 1006 00:53:51,153 --> 00:53:53,070 But the reason we encourage doing this is just 1007 00:53:53,070 --> 00:53:58,450 to ensure that everybody on the team knows exactly what's going on. 1008 00:53:58,450 --> 00:54:00,960 And you also have this whole process of code review, 1009 00:54:00,960 --> 00:54:03,168 where different people look at the code and make sure 1010 00:54:03,168 --> 00:54:06,780 that everything is good to go before you merge it into the main branch, which 1011 00:54:06,780 --> 00:54:09,824 contains the working version. 1012 00:54:09,824 --> 00:54:14,020 BERNIE LONGBOY: OK, and Tarun, we're in our last four minutes 1013 00:54:14,020 --> 00:54:18,520 here, so if we have other questions or comments. 1014 00:54:18,520 --> 00:54:23,060 1015 00:54:23,060 --> 00:54:24,700 Here's one from Jim. 1016 00:54:24,700 --> 00:54:29,740 If a merge is done to the main branch and a bug is discovered later, 1017 00:54:29,740 --> 00:54:33,010 what is the best way to handle the bug fix? 1018 00:54:33,010 --> 00:54:36,880 TARUN PRASAD: Yeah, that's a really good question. 1019 00:54:36,880 --> 00:54:41,050 So there are a few ways of handling bug fixes. 1020 00:54:41,050 --> 00:54:46,030 If it's something that you want to undo, like maybe it's one very specific buggy 1021 00:54:46,030 --> 00:54:48,790 commit that you want to undo, you can then 1022 00:54:48,790 --> 00:54:50,890 use git revert, like we saw earlier. 1023 00:54:50,890 --> 00:54:55,690 You can do git revert, followed by the commit hash of the buggy commit. 1024 00:54:55,690 --> 00:55:00,160 And then you can then push those changes back into the main branch. 1025 00:55:00,160 --> 00:55:04,930 If it's more detailed than that, maybe it's more specific. 1026 00:55:04,930 --> 00:55:08,050 Maybe a bunch of commits are all buggy, or maybe you 1027 00:55:08,050 --> 00:55:10,060 want to completely get rid of the history 1028 00:55:10,060 --> 00:55:12,850 of the existence of that commit itself. 1029 00:55:12,850 --> 00:55:16,090 There are ways of doing that as well, which we don't quite have time 1030 00:55:16,090 --> 00:55:19,930 to go through now, but I'll just send over a couple of commands 1031 00:55:19,930 --> 00:55:27,250 that you can look at, that you can definitely look up, 1032 00:55:27,250 --> 00:55:30,340 and you can learn more about exactly how to work with these. 1033 00:55:30,340 --> 00:55:34,660 Two of them that'll be very useful include git reset and git rebase 1034 00:55:34,660 --> 00:55:37,900 -i, which is something called an interactive rebase. 1035 00:55:37,900 --> 00:55:42,516 And yeah, those should help you learn more about this. 1036 00:55:42,516 --> 00:55:46,860 BERNIE LONGBOY: What are your thoughts on GitHub Desktop App? 1037 00:55:46,860 --> 00:55:49,090 TARUN PRASAD: That's also a good question. 1038 00:55:49,090 --> 00:55:51,430 Lots of people find it very useful, especially when 1039 00:55:51,430 --> 00:55:55,720 you first start using or learning Git. 1040 00:55:55,720 --> 00:55:57,970 I personally wouldn't recommend it, just because I 1041 00:55:57,970 --> 00:56:00,640 think it's very useful to learn the commands themselves, 1042 00:56:00,640 --> 00:56:05,410 because that's what lets you understand, or it gives you 1043 00:56:05,410 --> 00:56:07,483 the full power of what Git can do. 1044 00:56:07,483 --> 00:56:10,150 But having said that, you can definitely download GitHub Desktop 1045 00:56:10,150 --> 00:56:13,000 and use that for making a lot of this easier, because then you 1046 00:56:13,000 --> 00:56:14,500 don't have to remember the commands. 1047 00:56:14,500 --> 00:56:17,620 You can just click on the Add button and the Commit button, 1048 00:56:17,620 --> 00:56:19,810 and that definitely makes things easier. 1049 00:56:19,810 --> 00:56:21,490 BERNIE LONGBOY: OK, last two. 1050 00:56:21,490 --> 00:56:23,680 One's a comment, and a question. 1051 00:56:23,680 --> 00:56:26,500 Is it considered best practice to-- 1052 00:56:26,500 --> 00:56:27,580 oops. 1053 00:56:27,580 --> 00:56:30,730 Is it considered best practice to make our comments in code 1054 00:56:30,730 --> 00:56:36,070 and pull merge requests in present tense, rather than past tense, i.e. 1055 00:56:36,070 --> 00:56:39,040 add a comment versus added a comment? 1056 00:56:39,040 --> 00:56:41,920 TARUN PRASAD: Yeah, also a really good question, and different people 1057 00:56:41,920 --> 00:56:44,950 have very different conventions for this. 1058 00:56:44,950 --> 00:56:48,370 I personally use present tense, like add a comment, 1059 00:56:48,370 --> 00:56:51,460 because one way of thinking about commits is, 1060 00:56:51,460 --> 00:56:53,530 rather than what you did in the past, you 1061 00:56:53,530 --> 00:56:56,440 can think of a commit as what are the changes that will 1062 00:56:56,440 --> 00:56:58,960 be made when you apply this commit. 1063 00:56:58,960 --> 00:57:01,720 So when I apply this commit, it adds this comment, 1064 00:57:01,720 --> 00:57:04,570 and so you can write the message in present tense. 1065 00:57:04,570 --> 00:57:07,750 But of course, different people have very different opinions on this, 1066 00:57:07,750 --> 00:57:09,475 and there's no one right answer. 1067 00:57:09,475 --> 00:57:10,210 BERNIE LONGBOY: Thanks, Tarun. 1068 00:57:10,210 --> 00:57:11,002 TARUN PRASAD: Yeah. 1069 00:57:11,002 --> 00:57:12,180 Thank you all for coming. 1070 00:57:12,180 --> 00:57:13,000