WEBVTT 00:00:01.490 --> 00:00:06.480 alright let's get started with today's 00:00:03.780 --> 00:00:08.250 lecture so actually before we get 00:00:06.480 --> 00:00:10.260 started one quick note about office 00:00:08.250 --> 00:00:11.280 hours it seemed from the poll that some 00:00:10.260 --> 00:00:12.780 people were under the impression that 00:00:11.280 --> 00:00:15.809 the office hours that follows each 00:00:12.780 --> 00:00:17.670 lecture is just about that day's 00:00:15.809 --> 00:00:19.439 lectures topics and this is not the case 00:00:17.670 --> 00:00:21.029 you can come to office hours and ask us 00:00:19.439 --> 00:00:22.289 questions about any lecture whether it's 00:00:21.029 --> 00:00:24.480 the previous day or from the previous 00:00:22.289 --> 00:00:25.500 week or even things not exactly covered 00:00:24.480 --> 00:00:28.619 in this class that you're just curious 00:00:25.500 --> 00:00:32.610 about so yeah come to office hours with 00:00:28.619 --> 00:00:36.630 questions about anything office hours 00:00:32.610 --> 00:00:38.460 are in the 32 g9 lounge so building 32 00:00:36.630 --> 00:00:40.860 also known as a Stata Center has two 00:00:38.460 --> 00:00:42.300 towers the G tower and the D tower so 00:00:40.860 --> 00:00:43.559 we're in the gates tower on the ninth 00:00:42.300 --> 00:00:44.910 floor so if you take the elevator all 00:00:43.559 --> 00:00:50.190 the way up there's the lounge right in 00:00:44.910 --> 00:00:51.420 front of you okay cool so today we're 00:00:50.190 --> 00:00:53.460 going to be talking about version 00:00:51.420 --> 00:00:55.920 control systems so I just want to get a 00:00:53.460 --> 00:00:58.020 sense of whether you guys have used 00:00:55.920 --> 00:00:59.730 version control systems before so could 00:00:58.020 --> 00:01:01.469 you raise your hand if you have any 00:00:59.730 --> 00:01:03.180 experience with git or any other version 00:01:01.469 --> 00:01:05.760 control system like subversion or 00:01:03.180 --> 00:01:08.640 mercurial or anything else oh great so 00:01:05.760 --> 00:01:10.530 that's a good number of you so I won't 00:01:08.640 --> 00:01:13.260 talk about version control systems in 00:01:10.530 --> 00:01:14.869 general way too much then we'll pretty 00:01:13.260 --> 00:01:17.340 quickly get into the details of git and 00:01:14.869 --> 00:01:19.350 like it's data model and its internals 00:01:17.340 --> 00:01:21.330 but just as a quick summary version 00:01:19.350 --> 00:01:23.460 control systems are tools that are used 00:01:21.330 --> 00:01:25.380 to keep track of changes to source code 00:01:23.460 --> 00:01:28.560 or other collections of files or folders 00:01:25.380 --> 00:01:31.979 and as the name implies these tools help 00:01:28.560 --> 00:01:33.990 track the history of changes to some set 00:01:31.979 --> 00:01:36.479 of documents and in addition to doing 00:01:33.990 --> 00:01:38.220 that they facilitate collaboration so 00:01:36.479 --> 00:01:41.509 they're really useful for working with a 00:01:38.220 --> 00:01:43.920 group of people on a software project 00:01:41.509 --> 00:01:46.350 Virna control systems track changes to a 00:01:43.920 --> 00:01:48.630 folder and its contents in a series of 00:01:46.350 --> 00:01:49.829 snapshots so you capture the entire 00:01:48.630 --> 00:01:51.780 state of a folder and everything inside 00:01:49.829 --> 00:01:53.640 like a software project and you have 00:01:51.780 --> 00:01:56.310 multiple of these in a series of 00:01:53.640 --> 00:01:57.840 snapshots each snapshot encapsulate the 00:01:56.310 --> 00:01:58.979 entire set of files and folders 00:01:57.840 --> 00:02:01.140 contained within some top-level 00:01:58.979 --> 00:02:02.610 directory and then version control 00:02:01.140 --> 00:02:04.770 systems also maintain a bunch of 00:02:02.610 --> 00:02:06.570 metadata along with the actual changes 00:02:04.770 --> 00:02:09.060 to the content and this is to make it 00:02:06.570 --> 00:02:10.560 possible to figure things out like who 00:02:09.060 --> 00:02:12.660 authored a particular change to a 00:02:10.560 --> 00:02:13.560 particular file or when was a particular 00:02:12.660 --> 00:02:14.849 change made 00:02:13.560 --> 00:02:16.620 and slow version control systems 00:02:14.849 --> 00:02:19.380 maintain metadata like authors and 00:02:16.620 --> 00:02:21.180 commit timestamps and you can also 00:02:19.380 --> 00:02:24.030 attach extra messages to these snapshots 00:02:21.180 --> 00:02:25.440 and things like that and so why is 00:02:24.030 --> 00:02:26.430 version control useful 00:02:25.440 --> 00:02:29.099 well it's useful even when you're 00:02:26.430 --> 00:02:31.050 working on projects by yourself so you 00:02:29.099 --> 00:02:32.880 can use it to look at old versions of 00:02:31.050 --> 00:02:34.349 code you've written figure out like why 00:02:32.880 --> 00:02:36.810 something was changed by looking at 00:02:34.349 --> 00:02:38.519 commit messages work on different things 00:02:36.810 --> 00:02:41.190 in parallel without conflicts by using 00:02:38.519 --> 00:02:42.750 different branches of development or be 00:02:41.190 --> 00:02:44.550 able to work on bug fixes while keeping 00:02:42.750 --> 00:02:46.380 work on different features independent 00:02:44.550 --> 00:02:48.060 things like that and so it's an 00:02:46.380 --> 00:02:49.709 invaluable tool even if you're working 00:02:48.060 --> 00:02:53.370 just by yourself even on a small scale 00:02:49.709 --> 00:02:56.489 project like I think the instructors of 00:02:53.370 --> 00:02:58.140 this course use git even on things like 00:02:56.489 --> 00:03:00.150 homework assignments or class projects 00:02:58.140 --> 00:03:01.920 even small scale things in addition to 00:03:00.150 --> 00:03:05.099 our research or larger software projects 00:03:01.920 --> 00:03:06.930 and then of course version control is a 00:03:05.099 --> 00:03:09.000 really powerful tool for working with 00:03:06.930 --> 00:03:11.580 other people so it's useful for sending 00:03:09.000 --> 00:03:13.709 patches of code around resolving 00:03:11.580 --> 00:03:15.120 conflicts when different people are 00:03:13.709 --> 00:03:18.900 working on the same piece of code at the 00:03:15.120 --> 00:03:20.310 same time things like that and so it's a 00:03:18.900 --> 00:03:22.440 really powerful tool for working by 00:03:20.310 --> 00:03:25.140 yourself or with others and it also has 00:03:22.440 --> 00:03:26.579 a neat functionality to let you answer 00:03:25.140 --> 00:03:28.500 questions that would otherwise be kind 00:03:26.579 --> 00:03:30.540 of hard to answer like who wrote a 00:03:28.500 --> 00:03:32.819 particular module in a software project 00:03:30.540 --> 00:03:34.739 or who edited a particular line in a 00:03:32.819 --> 00:03:36.810 particular software project why was this 00:03:34.739 --> 00:03:38.930 particular line change when was it 00:03:36.810 --> 00:03:41.310 changed by whom things like that and 00:03:38.930 --> 00:03:42.810 version control systems also have some 00:03:41.310 --> 00:03:44.100 really powerful functionality that we 00:03:42.810 --> 00:03:44.670 might cover at the end of today's 00:03:44.100 --> 00:03:46.049 lecture 00:03:44.670 --> 00:03:47.639 or you can find the lecture notes if we 00:03:46.049 --> 00:03:49.019 don't have time to do things like 00:03:47.639 --> 00:03:50.730 supposed to have some project you've 00:03:49.019 --> 00:03:52.170 been working on for a couple years and 00:03:50.730 --> 00:03:53.549 then you notice that some funny thing 00:03:52.170 --> 00:03:54.810 about the project was broken like you 00:03:53.549 --> 00:03:57.569 have some unit test that doesn't pass 00:03:54.810 --> 00:03:58.859 anymore and it wasn't broken just now it 00:03:57.569 --> 00:04:01.560 was broken some time ago and you don't 00:03:58.859 --> 00:04:03.630 know exactly when this regression was 00:04:01.560 --> 00:04:05.579 introduced well written control systems 00:04:03.630 --> 00:04:07.859 have a way of automatically identifying 00:04:05.579 --> 00:04:09.810 this like you can take it and give it a 00:04:07.859 --> 00:04:11.489 unit test that's currently failing but 00:04:09.810 --> 00:04:13.380 you know was passing at some point in 00:04:11.489 --> 00:04:15.299 the past and it can binary search your 00:04:13.380 --> 00:04:17.370 history and figure out exactly what 00:04:15.299 --> 00:04:19.769 change to your code made it break so 00:04:17.370 --> 00:04:21.359 lots of really powerful fancy features 00:04:19.769 --> 00:04:23.900 if you know how to use these tools 00:04:21.359 --> 00:04:23.900 properly 00:04:25.860 --> 00:04:30.070 there are a number of version control 00:04:27.730 --> 00:04:31.720 systems out there and get has become 00:04:30.070 --> 00:04:33.250 kind of the de facto standard for 00:04:31.720 --> 00:04:36.450 version control so that's what we're 00:04:33.250 --> 00:04:39.370 going to be covering in today's lecture 00:04:36.450 --> 00:04:41.830 one comic I want to show you which was 00:04:39.370 --> 00:04:47.830 on the screen before hand let me bring 00:04:41.830 --> 00:04:50.320 it back up so this is an xkcd comic that 00:04:47.830 --> 00:04:52.080 illustrates gets reputation so let me 00:04:50.320 --> 00:04:55.030 read it out loud for you 00:04:52.080 --> 00:04:56.590 this is good it tries collaborative work 00:04:55.030 --> 00:04:59.170 on projects through a beautiful 00:04:56.590 --> 00:05:01.750 distributed graph theory tree model cool 00:04:59.170 --> 00:05:02.890 how do we use it no idea just memorize 00:05:01.750 --> 00:05:05.260 these shell commands and type them to 00:05:02.890 --> 00:05:06.760 sync up if you get errors save your work 00:05:05.260 --> 00:05:11.920 elsewhere delete the project and 00:05:06.760 --> 00:05:12.940 download a fresh copy so maybe some 00:05:11.920 --> 00:05:14.320 people may not want to raise their hands 00:05:12.940 --> 00:05:15.460 for this but raise your hand if you've 00:05:14.320 --> 00:05:17.260 ever done this before 00:05:15.460 --> 00:05:20.350 I certainly have when I was learning 00:05:17.260 --> 00:05:22.270 this tool so good number of you here 00:05:20.350 --> 00:05:23.890 have done this before so the goal of 00:05:22.270 --> 00:05:27.460 this lecture is to make it so you don't 00:05:23.890 --> 00:05:31.840 have to do this anymore unfortunately as 00:05:27.460 --> 00:05:34.120 this comic illustrates gets interface is 00:05:31.840 --> 00:05:36.400 a pretty terribly designed interface 00:05:34.120 --> 00:05:37.990 it's a leaky abstraction and so for this 00:05:36.400 --> 00:05:39.880 reason we believe that learning get 00:05:37.990 --> 00:05:42.220 topped down starting with the interface 00:05:39.880 --> 00:05:44.980 is maybe not the best way to go and it 00:05:42.220 --> 00:05:46.600 can lead to some confusion it's possible 00:05:44.980 --> 00:05:48.400 like this comic shows to memorize a 00:05:46.600 --> 00:05:50.440 handful of commands and think of them as 00:05:48.400 --> 00:05:52.510 magic incantations and why everything's 00:05:50.440 --> 00:05:54.340 working all right it kind of works out 00:05:52.510 --> 00:05:55.750 all right but then you have to follow 00:05:54.340 --> 00:05:57.240 the approach of this comic whenever 00:05:55.750 --> 00:06:01.360 things go wrong 00:05:57.240 --> 00:06:03.430 so while git has an ugly interface its 00:06:01.360 --> 00:06:06.430 underlying design and ideas are actually 00:06:03.430 --> 00:06:08.560 pretty beautiful an ugly interface has 00:06:06.430 --> 00:06:09.880 to be memorized but the beautiful ideas 00:06:08.560 --> 00:06:12.280 underlying git can actually be 00:06:09.880 --> 00:06:14.620 understood and once you understand gets 00:06:12.280 --> 00:06:17.110 internals its data model which is 00:06:14.620 --> 00:06:19.150 actually not that complicated then you 00:06:17.110 --> 00:06:20.830 can learn the interface to get you 00:06:19.150 --> 00:06:23.320 you'll have to memorize some things but 00:06:20.830 --> 00:06:25.300 you can understand what exactly certain 00:06:23.320 --> 00:06:27.610 commands do by understanding how they 00:06:25.300 --> 00:06:29.230 manipulate the underlying data model and 00:06:27.610 --> 00:06:31.450 so the way we're going to teach get 00:06:29.230 --> 00:06:33.490 today is first talk about the data model 00:06:31.450 --> 00:06:36.250 almost in abstract talk about how we 00:06:33.490 --> 00:06:37.900 might model files and folders snapshots 00:06:36.250 --> 00:06:38.650 of history and how they relate to each 00:06:37.900 --> 00:06:40.000 other 00:06:38.650 --> 00:06:42.009 then after that we'll walk you through 00:06:40.000 --> 00:06:43.900 some get commands and then finally in 00:06:42.009 --> 00:06:45.580 the resources and exercises will link 00:06:43.900 --> 00:06:47.110 you to tutorials that'll teach you all 00:06:45.580 --> 00:06:48.280 the specifics because there are lots of 00:06:47.110 --> 00:06:51.220 different commands that you will need to 00:06:48.280 --> 00:06:54.360 learn eventually any questions so far 00:06:51.220 --> 00:06:59.259 about our teaching approach for today 00:06:54.360 --> 00:07:01.060 cool great so let's get started there 00:06:59.259 --> 00:07:03.820 are probably many ad hoc approaches you 00:07:01.060 --> 00:07:05.169 could take to version control and I'm 00:07:03.820 --> 00:07:07.240 guessing some of you may have done this 00:07:05.169 --> 00:07:08.380 before like say you have some file or 00:07:07.240 --> 00:07:10.240 folder we have a bunch of different 00:07:08.380 --> 00:07:11.770 files corresponding system software 00:07:10.240 --> 00:07:14.110 project and you want to track changes 00:07:11.770 --> 00:07:15.699 you could just say every day make a copy 00:07:14.110 --> 00:07:17.470 of that entire folder and give that 00:07:15.699 --> 00:07:18.580 folder a timestamp when you want to do 00:07:17.470 --> 00:07:20.289 things like collaborate with other 00:07:18.580 --> 00:07:22.330 people you could take the entire folder 00:07:20.289 --> 00:07:24.460 turned it into a zip archive and email 00:07:22.330 --> 00:07:25.870 it to somebody and then whenever you and 00:07:24.460 --> 00:07:27.550 your buddy are working on two different 00:07:25.870 --> 00:07:29.260 features of a software project you can 00:07:27.550 --> 00:07:30.820 work on them in parallel then one of you 00:07:29.260 --> 00:07:32.500 emails the zip file to the other person 00:07:30.820 --> 00:07:34.030 and then you manually copy and paste the 00:07:32.500 --> 00:07:35.889 appropriate segments from their code 00:07:34.030 --> 00:07:38.440 into your code so that eventually you 00:07:35.889 --> 00:07:41.289 end up with one piece of code that has 00:07:38.440 --> 00:07:43.930 both of your features in it this kind of 00:07:41.289 --> 00:07:44.560 sort of works raise your hand if you've 00:07:43.930 --> 00:07:47.349 done this before 00:07:44.560 --> 00:07:52.210 I certainly have still a decent number 00:07:47.349 --> 00:07:52.539 of you get let's us not do this sort of 00:07:52.210 --> 00:07:55.210 thing 00:07:52.539 --> 00:07:56.470 it is a well-thought-out model that kind 00:07:55.210 --> 00:07:58.360 of facilitates these sorts of 00:07:56.470 --> 00:08:00.340 interactions things that you might want 00:07:58.360 --> 00:08:01.659 to do like tracking your own history on 00:08:00.340 --> 00:08:04.780 your in project or collaboration or 00:08:01.659 --> 00:08:06.159 things like that so git has a well 00:08:04.780 --> 00:08:08.080 thought-out model that enables things 00:08:06.159 --> 00:08:09.970 like branches and collaboration and 00:08:08.080 --> 00:08:13.060 merging changes from other people all 00:08:09.970 --> 00:08:14.560 sorts of neat stuff get models history 00:08:13.060 --> 00:08:16.840 is a collection of files and folders 00:08:14.560 --> 00:08:18.280 within some top-level directory so 00:08:16.840 --> 00:08:19.810 you're probably familiar with this 00:08:18.280 --> 00:08:21.400 abstraction just from files and folders 00:08:19.810 --> 00:08:23.020 on your own computer and so here's one 00:08:21.400 --> 00:08:24.729 example like you might have some 00:08:23.020 --> 00:08:27.940 top-level directory I'll just call this 00:08:24.729 --> 00:08:29.979 like root in parentheses and this 00:08:27.940 --> 00:08:32.380 directory might have say a folder in it 00:08:29.979 --> 00:08:35.760 called foo and this folder inside of it 00:08:32.380 --> 00:08:38.050 might have a file called bar dot txt and 00:08:35.760 --> 00:08:43.390 this might have some contents in it like 00:08:38.050 --> 00:08:45.130 say this says hello world and then maybe 00:08:43.390 --> 00:08:46.660 this top-level directory it has one 00:08:45.130 --> 00:08:49.480 folder in it it caalso have another file 00:08:46.660 --> 00:08:52.300 in it so say there's some other file 00:08:49.480 --> 00:08:58.990 and this file also has some contents in 00:08:52.300 --> 00:09:01.750 it all right 00:08:58.990 --> 00:09:03.010 simple enough the terminology get uses 00:09:01.750 --> 00:09:08.410 for these different things for files and 00:09:03.010 --> 00:09:15.870 folders is this and the top-level thing 00:09:08.410 --> 00:09:18.940 are called trees so this is a folder and 00:09:15.870 --> 00:09:27.040 then these things what we normally call 00:09:18.940 --> 00:09:29.010 files are called blogs all right ok so 00:09:27.040 --> 00:09:32.830 now we have a model of files and folders 00:09:29.010 --> 00:09:35.320 and this is a recursive data structure 00:09:32.830 --> 00:09:37.540 trees can contain other trees and then 00:09:35.320 --> 00:09:41.230 trees can contain both trees and files 00:09:37.540 --> 00:09:43.510 obviously files can't contain trees all 00:09:41.230 --> 00:09:47.800 right so now we have a model of files 00:09:43.510 --> 00:09:49.000 and folders and the kind of top-level of 00:09:47.800 --> 00:09:52.390 this thing the thing I've just labeled 00:09:49.000 --> 00:09:53.350 root is the directory being tracked like 00:09:52.390 --> 00:09:54.760 you might have some folder on your 00:09:53.350 --> 00:09:58.750 computer corresponding to a software 00:09:54.760 --> 00:10:00.250 project now how do you model history 00:09:58.750 --> 00:10:02.230 once you have a model of files and 00:10:00.250 --> 00:10:03.880 folders well you can imagine one way of 00:10:02.230 --> 00:10:05.770 doing it which is you take a snapshot of 00:10:03.880 --> 00:10:07.630 this entire thing and then history is 00:10:05.770 --> 00:10:10.210 just a linear sequence of snapshots like 00:10:07.630 --> 00:10:11.410 you might imagine that it's you can 00:10:10.210 --> 00:10:13.570 almost think of it like you have copies 00:10:11.410 --> 00:10:16.480 of the folder which are dated and 00:10:13.570 --> 00:10:18.520 time-stamped well it doesn't use a 00:10:16.480 --> 00:10:20.500 simple linear model like that it uses 00:10:18.520 --> 00:10:21.970 something a little bit fancier you might 00:10:20.500 --> 00:10:24.160 have heard this terminology before but 00:10:21.970 --> 00:10:25.900 git uses a directed acyclic graph to 00:10:24.160 --> 00:10:27.610 model history and this might sound like 00:10:25.900 --> 00:10:29.460 a bunch of fancy math words but it's 00:10:27.610 --> 00:10:33.220 actually not all that complicated 00:10:29.460 --> 00:10:35.290 so in get each snapshot has some number 00:10:33.220 --> 00:10:36.880 of parents and basically want to know 00:10:35.290 --> 00:10:39.010 like what change preceded what other 00:10:36.880 --> 00:10:41.770 change so suppose here I'm going to use 00:10:39.010 --> 00:10:44.950 circles to refer to individual snapshots 00:10:41.770 --> 00:10:47.320 this is the entire contents within this 00:10:44.950 --> 00:10:50.350 tree so all the files and folders in my 00:10:47.320 --> 00:10:52.990 project my entire project may be in some 00:10:50.350 --> 00:10:55.120 state and then I edit some files and now 00:10:52.990 --> 00:10:56.260 it's in some other state and then I add 00:10:55.120 --> 00:10:58.510 some more files and that's in some other 00:10:56.260 --> 00:11:02.350 state and every state points back to 00:10:58.510 --> 00:11:03.380 which state preceded it this so far is a 00:11:02.350 --> 00:11:05.240 linear history 00:11:03.380 --> 00:11:08.630 but it lets us do something a little bit 00:11:05.240 --> 00:11:11.270 fancier than this you can also from a 00:11:08.630 --> 00:11:14.600 certain snapshot fork your history and 00:11:11.270 --> 00:11:18.950 say I want to base changes off of this 00:11:14.600 --> 00:11:22.700 version and create a new snapshot like 00:11:18.950 --> 00:11:24.260 this so this way of modeling history 00:11:22.700 --> 00:11:25.940 allows you to do things like okay I'm 00:11:24.260 --> 00:11:27.860 working on my project this is my main 00:11:25.940 --> 00:11:29.780 line of development I go up to here and 00:11:27.860 --> 00:11:31.850 now I have two different tasks I want to 00:11:29.780 --> 00:11:33.500 work on suppose on one hand I have some 00:11:31.850 --> 00:11:34.760 fancy new feature I want to add to my 00:11:33.500 --> 00:11:36.830 project and so I'm going to be working 00:11:34.760 --> 00:11:38.450 on that for a couple days but separately 00:11:36.830 --> 00:11:39.740 from that somebody's reported a bug to 00:11:38.450 --> 00:11:41.930 me and I need to go chase down that bug 00:11:39.740 --> 00:11:43.640 and fix it well instead of working on 00:11:41.930 --> 00:11:45.140 all that stuff kind of concurrently at 00:11:43.640 --> 00:11:46.400 the same time in the same line of 00:11:45.140 --> 00:11:49.010 development 00:11:46.400 --> 00:11:50.810 git has its way of branching the history 00:11:49.010 --> 00:11:53.270 into two separate Forks and working on 00:11:50.810 --> 00:11:54.620 different things in parallel temporarily 00:11:53.270 --> 00:11:57.080 in a way that are unrelated to each 00:11:54.620 --> 00:11:58.790 other so I could take this base snapshot 00:11:57.080 --> 00:12:01.160 like my project is in some state where 00:11:58.790 --> 00:12:03.080 it works and then from here I could 00:12:01.160 --> 00:12:05.330 implement a new feature that creates a 00:12:03.080 --> 00:12:07.670 new snapshot so this has the base 00:12:05.330 --> 00:12:12.380 project plus a new feature so I'll do 00:12:07.670 --> 00:12:13.940 like plus feature and then similarly 00:12:12.380 --> 00:12:15.290 separately from this I could go back to 00:12:13.940 --> 00:12:16.910 this original snapshot because I don't 00:12:15.290 --> 00:12:19.580 want to do bug fixing while implementing 00:12:16.910 --> 00:12:20.840 my new feature go here and then work on 00:12:19.580 --> 00:12:25.330 my bug fix and create a different 00:12:20.840 --> 00:12:25.330 snapshot so this has only the bug fix 00:12:26.020 --> 00:12:30.320 but not the feature and then finally 00:12:28.970 --> 00:12:32.390 once I've done these two separate things 00:12:30.320 --> 00:12:34.130 in parallel eventually I want to 00:12:32.390 --> 00:12:35.240 incorporate them all into my common 00:12:34.130 --> 00:12:37.250 source code that has both the feature 00:12:35.240 --> 00:12:39.770 and the bug fix so eventually I might 00:12:37.250 --> 00:12:41.630 author a new snapshot by merging the 00:12:39.770 --> 00:12:43.610 changes present in these two different 00:12:41.630 --> 00:12:47.090 snapshots and so this one I'll have both 00:12:43.610 --> 00:12:55.070 of these snapshots as parents and this 00:12:47.090 --> 00:12:58.250 version here will have both the feature 00:12:55.070 --> 00:13:00.380 and my bug fix so does it make sense why 00:12:58.250 --> 00:13:02.120 get models history in a way that's a 00:13:00.380 --> 00:13:04.550 little bit fancier than just a sequence 00:13:02.120 --> 00:13:06.320 of snapshots of my files and folders why 00:13:04.550 --> 00:13:07.910 I want to be able to support branching 00:13:06.320 --> 00:13:10.100 to work on things in parallel and then 00:13:07.910 --> 00:13:11.270 also merging to combine changes from 00:13:10.100 --> 00:13:14.440 different parallel branches of 00:13:11.270 --> 00:13:14.440 development question 00:13:16.840 --> 00:13:22.160 yeah so that's an excellent point it 00:13:20.510 --> 00:13:23.480 seems that when you merge things you 00:13:22.160 --> 00:13:25.700 could create errors that weren't 00:13:23.480 --> 00:13:27.770 anticipated you could imagine here that 00:13:25.700 --> 00:13:29.780 this feature actually changes something 00:13:27.770 --> 00:13:31.190 that makes this bug-fix redundant or you 00:13:29.780 --> 00:13:32.840 could imagine this bug fix breaking this 00:13:31.190 --> 00:13:34.790 feature or something like that oh that's 00:13:32.840 --> 00:13:36.980 a really good point that's a something 00:13:34.790 --> 00:13:39.110 known as merge conflicts and this is 00:13:36.980 --> 00:13:40.850 something that git will try to do like 00:13:39.110 --> 00:13:42.650 when you merge your parallel branches of 00:13:40.850 --> 00:13:44.150 development it will try to automatically 00:13:42.650 --> 00:13:46.550 combine the changes in a way such that 00:13:44.150 --> 00:13:48.650 it retains all the important changes but 00:13:46.550 --> 00:13:50.240 if it gets confused it will report a 00:13:48.650 --> 00:13:52.250 merge conflict and then leave it up to 00:13:50.240 --> 00:13:54.590 you the programmer to figure out how to 00:13:52.250 --> 00:13:56.030 combine kind of concurrent changes to 00:13:54.590 --> 00:13:57.830 the same files or things like that and 00:13:56.030 --> 00:14:05.810 then get has some tools for facilitating 00:13:57.830 --> 00:14:07.880 this any other questions great ok so now 00:14:05.810 --> 00:14:09.740 we have a model files and folders and 00:14:07.880 --> 00:14:11.180 then we have a model of history how 00:14:09.740 --> 00:14:11.690 different snapshots of our code relate 00:14:11.180 --> 00:14:15.380 to each other 00:14:11.690 --> 00:14:17.780 one little detail here is that each of 00:14:15.380 --> 00:14:20.300 these circles so they kind of correspond 00:14:17.780 --> 00:14:22.370 to a snapshot like a tree with files and 00:14:20.300 --> 00:14:24.560 folders but they also have a little bit 00:14:22.370 --> 00:14:29.360 of metadata so like inside here we might 00:14:24.560 --> 00:14:34.430 have like the author of this commit is 00:14:29.360 --> 00:14:36.260 me and we might have other metadata like 00:14:34.430 --> 00:14:39.230 some message associated with this commit 00:14:36.260 --> 00:14:40.850 I might describe what kinds of changes 00:14:39.230 --> 00:14:44.200 I've made that are present in this 00:14:40.850 --> 00:14:44.200 snapshot but not the previous one 00:14:48.410 --> 00:15:01.470 that is not really the chair class so 00:14:59.280 --> 00:15:03.330 next we're going to talk about kind of 00:15:01.470 --> 00:15:07.770 one level lower than this like how 00:15:03.330 --> 00:15:09.750 exactly is this represented as a as a 00:15:07.770 --> 00:15:10.980 data structure inside get and so I'm 00:15:09.750 --> 00:15:12.300 actually going to write down pseudocode 00:15:10.980 --> 00:15:15.600 because I think it's actually easiest to 00:15:12.300 --> 00:15:20.670 understand this way so first we have 00:15:15.600 --> 00:15:24.590 files so a log is just a bunch of bytes 00:15:20.670 --> 00:15:24.590 so I'll say this is an array of bytes 00:15:26.150 --> 00:15:34.080 okay then what is a tree remember that 00:15:32.070 --> 00:15:39.180 this is just a folder of what are 00:15:34.080 --> 00:15:41.970 folders they're mappings from the 00:15:39.180 --> 00:15:44.760 filename or directoryname to the actual 00:15:41.970 --> 00:15:50.060 contents and the contents are either 00:15:44.760 --> 00:15:56.190 another tree like a subtree or the file 00:15:50.060 --> 00:15:57.330 and then finally we have the last thing 00:15:56.190 --> 00:15:59.280 there what I've been calling snapshots 00:15:57.330 --> 00:16:04.070 so far and get terminology those are 00:15:59.280 --> 00:16:04.070 called commits and so what does a commit 00:16:04.130 --> 00:16:09.960 [Applause] 00:16:06.560 --> 00:16:14.190 it's a bunch of stuff commits have 00:16:09.960 --> 00:16:16.890 parents that describes what precede them 00:16:14.190 --> 00:16:18.240 so in the case of most normal commits 00:16:16.890 --> 00:16:19.800 they have one parent like what they came 00:16:18.240 --> 00:16:24.930 from what merge commits can have 00:16:19.800 --> 00:16:31.200 multiple parents so parents are an array 00:16:24.930 --> 00:16:39.020 of commits and then I have some metadata 00:16:31.200 --> 00:16:39.020 like the author and maybe a message 00:16:42.200 --> 00:16:50.540 and then finally the actual contents the 00:16:48.290 --> 00:16:53.720 snapshot which is a tree that's the 00:16:50.540 --> 00:16:55.820 top-level tree corresponding to a 00:16:53.720 --> 00:16:58.130 particular commitment so this is a 00:16:55.820 --> 00:17:00.769 really clean simple model of history and 00:16:58.130 --> 00:17:04.130 this is basically all there is to how 00:17:00.769 --> 00:17:10.160 get models history any questions about 00:17:04.130 --> 00:17:12.770 that all right so now we have that going 00:17:10.160 --> 00:17:15.380 a little bit deeper let's talk about how 00:17:12.770 --> 00:17:17.299 it actually stores and addresses this 00:17:15.380 --> 00:17:18.890 actual data like at some point this 00:17:17.299 --> 00:17:26.179 actually has to turn to data on disk 00:17:18.890 --> 00:17:28.370 right so get defines an object kind of a 00:17:26.179 --> 00:17:29.870 big standing term but an object is any 00:17:28.370 --> 00:17:39.950 one of those three things so it's a blob 00:17:29.870 --> 00:17:43.160 or a tree tree or a commit and then in 00:17:39.950 --> 00:17:45.770 get all objects are content addressed 00:17:43.160 --> 00:17:47.740 so what get maintains on disk and you 00:17:45.770 --> 00:18:00.500 can actually we can look at this later 00:17:47.740 --> 00:18:03.950 is a set of objects maintained as this 00:18:00.500 --> 00:18:06.470 content address store so if you have any 00:18:03.950 --> 00:18:09.590 one of these objects the way you put it 00:18:06.470 --> 00:18:12.919 into this store is its key is the hash 00:18:09.590 --> 00:18:16.640 of the object so like in pseudocode I 00:18:12.919 --> 00:18:19.580 might say that to store a particular 00:18:16.640 --> 00:18:25.960 object o what I do is I compute its ID 00:18:19.580 --> 00:18:25.960 by taking the sha-1 hash of o and then I 00:18:27.280 --> 00:18:36.230 put it into my objects map store it to 00:18:30.799 --> 00:18:39.740 disk a quick show of hands who here 00:18:36.230 --> 00:18:42.080 knows what a hash function is all right 00:18:39.740 --> 00:18:44.240 so I'll quickly summarize basically a 00:18:42.080 --> 00:18:45.679 hash function is you can think of it as 00:18:44.240 --> 00:18:47.600 like this magical function that takes a 00:18:45.679 --> 00:18:51.140 big piece of data and turns it into a 00:18:47.600 --> 00:18:54.860 short string at a high level these are 00:18:51.140 --> 00:18:55.549 used to or maybe that's like a 00:18:54.860 --> 00:18:56.989 sufficient 00:18:55.549 --> 00:18:58.249 clinician I won't go into too much more 00:18:56.989 --> 00:18:59.409 detail here but you can ask me 00:18:58.249 --> 00:19:02.690 afterwards if you're if you're curious 00:18:59.409 --> 00:19:04.519 so basically they give you a way to name 00:19:02.690 --> 00:19:06.139 a thing in a way that's kind of 00:19:04.519 --> 00:19:07.909 deterministic based on the constants of 00:19:06.139 --> 00:19:09.999 the thing it takes into thing as input 00:19:07.909 --> 00:19:13.460 and gives you a short name for it and 00:19:09.999 --> 00:19:16.429 then the opposite of stores load the way 00:19:13.460 --> 00:19:18.379 we can load things from the store you 00:19:16.429 --> 00:19:28.549 might have just guessed you can look 00:19:18.379 --> 00:19:30.259 them up by their ID and this is just we 00:19:28.549 --> 00:19:36.289 retrieve it from the object store by ID 00:19:30.259 --> 00:19:40.059 and it gives us back the contents any 00:19:36.289 --> 00:19:42.200 questions about this so far question 00:19:40.059 --> 00:19:43.489 that's a good question what language is 00:19:42.200 --> 00:19:45.230 it's all written in it's written in the 00:19:43.489 --> 00:19:48.200 language I just made up so it's 00:19:45.230 --> 00:19:51.019 pseudocode the get implementation itself 00:19:48.200 --> 00:19:54.739 is a mix of C it's mostly C and then 00:19:51.019 --> 00:19:57.169 some bash and Perl scripts I think any 00:19:54.739 --> 00:19:59.239 other questions is this made-up language 00:19:57.169 --> 00:20:06.470 clear enough or do I need to explain any 00:19:59.239 --> 00:20:09.289 aspects of it great okay so blobs trees 00:20:06.470 --> 00:20:14.960 and commits and get are unified in this 00:20:09.289 --> 00:20:16.460 way they're all objects and also as you 00:20:14.960 --> 00:20:19.159 might think given my description here 00:20:16.460 --> 00:20:21.409 like it looks like commits contain a 00:20:19.159 --> 00:20:22.940 whole bunch of other commits and contain 00:20:21.409 --> 00:20:25.489 a snapshot and things like that in 00:20:22.940 --> 00:20:28.989 practice it doesn't actually work that 00:20:25.489 --> 00:20:31.850 way instead all these are pointers so a 00:20:28.989 --> 00:20:34.100 commit will be able to reference a bunch 00:20:31.850 --> 00:20:35.629 of parents by their IDs so this is 00:20:34.100 --> 00:20:38.659 actually not an array of commits 00:20:35.629 --> 00:20:40.759 themselves but IDs and similarly the 00:20:38.659 --> 00:20:42.919 snapshot inside a commit is not the 00:20:40.759 --> 00:20:44.840 actual tree object it's the ID of the 00:20:42.919 --> 00:20:46.489 tree and so all these objects are kind 00:20:44.840 --> 00:20:48.559 of stored on their own in this object 00:20:46.489 --> 00:20:50.570 store and then all the references to 00:20:48.559 --> 00:20:53.899 different objects are just by their ID 00:20:50.570 --> 00:20:55.580 by their sha-1 hash does that make sense 00:20:53.899 --> 00:20:58.129 you can almost in your head map it to 00:20:55.580 --> 00:21:00.289 like these are objects in a programming 00:20:58.129 --> 00:21:02.059 language like Java and then this is a 00:21:00.289 --> 00:21:04.309 reference to a tree so it's like a 00:21:02.059 --> 00:21:05.929 pointer and then that is your realm 00:21:04.309 --> 00:21:08.109 maybe this naughty helps maybe it 00:21:05.929 --> 00:21:08.109 doesn't 00:21:08.919 --> 00:21:20.809 yeah yeah exactly so I'll just repeat 00:21:19.759 --> 00:21:21.409 that for everybody to hear on the 00:21:20.809 --> 00:21:24.649 microphone 00:21:21.409 --> 00:21:26.509 this is gets on disk data store it's a 00:21:24.649 --> 00:21:36.859 Content address store where objects are 00:21:26.509 --> 00:21:40.339 addressed by their hash all right any 00:21:36.859 --> 00:21:45.799 questions about that so far ok so now we 00:21:40.339 --> 00:21:47.629 have a way of identifying we've unified 00:21:45.799 --> 00:21:50.149 all the different types of objects into 00:21:47.629 --> 00:21:51.710 one type of thing we call object and we 00:21:50.149 --> 00:21:54.139 have a way of identifying objects by 00:21:51.710 --> 00:21:56.359 their sha-1 hash what do these actual 00:21:54.139 --> 00:21:58.129 sha-1 hashes look like well they're 00:21:56.359 --> 00:21:59.059 hexadecimal strings that are 40 00:21:58.129 --> 00:22:02.839 characters long 00:21:59.059 --> 00:22:05.539 like sha-1 is a 160-bit hash and so one 00:22:02.839 --> 00:22:07.489 of the actual IDs returned by that sha-1 00:22:05.539 --> 00:22:12.080 function is going to be a really long 00:22:07.489 --> 00:22:13.460 string and so given that we'll have ways 00:22:12.080 --> 00:22:15.440 of identifying these different things 00:22:13.460 --> 00:22:20.239 like this we'll have corresponding to it 00:22:15.440 --> 00:22:27.440 an ID like for a 3-2 CEB or something 00:22:20.239 --> 00:22:29.509 something so now we have a way of naming 00:22:27.440 --> 00:22:31.039 everything in this commit graph but 00:22:29.509 --> 00:22:33.739 these names are really inconvenient 00:22:31.039 --> 00:22:35.779 because they're super long and they're 00:22:33.739 --> 00:22:38.989 like text strings they're not meaningful 00:22:35.779 --> 00:22:41.179 to humans in any way so it's solution to 00:22:38.989 --> 00:22:43.219 this problem is one other thing so get 00:22:41.179 --> 00:22:45.739 maintains a set of objects and then it 00:22:43.219 --> 00:22:48.529 maintains a set of references what our 00:22:45.739 --> 00:22:54.429 references here I'll erase this bit on 00:22:48.529 --> 00:22:54.429 the left this parts pretty logical 00:22:54.519 --> 00:23:02.529 that's the irony another time so 00:22:57.440 --> 00:23:02.529 references all right here 00:23:03.470 --> 00:23:08.970 so this is another piece of data that 00:23:06.000 --> 00:23:16.679 get maintains internally references is a 00:23:08.970 --> 00:23:18.929 map from string to string and you can 00:23:16.679 --> 00:23:23.100 think of this as mapping human readable 00:23:18.929 --> 00:23:28.440 names like I might have a name like fix 00:23:23.100 --> 00:23:30.510 encoding bug fix - encoding - bug is a 00:23:28.440 --> 00:23:33.300 human readable name and this would be 00:23:30.510 --> 00:23:36.059 maps to like that long hexadecimal 00:23:33.300 --> 00:23:38.370 string there and so with these 00:23:36.059 --> 00:23:41.220 references and you can imagine how we 00:23:38.370 --> 00:23:43.980 might have ways of creating new 00:23:41.220 --> 00:23:44.610 references and updating references and 00:23:43.980 --> 00:23:48.360 things like that 00:23:44.610 --> 00:23:51.090 with this I can now refer to things in 00:23:48.360 --> 00:23:55.010 my commit graph by name so I might have 00:23:51.090 --> 00:23:57.179 the same be called like fix bug or I 00:23:55.010 --> 00:24:00.360 might have a name for something over 00:23:57.179 --> 00:24:02.070 here things like that and so yeah with 00:24:00.360 --> 00:24:04.380 this skit can use human readable names 00:24:02.070 --> 00:24:05.880 to refer to particular snapshots in the 00:24:04.380 --> 00:24:10.050 history instead of these long 00:24:05.880 --> 00:24:14.370 hexadecimal strings one other thing to 00:24:10.050 --> 00:24:16.620 be aware of here is given gits design 00:24:14.370 --> 00:24:18.780 for history this entire graph is 00:24:16.620 --> 00:24:20.670 actually immutable you can add new stuff 00:24:18.780 --> 00:24:23.340 to it but you can't actually manipulate 00:24:20.670 --> 00:24:25.620 anything in here I won't go into the 00:24:23.340 --> 00:24:27.630 details of exactly how or why but just 00:24:25.620 --> 00:24:30.030 assume that that's the case however 00:24:27.630 --> 00:24:31.530 references are immutable so as you're 00:24:30.030 --> 00:24:32.970 updating the history like suppose you 00:24:31.530 --> 00:24:34.830 keep working on this piece of software 00:24:32.970 --> 00:24:36.630 you create a new commit so I'm 00:24:34.830 --> 00:24:38.370 representing that by the circle this 00:24:36.630 --> 00:24:40.890 points to the previous commit I can 00:24:38.370 --> 00:24:42.750 actually have say my fixed bug reference 00:24:40.890 --> 00:24:48.300 is pointing here I can update this 00:24:42.750 --> 00:24:51.090 reference to now point over here however 00:24:48.300 --> 00:24:52.470 I can't for example make this point over 00:24:51.090 --> 00:24:54.840 here that's not even a meaningful thing 00:24:52.470 --> 00:24:57.090 to say because this is just the hash of 00:24:54.840 --> 00:24:58.170 this object to change this hash I'd need 00:24:57.090 --> 00:25:01.309 to change the contents of the object 00:24:58.170 --> 00:25:01.309 which doesn't really make sense 00:25:02.700 --> 00:25:06.330 all right any questions about that so 00:25:04.649 --> 00:25:08.730 far that's basically it forgets data 00:25:06.330 --> 00:25:10.049 model and then we'll go into actually 00:25:08.730 --> 00:25:12.029 interacting with get via the command 00:25:10.049 --> 00:25:14.429 line and we'll see how git commands 00:25:12.029 --> 00:25:17.179 correspond with manipulations of a graph 00:25:14.429 --> 00:25:21.570 data structure so any questions about 00:25:17.179 --> 00:25:23.609 modeling history as trees of trees and 00:25:21.570 --> 00:25:25.109 blobs and then snapshots these things 00:25:23.609 --> 00:25:27.149 called commits being chained together 00:25:25.109 --> 00:25:32.759 and you have references that can point 00:25:27.149 --> 00:25:38.539 to particular nodes in this graph cool 00:25:32.759 --> 00:25:41.909 no questions so basically once we have 00:25:38.539 --> 00:25:43.710 objects and references like that's 00:25:41.909 --> 00:25:46.559 basically all there is to a git 00:25:43.710 --> 00:25:53.239 repository those are the two pieces of 00:25:46.559 --> 00:25:53.239 data that it stores and at a high level 00:25:53.450 --> 00:25:59.399 all get command line commands are just 00:25:57.269 --> 00:26:11.519 manipulations of either the references 00:25:59.399 --> 00:26:12.509 data or the objects data okay so for the 00:26:11.519 --> 00:26:15.179 rest of this lecture I'm going to go 00:26:12.509 --> 00:26:16.830 through some git commands it's basically 00:26:15.179 --> 00:26:18.269 going to be an interactive demo similar 00:26:16.830 --> 00:26:19.830 to the vim lecture and then you can 00:26:18.269 --> 00:26:21.600 refer to the notes for full information 00:26:19.830 --> 00:26:23.129 on these commands look of course it's a 00:26:21.600 --> 00:26:27.629 really powerful tool we can't cover 00:26:23.129 --> 00:26:29.519 everything in what 20 minutes all right 00:26:27.629 --> 00:26:31.619 so I'm going to go over to this folder 00:26:29.519 --> 00:26:33.960 called playground and I'm going to make 00:26:31.619 --> 00:26:35.639 a new directory called demo CD into demo 00:26:33.960 --> 00:26:37.739 and this directory is going to represent 00:26:35.639 --> 00:26:40.109 the top level of my project it's 00:26:37.739 --> 00:26:44.340 currently empty because I just created 00:26:40.109 --> 00:26:46.460 it if I want to turn this into a git 00:26:44.340 --> 00:26:49.409 repository I use the git init command 00:26:46.460 --> 00:26:51.720 get in it stands for git initialize and 00:26:49.409 --> 00:26:54.090 we see that it says initialized empty 00:26:51.720 --> 00:26:57.629 git repository in blah blah slash dot 00:26:54.090 --> 00:27:01.320 git if I do LS I still see nothing but 00:26:57.629 --> 00:27:03.450 if I do LS - a there's a hidden file in 00:27:01.320 --> 00:27:05.399 this directory called dot git if I do LS 00:27:03.450 --> 00:27:07.830 get there's a bunch of stuff in here 00:27:05.399 --> 00:27:09.149 this is the directory on disk where it 00:27:07.830 --> 00:27:11.099 gets stores all of its internal data 00:27:09.149 --> 00:27:12.960 namely the objects and the references 00:27:11.099 --> 00:27:15.270 and you actually see here objects and 00:27:12.960 --> 00:27:17.340 refs as two directories in here and 00:27:15.270 --> 00:27:22.050 all the repository data will be stored 00:27:17.340 --> 00:27:23.610 underneath those two directories one 00:27:22.050 --> 00:27:24.570 letter command to keep in mind as we're 00:27:23.610 --> 00:27:27.480 going through these is something called 00:27:24.570 --> 00:27:28.890 get help get help takes a sub command as 00:27:27.480 --> 00:27:30.600 an argument it gives you some help on it 00:27:28.890 --> 00:27:34.160 so if I do get help in it for example 00:27:30.600 --> 00:27:37.920 it'll tell me about the git init command 00:27:34.160 --> 00:27:39.150 so now there are some commands for 00:27:37.920 --> 00:27:41.220 figuring out what's going on with a git 00:27:39.150 --> 00:27:43.580 repository like git status at a high 00:27:41.220 --> 00:27:45.900 level says what is going on right now 00:27:43.580 --> 00:27:47.880 and we see here let's ignore the first 00:27:45.900 --> 00:27:49.500 line for now the second line says no 00:27:47.880 --> 00:27:51.570 commits yet that's because we just 00:27:49.500 --> 00:27:53.880 initialized a fresh repository and so 00:27:51.570 --> 00:27:58.200 there is no history yet I'm actually 00:27:53.880 --> 00:27:59.600 going to does anybody still want this 00:27:58.200 --> 00:28:03.300 are kind of clear this part of the board 00:27:59.600 --> 00:28:05.340 I'm going to as we go along draw how the 00:28:03.300 --> 00:28:07.530 underlying objects and references data 00:28:05.340 --> 00:28:10.410 is changing when I type in certain git 00:28:07.530 --> 00:28:11.820 commands so right now this picture or 00:28:10.410 --> 00:28:13.860 lack of picture represents the current 00:28:11.820 --> 00:28:17.550 state of our repository it's empty there 00:28:13.860 --> 00:28:19.650 are no snapshots so let's fix that let's 00:28:17.550 --> 00:28:23.130 add something to our history here we 00:28:19.650 --> 00:28:25.230 have no files so let me just go ahead 00:28:23.130 --> 00:28:26.970 and create a file hello.txt with the 00:28:25.230 --> 00:28:28.679 content hello world normally you'd have 00:28:26.970 --> 00:28:32.610 your source code with actually useful 00:28:28.679 --> 00:28:33.990 stuff in it now what I want to do is I 00:28:32.610 --> 00:28:35.910 want to take the current contents of 00:28:33.990 --> 00:28:37.860 this directory and turn it into a new 00:28:35.910 --> 00:28:41.280 snapshot to represent say the first 00:28:37.860 --> 00:28:42.660 state my project was in you might 00:28:41.280 --> 00:28:44.400 imagine an interface for doing this 00:28:42.660 --> 00:28:46.290 where there is like a git snapshot 00:28:44.400 --> 00:28:47.670 command or get something else command 00:28:46.290 --> 00:28:50.190 which takes a snapshot of the entire 00:28:47.670 --> 00:28:51.480 state of the current directory for a 00:28:50.190 --> 00:28:52.800 number of reasons git doesn't have a 00:28:51.480 --> 00:28:54.600 command that works exactly like that 00:28:52.800 --> 00:28:57.360 because git wants to give you a little 00:28:54.600 --> 00:28:59.160 bit of flexibility as to what changes to 00:28:57.360 --> 00:29:00.480 include in the next snapshot you take 00:28:59.160 --> 00:29:02.070 this is something that's kind of 00:29:00.480 --> 00:29:04.590 confusing to beginners sometimes so I'll 00:29:02.070 --> 00:29:06.030 try to explain it right now git has a 00:29:04.590 --> 00:29:10.020 concept of something called a staging 00:29:06.030 --> 00:29:12.270 area and at a high level it's where you 00:29:10.020 --> 00:29:15.630 tell git what changes should be included 00:29:12.270 --> 00:29:17.640 in the next snapshot you take if we do 00:29:15.630 --> 00:29:19.830 get status here we'll see that git says 00:29:17.640 --> 00:29:22.679 no commits yet like it said before and 00:29:19.830 --> 00:29:25.050 it says untracked files hello Tex 00:29:22.679 --> 00:29:26.220 so this is saying that get notices that 00:29:25.050 --> 00:29:28.290 there's a new file in the current 00:29:26.220 --> 00:29:29.070 directory but it is not going to be 00:29:28.290 --> 00:29:30.899 included in the neck 00:29:29.070 --> 00:29:34.679 snapshot gets kind of ignoring it for 00:29:30.899 --> 00:29:37.320 now but if I do get ad hello text and if 00:29:34.679 --> 00:29:39.539 I do get status again it says now 00:29:37.320 --> 00:29:42.480 changes to be committed new file 00:29:39.539 --> 00:29:44.460 hello.txt and so now if I do the get 00:29:42.480 --> 00:29:46.409 snapshot command which is actually get 00:29:44.460 --> 00:29:47.789 commit which creates a new one of those 00:29:46.409 --> 00:29:50.370 circles I drone the board over there 00:29:47.789 --> 00:29:52.889 this file will be included in that 00:29:50.370 --> 00:29:55.799 snapshot I'm I take so let me go ahead 00:29:52.889 --> 00:29:57.809 and run git commit what this does is it 00:29:55.799 --> 00:29:58.919 pops up my text editor and it lets me 00:29:57.809 --> 00:30:01.110 type in a message that will be 00:29:58.919 --> 00:30:02.879 associated with this commit and it's 00:30:01.110 --> 00:30:04.080 really good to write high-quality commit 00:30:02.879 --> 00:30:05.370 messages because then later when you're 00:30:04.080 --> 00:30:06.960 looking back at your products version 00:30:05.370 --> 00:30:12.000 history you'll know why you made certain 00:30:06.960 --> 00:30:14.009 changes I'm going to add this relatively 00:30:12.000 --> 00:30:16.080 useless commit message but we have a 00:30:14.009 --> 00:30:17.669 link in the lecture notes for a guide on 00:30:16.080 --> 00:30:21.029 how to write high-quality commit 00:30:17.669 --> 00:30:24.120 messages so now that I've done that get 00:30:21.029 --> 00:30:27.029 prints out some output master ignore 00:30:24.120 --> 00:30:29.039 that bit for now this thing is the hash 00:30:27.029 --> 00:30:32.759 of the commit I just created so now I 00:30:29.039 --> 00:30:35.370 have in my history a single node this 00:30:32.759 --> 00:30:37.620 has in it a tree that has a single blob 00:30:35.370 --> 00:30:41.399 a single file hello.txt with the 00:30:37.620 --> 00:30:46.279 contents hello world and then this has 00:30:41.399 --> 00:30:48.059 the sha-1 hash for 2fb 00:30:46.279 --> 00:30:49.470 something something something it's 00:30:48.059 --> 00:30:52.679 actually truncated in the get interface 00:30:49.470 --> 00:30:55.080 as well this is just printing out my 00:30:52.679 --> 00:30:57.379 commit message again and it says as a 00:30:55.080 --> 00:31:00.720 reminder I just added hello dot text and 00:30:57.379 --> 00:31:02.309 so now if I use the git log command so 00:31:00.720 --> 00:31:04.559 the git log commit is really useful in 00:31:02.309 --> 00:31:09.529 that it helps you visualize the history 00:31:04.559 --> 00:31:09.529 the the commit graph if I do question 00:31:16.009 --> 00:31:20.129 that's a great question so the question 00:31:18.509 --> 00:31:23.100 is what exactly does this hash 00:31:20.129 --> 00:31:26.460 correspond to so this is the hash of the 00:31:23.100 --> 00:31:29.220 commit the commit contains inside of it 00:31:26.460 --> 00:31:31.470 the hash of the tree along with whatever 00:31:29.220 --> 00:31:35.850 other information so I can actually use 00:31:31.470 --> 00:31:38.399 get cat file - P this number this is 00:31:35.850 --> 00:31:40.590 kind of like a get internals command 00:31:38.399 --> 00:31:42.149 that will print out the contents of this 00:31:40.590 --> 00:31:42.410 commit so you can see this kind of maps 00:31:42.149 --> 00:31:43.640 to 00:31:42.410 --> 00:31:46.070 data structure I drew on the board over 00:31:43.640 --> 00:31:48.050 there so this commit has inside of it 00:31:46.070 --> 00:31:49.430 this tree and then I'm the author and 00:31:48.050 --> 00:31:51.020 this is the commit message and so on and 00:31:49.430 --> 00:31:52.970 I can continue digging down here so you 00:31:51.020 --> 00:31:56.090 can take this hash of this tree and do 00:31:52.970 --> 00:31:58.910 get cat file - P this hash here it says 00:31:56.090 --> 00:32:02.750 that this tree has inside of it a single 00:31:58.910 --> 00:32:06.230 entry hello text and that file has it's 00:32:02.750 --> 00:32:09.020 a blob and it has this hash I can do get 00:32:06.230 --> 00:32:11.960 cat file - P this thing and it will show 00:32:09.020 --> 00:32:13.460 me the actual contents of that file so 00:32:11.960 --> 00:32:15.800 these are like internal git commands to 00:32:13.460 --> 00:32:22.970 explore objects in the object store 00:32:15.800 --> 00:32:24.830 question that's a great question so the 00:32:22.970 --> 00:32:26.510 question is why did I have to use get 00:32:24.830 --> 00:32:28.850 add why can't you just commit all 00:32:26.510 --> 00:32:30.350 changes and the answer is well there 00:32:28.850 --> 00:32:33.680 kind of is a way to commit all changes 00:32:30.350 --> 00:32:36.320 if you do get commit - a this commits 00:32:33.680 --> 00:32:38.210 all the changes that were made to files 00:32:36.320 --> 00:32:39.380 that are already being tracked by git so 00:32:38.210 --> 00:32:41.120 anything that was included in the 00:32:39.380 --> 00:32:43.610 previous snapshot but has been modified 00:32:41.120 --> 00:32:46.520 since then it doesn't include new things 00:32:43.610 --> 00:32:48.800 there's also variants of git add like if 00:32:46.520 --> 00:32:50.570 you do get add colon slash this will add 00:32:48.800 --> 00:32:52.910 everything in the top from the top level 00:32:50.570 --> 00:32:55.070 down of your repository but at a higher 00:32:52.910 --> 00:32:57.080 level the reason we have this separation 00:32:55.070 --> 00:32:58.700 between git add and git commit and why 00:32:57.080 --> 00:33:00.830 get come it doesn't just snapshot the 00:32:58.700 --> 00:33:02.450 entire directory is that they're often 00:33:00.830 --> 00:33:03.740 situations where you don't want to 00:33:02.450 --> 00:33:05.660 include everything in the current 00:33:03.740 --> 00:33:08.330 snapshot like here's a couple examples 00:33:05.660 --> 00:33:09.770 one is that I might be packing on my 00:33:08.330 --> 00:33:11.870 project and I go ahead and implement two 00:33:09.770 --> 00:33:13.730 features maybe I don't want to have a 00:33:11.870 --> 00:33:15.650 single snapshot that comes after this 00:33:13.730 --> 00:33:17.660 one that's like I implemented feature a 00:33:15.650 --> 00:33:19.190 and feature B maybe I want to create two 00:33:17.660 --> 00:33:21.200 separate nodes in the history so that it 00:33:19.190 --> 00:33:22.760 looks like first I implemented feature a 00:33:21.200 --> 00:33:24.260 and then after that I implemented 00:33:22.760 --> 00:33:25.820 feature B so I have one snapshot that 00:33:24.260 --> 00:33:28.970 only includes a and then the next one 00:33:25.820 --> 00:33:30.590 includes both a and B git add is a tool 00:33:28.970 --> 00:33:32.120 and like the staging area in general is 00:33:30.590 --> 00:33:33.040 a tool that will allow me to do that 00:33:32.120 --> 00:33:35.810 sort of thing 00:33:33.040 --> 00:33:37.820 another example is suppose I'm working 00:33:35.810 --> 00:33:39.440 on a bug fix and I have printf 00:33:37.820 --> 00:33:40.790 statements I've put all over my code and 00:33:39.440 --> 00:33:41.990 then finally I find the bug and there's 00:33:40.790 --> 00:33:43.280 a plus one somewhere where there 00:33:41.990 --> 00:33:45.140 shouldn't be a plus one so go fix that 00:33:43.280 --> 00:33:46.220 and then I want to take a new snapshot 00:33:45.140 --> 00:33:48.200 right with my fix 00:33:46.220 --> 00:33:50.120 but the snapshot probably should include 00:33:48.200 --> 00:33:51.770 all of my print statements it just needs 00:33:50.120 --> 00:33:53.870 to include the fix of removing that plus 00:33:51.770 --> 00:33:54.899 one so one way I could solve that issue 00:33:53.870 --> 00:33:56.549 is I can go in 00:33:54.899 --> 00:33:58.559 annually remove all the print statements 00:33:56.549 --> 00:34:00.659 but it has a much better way of doing 00:33:58.559 --> 00:34:02.909 that there's actually a way to specify 00:34:00.659 --> 00:34:05.669 that I only want to add the change of 00:34:02.909 --> 00:34:07.619 removing that plus one then I can commit 00:34:05.669 --> 00:34:09.270 that take the new snapshot and then I 00:34:07.619 --> 00:34:10.740 can throw away all the other changes 00:34:09.270 --> 00:34:11.789 there are commands for doing that and 00:34:10.740 --> 00:34:14.099 some of them are linked in the lecture 00:34:11.789 --> 00:34:15.929 notes so those are two ways in which you 00:34:14.099 --> 00:34:17.579 can use the staging area to help you and 00:34:15.929 --> 00:34:24.720 why there isn't just like a snapshot 00:34:17.579 --> 00:34:26.069 everything command yeah so mm-hmm yeah 00:34:24.720 --> 00:34:27.690 John John points out the yeah yet 00:34:26.069 --> 00:34:28.859 another example is you might have log 00:34:27.690 --> 00:34:31.049 files in your current directory that 00:34:28.859 --> 00:34:32.730 your program runs when you run it and 00:34:31.049 --> 00:34:34.889 you probably don't want to include those 00:34:32.730 --> 00:34:36.059 when you take a snapshot there's 00:34:34.889 --> 00:34:37.740 probably other things like if you 00:34:36.059 --> 00:34:39.539 compile your project you end up with a 00:34:37.740 --> 00:34:40.770 bunch of dotto and like elf files you 00:34:39.539 --> 00:34:47.399 probably don't want those to be part of 00:34:40.770 --> 00:34:50.069 your history so going back to what I was 00:34:47.399 --> 00:34:51.270 showing you before I'm going to clear 00:34:50.069 --> 00:34:53.639 the terminal screen and then show you 00:34:51.270 --> 00:34:55.289 the git log command so get logged lets 00:34:53.639 --> 00:34:58.109 you visualize the version history and 00:34:55.289 --> 00:35:00.299 this is an incredibly helpful command by 00:34:58.109 --> 00:35:02.880 default git log shows you a flattened 00:35:00.299 --> 00:35:03.960 version of the version history so even 00:35:02.880 --> 00:35:05.400 though the version history is a graph 00:35:03.960 --> 00:35:07.109 this will linearize it and just show 00:35:05.400 --> 00:35:08.819 things in order i personally find that 00:35:07.109 --> 00:35:11.460 confusing so I almost never use git log 00:35:08.819 --> 00:35:12.930 and instead get log takes some arguments 00:35:11.460 --> 00:35:18.809 that actually show the history as a 00:35:12.930 --> 00:35:20.490 graph so you can treat this as a magic 00:35:18.809 --> 00:35:21.599 incantation for now and you can read the 00:35:20.490 --> 00:35:23.039 documentation if you want to figure out 00:35:21.599 --> 00:35:25.410 exactly what each of those flags does 00:35:23.039 --> 00:35:27.630 but for now this doesn't look all that 00:35:25.410 --> 00:35:29.339 different because we only have one node 00:35:27.630 --> 00:35:30.809 in our graph so visualizing it as a 00:35:29.339 --> 00:35:34.020 flattened thing versus a graph doesn't 00:35:30.809 --> 00:35:36.750 look all that different let me go ahead 00:35:34.020 --> 00:35:38.609 and create a new snapshot and then we 00:35:36.750 --> 00:35:44.400 can run this command again and then see 00:35:38.609 --> 00:35:48.240 exactly what it does so I will put 00:35:44.400 --> 00:35:50.250 another line into hello dot text and so 00:35:48.240 --> 00:35:53.250 if I cat hello dot text it has the thing 00:35:50.250 --> 00:35:55.289 it had before plus this I can do get 00:35:53.250 --> 00:35:57.299 commit and notice this doesn't do 00:35:55.289 --> 00:36:00.359 anything it just says no stained state 00:35:57.299 --> 00:36:02.130 no changes staged for commit why is that 00:36:00.359 --> 00:36:03.630 it's because I didn't add this to the 00:36:02.130 --> 00:36:04.500 staging area I didn't tell yet but like 00:36:03.630 --> 00:36:06.109 this is something that should be 00:36:04.500 --> 00:36:10.730 included in the next snap 00:36:06.109 --> 00:36:13.130 so if I do get ad hallo text get status 00:36:10.730 --> 00:36:15.430 it says okay this change is ready to be 00:36:13.130 --> 00:36:20.300 committed this modification to this file 00:36:15.430 --> 00:36:23.510 and now I can do git commit I'm gonna 00:36:20.300 --> 00:36:26.859 put in a useless commit message and the 00:36:23.510 --> 00:36:29.359 new changes have been made and so now my 00:36:26.859 --> 00:36:31.280 history has another note in it and then 00:36:29.359 --> 00:36:35.270 this note has some hash that's shown on 00:36:31.280 --> 00:36:37.460 the screen and now if I rerun that 00:36:35.270 --> 00:36:39.500 command from earlier the git log with 00:36:37.460 --> 00:36:41.750 all these arguments it actually starts 00:36:39.500 --> 00:36:44.720 looking more like a graph here notice 00:36:41.750 --> 00:36:47.390 that this is like that graph turned this 00:36:44.720 --> 00:36:49.400 way the more recent so it's shown 00:36:47.390 --> 00:36:54.290 vertically not horizontally and the more 00:36:49.400 --> 00:36:56.060 recent commits are shown at the top this 00:36:54.290 --> 00:36:58.160 is showing one commit it shows as commit 00:36:56.060 --> 00:37:00.890 hash shows a bunch of metadata including 00:36:58.160 --> 00:37:02.840 the commit message and then this is the 00:37:00.890 --> 00:37:04.670 part I want to talk about next so 00:37:02.840 --> 00:37:06.080 remember we talked about objects like 00:37:04.670 --> 00:37:08.300 the actual contents of your repository 00:37:06.080 --> 00:37:10.490 and then we talked about references ways 00:37:08.300 --> 00:37:14.900 of naming things in the repository with 00:37:10.490 --> 00:37:16.490 human readable names so master is one 00:37:14.900 --> 00:37:18.770 reference that's created by default when 00:37:16.490 --> 00:37:20.570 you initialize it get repository and by 00:37:18.770 --> 00:37:22.220 convention it generally refers to like 00:37:20.570 --> 00:37:24.680 the main branch of development in your 00:37:22.220 --> 00:37:26.950 code so master will represent like the 00:37:24.680 --> 00:37:29.810 most up-to-date version of your project 00:37:26.950 --> 00:37:32.270 so here you can think of master as a 00:37:29.810 --> 00:37:33.710 pointer to this commit and as we add 00:37:32.270 --> 00:37:36.920 more commits this pointer will be 00:37:33.710 --> 00:37:39.440 mutated to point to later commits then 00:37:36.920 --> 00:37:41.089 we also see here head this is a special 00:37:39.440 --> 00:37:42.770 reference and get it's a reference like 00:37:41.089 --> 00:37:45.980 master but it's special in some way and 00:37:42.770 --> 00:37:49.580 head basically is used to refer to where 00:37:45.980 --> 00:37:55.240 you are currently looking right now any 00:37:49.580 --> 00:37:55.240 questions so far yeah question 00:38:03.780 --> 00:38:09.069 that's an excellent question so the 00:38:06.250 --> 00:38:10.450 question is work with github before and 00:38:09.069 --> 00:38:13.599 you have to create an account to do that 00:38:10.450 --> 00:38:15.789 how does github relate to get and the 00:38:13.599 --> 00:38:20.369 answer to that question is github is a 00:38:15.789 --> 00:38:22.480 repository host for get so you can 00:38:20.369 --> 00:38:24.010 create an account on github and store a 00:38:22.480 --> 00:38:26.020 git repository there and use that to 00:38:24.010 --> 00:38:27.849 collaborate with other people but git as 00:38:26.020 --> 00:38:29.589 a command-line tool is just independent 00:38:27.849 --> 00:38:31.480 from github so you don't have to use 00:38:29.589 --> 00:38:33.099 github to use git you don't have to use 00:38:31.480 --> 00:38:34.359 github declare it with get either like 00:38:33.099 --> 00:38:36.549 there are other providers of git 00:38:34.359 --> 00:38:38.920 repositories like bitbucket or get lab 00:38:36.549 --> 00:38:42.400 or things like that and so yeah github 00:38:38.920 --> 00:39:04.990 is a host for github repositories any 00:38:42.400 --> 00:39:07.329 other questions yeah so the question is 00:39:04.990 --> 00:39:09.160 if you want this repository to end up on 00:39:07.329 --> 00:39:10.539 github how do you do that yeah there's a 00:39:09.160 --> 00:39:13.329 separate set of commands for doing that 00:39:10.539 --> 00:39:15.880 there's a so that concept of having your 00:39:13.329 --> 00:39:17.859 local copy of version history interact 00:39:15.880 --> 00:39:19.089 with another copy so the other copy is 00:39:17.859 --> 00:39:20.319 called a remote and then their set of 00:39:19.089 --> 00:39:22.180 commands for interacting with git 00:39:20.319 --> 00:39:24.490 remotes and sending data from your 00:39:22.180 --> 00:39:26.650 remote or from your copy to get remotes 00:39:24.490 --> 00:39:28.660 and getting data from git remotes into 00:39:26.650 --> 00:39:30.760 your local copy and we'll cover that 00:39:28.660 --> 00:39:31.869 later in this lecture or maybe in the 00:39:30.760 --> 00:39:33.430 lecture notes Ron might make a 00:39:31.869 --> 00:39:39.930 supplemental video to go along with this 00:39:33.430 --> 00:39:42.819 lecture any other questions okay a 00:39:39.930 --> 00:39:44.859 couple other basic commands to show you 00:39:42.819 --> 00:39:46.480 so so far I've shown you a version 00:39:44.859 --> 00:39:49.359 history and we've taken a file and 00:39:46.480 --> 00:39:50.650 modified it but we haven't really made 00:39:49.359 --> 00:39:53.200 use of the history in any way besides 00:39:50.650 --> 00:39:54.579 reading the messages so one useful git 00:39:53.200 --> 00:39:56.589 command is something called git checkout 00:39:54.579 --> 00:39:57.549 and this is a kind of wacky command it 00:39:56.589 --> 00:39:59.349 lets you do a bunch of different things 00:39:57.549 --> 00:40:01.420 but one thing it lets you do is move 00:39:59.349 --> 00:40:03.369 around in your version history so one 00:40:01.420 --> 00:40:05.410 thing I can do is give get checkout the 00:40:03.369 --> 00:40:06.609 commit hash of a previous commit and I 00:40:05.410 --> 00:40:08.079 don't need to type the whole thing I can 00:40:06.609 --> 00:40:09.819 give it a prefix and it's 00:40:08.079 --> 00:40:12.400 to figure out what I'm talking about and 00:40:09.819 --> 00:40:14.799 what this will do is it will change the 00:40:12.400 --> 00:40:18.849 state of my working directory to how it 00:40:14.799 --> 00:40:20.979 was at that commit so here if I do cat 00:40:18.849 --> 00:40:22.630 hello text recall that I had only one 00:40:20.979 --> 00:40:26.170 line in here before at the first commit 00:40:22.630 --> 00:40:28.029 and later I added that second line now 00:40:26.170 --> 00:40:29.650 if I do that get logged command and this 00:40:28.029 --> 00:40:32.199 command is super helpful like it shows 00:40:29.650 --> 00:40:33.880 you all the things if I do this command 00:40:32.199 --> 00:40:36.069 notice that this output looks a little 00:40:33.880 --> 00:40:38.499 bit different than before like my actual 00:40:36.069 --> 00:40:39.910 history contents the commits themselves 00:40:38.499 --> 00:40:42.489 in the way they relate to each other and 00:40:39.910 --> 00:40:44.979 all that have not changed but the 00:40:42.489 --> 00:40:46.959 references have so notice that head is 00:40:44.979 --> 00:40:48.459 down here even the master is still up 00:40:46.959 --> 00:40:50.619 here so at high level what this is 00:40:48.459 --> 00:40:53.439 telling me is this is what I'm looking 00:40:50.619 --> 00:40:56.170 at right now if I want to go back here I 00:40:53.439 --> 00:40:57.429 could type git checkout and this commit 00:40:56.170 --> 00:40:58.929 hash 00:40:57.429 --> 00:41:00.339 does anybody know a different thing I 00:40:58.929 --> 00:41:02.939 could type here instead of this long 00:41:00.339 --> 00:41:06.429 hash in order to go back to this commit 00:41:02.939 --> 00:41:08.679 yeah you can give it the name of this is 00:41:06.429 --> 00:41:10.299 a branch colored in green here and it 00:41:08.679 --> 00:41:11.529 refers to this commit so I can give it 00:41:10.299 --> 00:41:13.900 the short name or the human readable 00:41:11.529 --> 00:41:18.119 name instead and now if I do cat hello 00:41:13.900 --> 00:41:18.119 text notice that it has that second line 00:41:22.740 --> 00:41:25.840 [Music] 00:41:30.989 --> 00:41:43.449 yeah yeah so to repeat that git checkout 00:41:41.249 --> 00:41:45.910 actually changes the contents of your 00:41:43.449 --> 00:41:47.439 working directory and so in that way it 00:41:45.910 --> 00:41:49.749 can be a somewhat dangerous command if 00:41:47.439 --> 00:41:54.759 you misuse it for example you can see if 00:41:49.749 --> 00:41:56.140 I modify hello text and then try that 00:41:54.759 --> 00:41:58.390 get checkout command from earlier 00:41:56.140 --> 00:42:00.969 actually notice here that it says error 00:41:58.390 --> 00:42:02.469 it says there's a file that's been 00:42:00.969 --> 00:42:04.390 modified and the git checkout would 00:42:02.469 --> 00:42:05.769 destroy your modification you probably 00:42:04.390 --> 00:42:07.269 want to do something about that but 00:42:05.769 --> 00:42:09.189 there are flags like for example get 00:42:07.269 --> 00:42:11.319 checkout - eff does this forcibly and 00:42:09.189 --> 00:42:12.819 now it's throwing away my changes so 00:42:11.319 --> 00:42:14.439 yeah get checkout has the potential to 00:42:12.819 --> 00:42:15.670 well it certainly does modify things in 00:42:14.439 --> 00:42:17.199 your working directory and it can 00:42:15.670 --> 00:42:21.630 actually destroy changes if you're not 00:42:17.199 --> 00:42:21.630 careful question 00:42:23.850 --> 00:42:29.170 exactly yeah this is exactly what I want 00:42:27.250 --> 00:42:31.180 you to be thinking about how these like 00:42:29.170 --> 00:42:33.970 the crazy get interface commands 00:42:31.180 --> 00:42:35.590 correspond to mutations to this graph 00:42:33.970 --> 00:42:37.060 and mutations to the reference or like 00:42:35.590 --> 00:42:41.410 additions to the graph in mutations to 00:42:37.060 --> 00:42:43.810 the references map so yeah exactly 00:42:41.410 --> 00:42:45.370 get checkout moves the head pointer and 00:42:43.810 --> 00:42:47.620 then also mutates the contents of your 00:42:45.370 --> 00:42:49.810 working directory with the contents that 00:42:47.620 --> 00:42:54.490 the head pointer now points to of course 00:42:49.810 --> 00:43:01.450 my name for that commit any other 00:42:54.490 --> 00:43:03.220 questions all right so one other basic 00:43:01.450 --> 00:43:05.770 command I want to show you is the git 00:43:03.220 --> 00:43:08.800 diff command so I'm going to modify this 00:43:05.770 --> 00:43:11.440 file and put some changes in it the git 00:43:08.800 --> 00:43:13.570 diff command can show you what's changed 00:43:11.440 --> 00:43:14.890 since the last snapshot it's just 00:43:13.570 --> 00:43:18.010 helpful for like knowing what's going on 00:43:14.890 --> 00:43:23.290 with your project git diff can also take 00:43:18.010 --> 00:43:25.510 extra arguments like you can do git diff 00:43:23.290 --> 00:43:28.150 and say compute a diff not with respect 00:43:25.510 --> 00:43:30.070 to the last snapshot the last commit but 00:43:28.150 --> 00:43:31.780 with respect to this and say ok two 00:43:30.070 --> 00:43:35.250 lines have been added since this point 00:43:31.780 --> 00:43:35.250 to hello dot text 00:43:40.990 --> 00:43:52.990 question so your the question is what 00:43:51.190 --> 00:43:56.310 does this command do without this extra 00:43:52.990 --> 00:43:59.710 argument here that's a good question so 00:43:56.310 --> 00:44:04.990 what this does is it computes a DIF with 00:43:59.710 --> 00:44:07.390 respect to head and looking at my get 00:44:04.990 --> 00:44:08.950 log hat is pointing to here so it's 00:44:07.390 --> 00:44:10.840 doing a get diff with respect to this 00:44:08.950 --> 00:44:12.220 commit and you can actually specify that 00:44:10.840 --> 00:44:31.560 explicitly you can do get diff had 00:44:12.220 --> 00:44:33.970 hollow text okay yes uh-huh 00:44:31.560 --> 00:44:36.609 so that's a good question it's like how 00:44:33.970 --> 00:44:38.200 can hello dot text be different than 00:44:36.609 --> 00:44:40.930 head because head refers to where you 00:44:38.200 --> 00:44:44.650 currently are so to clarify head refers 00:44:40.930 --> 00:44:50.980 to the last snapshot so like in my 00:44:44.650 --> 00:44:54.220 picture here had and master are both 00:44:50.980 --> 00:44:55.780 here and the current working directory 00:44:54.220 --> 00:44:57.130 is kind of independent of this like 00:44:55.780 --> 00:44:58.869 you're going to delete all the files in 00:44:57.130 --> 00:45:00.490 here it doesn't change the history graph 00:44:58.869 --> 00:45:01.780 or the references and so yeah you can 00:45:00.490 --> 00:45:03.430 have differences between here and here 00:45:01.780 --> 00:45:04.869 and at a high level this is how you work 00:45:03.430 --> 00:45:07.119 on a project like you make some changes 00:45:04.869 --> 00:45:08.830 here you get add them to stage them and 00:45:07.119 --> 00:45:12.700 then you get commit and that creates a 00:45:08.830 --> 00:45:17.790 new snapshot here good question 00:45:12.700 --> 00:45:17.790 any other questions yep 00:45:25.670 --> 00:45:30.000 so the question is does get actually 00:45:28.440 --> 00:45:31.320 save all this stuff kind of in the 00:45:30.000 --> 00:45:33.630 obvious way or is it doing something 00:45:31.320 --> 00:45:36.150 fancier the answer is is it is doing 00:45:33.630 --> 00:45:37.860 something a little bit fancier but you 00:45:36.150 --> 00:45:40.080 can it has an interface that lets you 00:45:37.860 --> 00:45:42.090 think of it like it stored that way in 00:45:40.080 --> 00:45:44.550 practice get uses Delta compression it 00:45:42.090 --> 00:45:45.960 also does some other stuff but yeah the 00:45:44.550 --> 00:45:58.350 on disk representation is actually 00:45:45.960 --> 00:46:00.150 reasonably efficient question yeah 00:45:58.350 --> 00:46:02.910 that's a good question so the question 00:46:00.150 --> 00:46:05.100 is here we were comparing the current 00:46:02.910 --> 00:46:07.020 working directory with a particular 00:46:05.100 --> 00:46:09.210 snapshot in the past can we compare two 00:46:07.020 --> 00:46:10.710 snapshots with each other like at two 00:46:09.210 --> 00:46:12.480 different points in the history and yeah 00:46:10.710 --> 00:46:14.340 I get diff can take yet another argument 00:46:12.480 --> 00:46:18.300 here so I can for example compare head 00:46:14.340 --> 00:46:21.420 with it did in the wrong order I can 00:46:18.300 --> 00:46:23.640 compare what change from here to head in 00:46:21.420 --> 00:46:27.240 hello text and it shows me that I added 00:46:23.640 --> 00:46:29.570 the second line in there any other 00:46:27.240 --> 00:46:29.570 questions 00:46:41.280 --> 00:46:44.430 yeah so the question is you're working 00:46:42.900 --> 00:46:46.050 on a shared project in a Dropbox folder 00:46:44.430 --> 00:46:48.540 and anyone a migrate to get does it make 00:46:46.050 --> 00:46:51.570 sense to turn the Dropbox folder into a 00:46:48.540 --> 00:46:52.980 git repo do not use get inside dropbox 00:46:51.570 --> 00:46:54.780 dropbox will corrupt your gate repo 00:46:52.980 --> 00:46:57.210 there are good solutions to doing that 00:46:54.780 --> 00:46:58.470 one is just use github otherwise I talk 00:46:57.210 --> 00:47:03.780 to me after class and there ways of 00:46:58.470 --> 00:47:06.470 using Dropbox as I get remote safely any 00:47:03.780 --> 00:47:06.470 other questions 00:47:06.830 --> 00:47:11.430 next we're going to talk about branching 00:47:09.420 --> 00:47:12.990 and merging which is another powerful 00:47:11.430 --> 00:47:15.030 feature of get that you almost certainly 00:47:12.990 --> 00:47:16.380 use both when working on your own 00:47:15.030 --> 00:47:19.620 projects and when collaborating with 00:47:16.380 --> 00:47:22.230 others for this series of demos we're 00:47:19.620 --> 00:47:24.630 going to rather than work with a simple 00:47:22.230 --> 00:47:26.670 text file actually write a simple 00:47:24.630 --> 00:47:28.170 computer program because it'll better 00:47:26.670 --> 00:47:29.820 illustrate the concepts of branching and 00:47:28.170 --> 00:47:32.550 merging and as we go through this 00:47:29.820 --> 00:47:34.680 demonstration we'll keep in mind how the 00:47:32.550 --> 00:47:37.260 get interface commands connect to the 00:47:34.680 --> 00:47:39.930 underlying data model connect to objects 00:47:37.260 --> 00:47:44.130 and references and how these commands 00:47:39.930 --> 00:47:46.080 modify those two data structures let me 00:47:44.130 --> 00:47:47.940 do a get status to see the current state 00:47:46.080 --> 00:47:50.190 of my repository here I've modified 00:47:47.940 --> 00:47:51.930 hello text I actually don't really care 00:47:50.190 --> 00:47:54.930 about this modification anymore this is 00:47:51.930 --> 00:47:57.960 some random file if I do get check out 00:47:54.930 --> 00:48:00.330 folio text this is another different use 00:47:57.960 --> 00:48:02.250 of the check out command which basically 00:48:00.330 --> 00:48:04.770 throws away the changes that I've made 00:48:02.250 --> 00:48:07.200 in the working directory and sets the 00:48:04.770 --> 00:48:09.660 contents of hello text back to the way 00:48:07.200 --> 00:48:12.330 it was in the snapshot that head points 00:48:09.660 --> 00:48:15.450 to if I like it get logged - - all - 00:48:12.330 --> 00:48:18.450 graft - - decorate it'll show me that 00:48:15.450 --> 00:48:20.700 here I added the initial attacks and it 00:48:18.450 --> 00:48:23.190 added that single line here and so now 00:48:20.700 --> 00:48:26.420 whole text doesn't have that third line 00:48:23.190 --> 00:48:28.530 I'd added it just has the original - 00:48:26.420 --> 00:48:30.420 next time we should write a very simple 00:48:28.530 --> 00:48:34.440 program we'll call this program and a 00:48:30.420 --> 00:48:36.420 mold pie and let me just go ahead and 00:48:34.440 --> 00:48:43.790 write a program that it prints a little 00:48:36.420 --> 00:48:43.790 bit of output when I run it let's see 00:48:45.930 --> 00:48:50.020 [Applause] 00:48:47.850 --> 00:48:52.119 so when I run this program it runs main 00:48:50.020 --> 00:48:54.340 mean calls default and then let me go 00:48:52.119 --> 00:48:57.220 right ahead go ahead and define default 00:48:54.340 --> 00:48:58.840 and default is going it's just going to 00:48:57.220 --> 00:49:01.900 print hello so this is a program that 00:48:58.840 --> 00:49:03.310 greets its user and so if I run animal 00:49:01.900 --> 00:49:05.110 dot pi I'll see that it just prints 00:49:03.310 --> 00:49:07.710 hello so that'll be our starting point 00:49:05.110 --> 00:49:12.250 if I do get status it shows me that 00:49:07.710 --> 00:49:14.260 animal dot hi is an untracked file to 00:49:12.250 --> 00:49:17.140 begin with i want this to be part of my 00:49:14.260 --> 00:49:19.180 part of the snapshot so i'm going to get 00:49:17.140 --> 00:49:23.670 add animal dot hi to add it to the 00:49:19.180 --> 00:49:23.670 staging area and do then do a git commit 00:49:24.660 --> 00:49:28.690 here I'm going to write yet another 00:49:26.800 --> 00:49:30.100 useless commit message don't actually 00:49:28.690 --> 00:49:33.100 write commit messages like this in real 00:49:30.100 --> 00:49:35.200 projects but for now this is fine so now 00:49:33.100 --> 00:49:38.350 I have this basic animal dot pi and if I 00:49:35.200 --> 00:49:41.320 look at my get history now I have this 00:49:38.350 --> 00:49:43.960 latest snapshot this is the commit hash 00:49:41.320 --> 00:49:45.580 and this is where the master branch is 00:49:43.960 --> 00:49:48.520 pointing now we're actually way to 00:49:45.580 --> 00:49:51.760 demonstrate how to use git branches to 00:49:48.520 --> 00:49:53.500 have parallel lines of development they 00:49:51.760 --> 00:49:55.090 get branch command or the branch 00:49:53.500 --> 00:49:57.400 sub-command is used to access 00:49:55.090 --> 00:49:59.500 functionality related to branching just 00:49:57.400 --> 00:50:00.820 running git branch by itself lists all 00:49:59.500 --> 00:50:03.010 the branches that are present in the 00:50:00.820 --> 00:50:05.500 local repository it can also take an 00:50:03.010 --> 00:50:08.710 extra argument - V V to be extra verbose 00:50:05.500 --> 00:50:11.020 and print some extra information if we 00:50:08.710 --> 00:50:13.359 do get branch and then specify the name 00:50:11.020 --> 00:50:15.369 for a new branch git will create a new 00:50:13.359 --> 00:50:16.780 branch which is just a reference that 00:50:15.369 --> 00:50:18.400 points the same place where we're 00:50:16.780 --> 00:50:21.609 currently looking so now there's a new 00:50:18.400 --> 00:50:22.930 reference called cat reference in this 00:50:21.609 --> 00:50:24.700 case is the same as branch there's a new 00:50:22.930 --> 00:50:26.590 branch called cat which points to 00:50:24.700 --> 00:50:29.859 wherever head was pointing if I look at 00:50:26.590 --> 00:50:31.930 the git log again I'll see that here had 00:50:29.859 --> 00:50:34.119 points to master masters over here and 00:50:31.930 --> 00:50:35.710 this is also where the cat branches so 00:50:34.119 --> 00:50:39.550 now I have two branches two references 00:50:35.710 --> 00:50:41.080 that resolve to the same commit get is 00:50:39.550 --> 00:50:42.550 actually aware of not only which 00:50:41.080 --> 00:50:44.500 snapshot in the history are currently 00:50:42.550 --> 00:50:46.540 looking at so had points to this commit 00:50:44.500 --> 00:50:49.390 but it's also aware of had kind of being 00:50:46.540 --> 00:50:51.310 associated with a with a branch so here 00:50:49.390 --> 00:50:52.390 head is associated with master and it's 00:50:51.310 --> 00:50:54.790 the case that if I create a new snapshot 00:50:52.390 --> 00:50:57.680 if I type git commit at this point the 00:50:54.790 --> 00:50:59.540 next snapshot will be created and 00:50:57.680 --> 00:51:02.000 I'll point to that new snapshot master 00:50:59.540 --> 00:51:05.690 will be updated along with head if I do 00:51:02.000 --> 00:51:07.730 get checkout cat what this does is it 00:51:05.690 --> 00:51:08.839 switches to the branch cat it replaces 00:51:07.730 --> 00:51:11.000 the contents of the working directory 00:51:08.839 --> 00:51:12.770 without with whatever cats pointing to 00:51:11.000 --> 00:51:14.780 which in this case is the same as the 00:51:12.770 --> 00:51:17.809 contents before but now if I look at the 00:51:14.780 --> 00:51:20.270 git log again now I have head point to 00:51:17.809 --> 00:51:21.710 cat instead of master and then master 00:51:20.270 --> 00:51:24.829 also points to the same place the same 00:51:21.710 --> 00:51:27.050 underlying commit and now at this point 00:51:24.829 --> 00:51:29.300 if I make changes to my current working 00:51:27.050 --> 00:51:31.520 directory and make a new commit the cat 00:51:29.300 --> 00:51:33.170 branch the cat pointer will be updated 00:51:31.520 --> 00:51:34.430 to point than you commit where as master 00:51:33.170 --> 00:51:36.800 will continue pointing wherever it 00:51:34.430 --> 00:51:39.500 pointed before so let me go ahead and 00:51:36.800 --> 00:51:41.690 modify animal PI to add some cat related 00:51:39.500 --> 00:51:45.890 functionality so I'm going to say that 00:51:41.690 --> 00:51:47.390 if sISTAR V one is cat then run the cat 00:51:45.890 --> 00:51:49.309 function otherwise run the default 00:51:47.390 --> 00:51:52.880 function and then let me go ahead and 00:51:49.309 --> 00:51:55.400 import define the cat function so cats 00:51:52.880 --> 00:51:58.640 don't say hello them you know so cat 00:51:55.400 --> 00:52:01.309 prints meow straightforward enough so 00:51:58.640 --> 00:52:03.500 now if I run animal dot PI and give it 00:52:01.309 --> 00:52:05.270 the cat argument it says meow if I give 00:52:03.500 --> 00:52:07.760 it some other argument it defaults back 00:52:05.270 --> 00:52:09.500 to the hello all right so simple change 00:52:07.760 --> 00:52:11.299 I made if I do a get status that says 00:52:09.500 --> 00:52:13.910 that animal that PI has been modified 00:52:11.299 --> 00:52:15.410 Farren get diff it'll show me what's 00:52:13.910 --> 00:52:17.299 changed since the last commit 00:52:15.410 --> 00:52:19.250 so here I've added this cat function 00:52:17.299 --> 00:52:22.160 highlighted in green then also change 00:52:19.250 --> 00:52:26.000 the main function a little bit now here 00:52:22.160 --> 00:52:29.900 if I do get add animal dot I get commit 00:52:26.000 --> 00:52:31.609 I mean actually you write a slightly 00:52:29.900 --> 00:52:34.670 more useful commit message this time I'm 00:52:31.609 --> 00:52:38.299 going to add cat functionality and now 00:52:34.670 --> 00:52:39.680 if I look at the git log I see a little 00:52:38.299 --> 00:52:41.329 more stuff I'm going to show you one 00:52:39.680 --> 00:52:45.440 more argument to this get logged command 00:52:41.329 --> 00:52:47.510 there's an argument - - one line one 00:52:45.440 --> 00:52:49.309 line spelled correctly which shows a 00:52:47.510 --> 00:52:51.500 more compact representation of the graph 00:52:49.309 --> 00:52:53.119 so sould be a more useful thing to use 00:52:51.500 --> 00:52:54.589 because we're super zoomed into the 00:52:53.119 --> 00:52:58.099 screen and there isn't that much space 00:52:54.589 --> 00:52:59.480 to show a long commit history so here we 00:52:58.099 --> 00:53:02.450 see the sequence of commits is still 00:52:59.480 --> 00:53:03.950 linear and we have master still pointing 00:53:02.450 --> 00:53:06.109 wherever it pointed before where we just 00:53:03.950 --> 00:53:08.180 had the basic underlying animal top high 00:53:06.109 --> 00:53:10.460 functionality but now we have this cat 00:53:08.180 --> 00:53:14.359 branch which adds the cat functionality 00:53:10.460 --> 00:53:16.789 we could for example get checkout master 00:53:14.359 --> 00:53:19.400 to go back to the master branch and then 00:53:16.789 --> 00:53:20.750 here if we look at animal dot pie it 00:53:19.400 --> 00:53:22.549 doesn't have the cat functionality 00:53:20.750 --> 00:53:24.619 anymore if we look at the git log we'll 00:53:22.549 --> 00:53:25.970 see that head is pointing to master so 00:53:24.619 --> 00:53:28.910 so we can jump back and forth between 00:53:25.970 --> 00:53:30.079 parallel lines of development so now 00:53:28.910 --> 00:53:31.670 that we have the cat functionality 00:53:30.079 --> 00:53:33.349 suppose that we want to work on adding 00:53:31.670 --> 00:53:35.690 dog functionality in parallel and 00:53:33.349 --> 00:53:37.039 suppose that in this case like the cat 00:53:35.690 --> 00:53:38.779 functionality is under development or 00:53:37.039 --> 00:53:39.829 maybe somebody else is working on it so 00:53:38.779 --> 00:53:42.170 we just want to start from the base 00:53:39.829 --> 00:53:44.779 master commit and build the dog 00:53:42.170 --> 00:53:45.920 functionality starting from there so now 00:53:44.779 --> 00:53:48.049 what do I want to do I want to create a 00:53:45.920 --> 00:53:49.430 new branch dog for adding the dog 00:53:48.049 --> 00:53:51.500 related functionality and I'll 00:53:49.430 --> 00:53:53.660 eventually merge it in later so I can 00:53:51.500 --> 00:53:56.869 use the git branch dog command followed 00:53:53.660 --> 00:53:58.819 by the git checkout dog command to 00:53:56.869 --> 00:54:00.410 create a new dog branch and then check 00:53:58.819 --> 00:54:04.309 it out there's actually a short form for 00:54:00.410 --> 00:54:06.799 this get checkout - b-dawg so this does 00:54:04.309 --> 00:54:09.710 get branch dog get checkout dog and now 00:54:06.799 --> 00:54:11.329 if I look at my graph I have cat where 00:54:09.710 --> 00:54:13.190 it was before master where it was before 00:54:11.329 --> 00:54:15.920 but now head instead of pointing to 00:54:13.190 --> 00:54:17.750 master as it did before now head points 00:54:15.920 --> 00:54:20.089 to this newly created dog reference 00:54:17.750 --> 00:54:22.520 which is also at the same commit so at 00:54:20.089 --> 00:54:25.430 this base commit and now I'll go ahead 00:54:22.520 --> 00:54:28.789 and add my dog functionality so let me 00:54:25.430 --> 00:54:31.549 go and define my dog function dogs don't 00:54:28.789 --> 00:54:33.500 say hello they say woof and then I'll 00:54:31.549 --> 00:54:35.869 add some similar functionality here to 00:54:33.500 --> 00:54:39.440 decide whether to run default or dog so 00:54:35.869 --> 00:54:42.400 if the first argument is dog then I want 00:54:39.440 --> 00:54:45.109 to run the dog function otherwise whoops 00:54:42.400 --> 00:54:49.520 otherwise I want to run the default 00:54:45.109 --> 00:54:51.200 function so here's what I've changed 00:54:49.520 --> 00:54:53.420 with respect to the base commit wherever 00:54:51.200 --> 00:54:54.920 master is pointing so I've added the dog 00:54:53.420 --> 00:54:56.960 function and I've changed mean a little 00:54:54.920 --> 00:54:59.569 bit so a kind of parallel modification 00:54:56.960 --> 00:55:02.599 to what I did in the cat branch let me 00:54:59.569 --> 00:55:04.970 go ahead and get add animal Titus add up 00:55:02.599 --> 00:55:06.079 to the staging area if I do get status 00:55:04.970 --> 00:55:08.440 I'll see that this change will be 00:55:06.079 --> 00:55:11.680 committed when I make the next commit 00:55:08.440 --> 00:55:16.190 and then I do get commit add 00:55:11.680 --> 00:55:18.500 functionality now when I look at the get 00:55:16.190 --> 00:55:19.640 graph it actually looks kind of 00:55:18.500 --> 00:55:22.670 interesting compared to the ones we've 00:55:19.640 --> 00:55:23.930 looked at before this shows that these 00:55:22.670 --> 00:55:25.550 three commits 00:55:23.930 --> 00:55:26.930 are in common with the ones that come 00:55:25.550 --> 00:55:28.940 after it but then the history is 00:55:26.930 --> 00:55:30.590 actually forked after this point and I 00:55:28.940 --> 00:55:32.390 have this one commit that adds cat 00:55:30.590 --> 00:55:34.550 functionality in one line of development 00:55:32.390 --> 00:55:36.440 and then I have this other commit that 00:55:34.550 --> 00:55:38.390 adds dog functionality in this other 00:55:36.440 --> 00:55:39.920 line of development and then using the 00:55:38.390 --> 00:55:43.180 git checkout command I can switch back 00:55:39.920 --> 00:55:45.890 and forth between dog and cat and master 00:55:43.180 --> 00:55:47.540 so this is great I can do development in 00:55:45.890 --> 00:55:48.830 parallel on different features but this 00:55:47.540 --> 00:55:50.990 is only really useful if I can 00:55:48.830 --> 00:55:52.550 eventually combine those things back 00:55:50.990 --> 00:55:54.590 into my original line of development to 00:55:52.550 --> 00:55:57.350 have both features in a single version 00:55:54.590 --> 00:56:00.290 of my source code so the command that's 00:55:57.350 --> 00:56:01.670 used to do that is get merge so like get 00:56:00.290 --> 00:56:06.400 branch and get merge can kind of be 00:56:01.670 --> 00:56:09.740 thought of as opposites let me check out 00:56:06.400 --> 00:56:11.600 get check out master let me check out my 00:56:09.740 --> 00:56:13.550 master branch so now you see head points 00:56:11.600 --> 00:56:14.870 to master and then I want to merge the 00:56:13.550 --> 00:56:17.060 cat functionality and the dog 00:56:14.870 --> 00:56:19.490 functionality into master and to do that 00:56:17.060 --> 00:56:21.080 I can use the git merge command and get 00:56:19.490 --> 00:56:22.700 merge is actually pretty fancy and I can 00:56:21.080 --> 00:56:24.650 actually merge cat and dog at the same 00:56:22.700 --> 00:56:26.120 time but for this demonstration we're 00:56:24.650 --> 00:56:28.810 going to only merge one thing at a time 00:56:26.120 --> 00:56:31.510 so first I'll type git merge cat and 00:56:28.810 --> 00:56:33.920 gets us some stuff here it says 00:56:31.510 --> 00:56:35.660 fast-forward so what is going on here 00:56:33.920 --> 00:56:38.180 well this is one interesting thing that 00:56:35.660 --> 00:56:40.040 get can do when you're at a particular 00:56:38.180 --> 00:56:42.650 commit and you merge some other branch 00:56:40.040 --> 00:56:46.340 in where that other branch has the 00:56:42.650 --> 00:56:48.110 current commit as a predecessor it's not 00:56:46.340 --> 00:56:50.180 necessary to create any new snapshots or 00:56:48.110 --> 00:56:52.790 do any other fancy stuff basically this 00:56:50.180 --> 00:56:54.740 this master branch here this pointer to 00:56:52.790 --> 00:56:56.810 this commit can just be moved to point 00:56:54.740 --> 00:56:59.240 here instead to incorporate that cat 00:56:56.810 --> 00:57:02.360 functionality and so if we look at the 00:56:59.240 --> 00:57:03.710 git log again we see that master is 00:57:02.360 --> 00:57:06.620 basically pointing to the same places 00:57:03.710 --> 00:57:07.970 wherever cat was pointing all right so 00:57:06.620 --> 00:57:09.830 now we're on the master branch and it 00:57:07.970 --> 00:57:14.000 has the cat functionality great we're 00:57:09.830 --> 00:57:16.190 halfway there if we look at animal dock 00:57:14.000 --> 00:57:19.730 by it has the cat functionality but it's 00:57:16.190 --> 00:57:22.040 missing the dog stuff so let's try get 00:57:19.730 --> 00:57:24.140 merge dog next something a little bit 00:57:22.040 --> 00:57:26.900 more interesting happens this time so 00:57:24.140 --> 00:57:28.880 this time the branch can't be fast 00:57:26.900 --> 00:57:31.070 forwarded like it was before it's not 00:57:28.880 --> 00:57:32.360 that one thing which is strictly older 00:57:31.070 --> 00:57:34.010 than the other thing there's been 00:57:32.360 --> 00:57:35.360 parallel development that may be kind of 00:57:34.010 --> 00:57:36.670 incompatible with the current set of 00:57:35.360 --> 00:57:39.490 changes and 00:57:36.670 --> 00:57:40.900 it does its best job at automatically 00:57:39.490 --> 00:57:41.470 merging the changes from this other 00:57:40.900 --> 00:57:43.359 branch 00:57:41.470 --> 00:57:45.579 so it says Auto merging animal dot pie 00:57:43.359 --> 00:57:47.890 but in this particular case there's what 00:57:45.579 --> 00:57:49.990 was what's called a merge conflict so it 00:57:47.890 --> 00:57:51.400 wasn't able to automatically resolve on 00:57:49.990 --> 00:57:53.440 the call the conflicts between these two 00:57:51.400 --> 00:57:54.460 parallel branches of development and 00:57:53.440 --> 00:57:55.990 this is something you'll see in practice 00:57:54.460 --> 00:57:57.390 when you're working on real software 00:57:55.990 --> 00:57:59.589 projects and they're complicated 00:57:57.390 --> 00:58:02.440 slightly incompatible changes happening 00:57:59.589 --> 00:58:04.390 in parallel so at this point it's left 00:58:02.440 --> 00:58:07.690 up to the developer to fix this issue 00:58:04.390 --> 00:58:09.519 and get offers some functionality in 00:58:07.690 --> 00:58:12.240 order to help resolve merge conflicts 00:58:09.519 --> 00:58:14.890 there's a program called git merge tool 00:58:12.240 --> 00:58:17.260 and in my particular setup this will 00:58:14.890 --> 00:58:21.880 launch vim diff actually this is not 00:58:17.260 --> 00:58:31.630 configured them diff I think will start 00:58:21.880 --> 00:58:37.599 the right program let me set up my get 00:58:31.630 --> 00:58:38.769 to launch the correct tool actually 00:58:37.599 --> 00:58:40.450 let's skip that part and let's just 00:58:38.769 --> 00:58:42.490 manually look at this event if so 00:58:40.450 --> 00:58:43.900 there's a program called vim diff which 00:58:42.490 --> 00:58:45.970 can be set up to be launched when you 00:58:43.900 --> 00:58:47.769 type in get merge tool which is a tool 00:58:45.970 --> 00:58:50.170 that you use when you try get merged in 00:58:47.769 --> 00:58:51.549 there merge conflicts but in this 00:58:50.170 --> 00:58:52.390 particular case we'll just manually 00:58:51.549 --> 00:58:55.630 resolve them 00:58:52.390 --> 00:58:57.099 so let me I did get merge - - abort so 00:58:55.630 --> 00:58:59.049 it put me back in the state I was before 00:58:57.099 --> 00:59:00.430 I tried that git merge so this is the 00:58:59.049 --> 00:59:02.559 current state of my repository I'm back 00:59:00.430 --> 00:59:04.750 to the case where master is at the same 00:59:02.559 --> 00:59:07.809 place as cat and I'm about to merge in 00:59:04.750 --> 00:59:10.660 dog so I do get merged dog and it says 00:59:07.809 --> 00:59:12.130 conflict merge conflict in animal Pi so 00:59:10.660 --> 00:59:16.089 let's just look at animal dot PI 00:59:12.130 --> 00:59:18.910 directly so it looks like this top part 00:59:16.089 --> 00:59:20.650 looks pretty reasonable it has both the 00:59:18.910 --> 00:59:22.779 cat function and the dog function which 00:59:20.650 --> 00:59:24.130 is exactly what I want but now I see 00:59:22.779 --> 00:59:25.480 some weird stuff in main and this is 00:59:24.130 --> 00:59:28.829 where I add slightly incompatible 00:59:25.480 --> 00:59:31.450 changes so here it says that in one 00:59:28.829 --> 00:59:34.690 thing like basically the branch you were 00:59:31.450 --> 00:59:36.369 on you had this content and then the 00:59:34.690 --> 00:59:38.859 branch you're trying to merge had this 00:59:36.369 --> 00:59:41.079 content and then these things here the 00:59:38.859 --> 00:59:43.000 angle brackets and the equals our 00:59:41.079 --> 00:59:43.960 conflict markers so this is where you 00:59:43.000 --> 00:59:45.940 were and this is the thing you're trying 00:59:43.960 --> 00:59:48.130 to merge in and it's basically saying 00:59:45.940 --> 00:59:49.420 that it was this on one case this in the 00:59:48.130 --> 00:59:50.050 other case and it doesn't really know 00:59:49.420 --> 00:59:51.520 how to resolve 00:59:50.050 --> 00:59:54.400 these two and it's left up to the 00:59:51.520 --> 00:59:55.630 programmer to fix this problem so in 00:59:54.400 --> 00:59:58.140 this particular case we can go ahead and 00:59:55.630 --> 00:59:59.910 delete the conflict markers and then 00:59:58.140 --> 01:00:01.930 turns out that we can actually 00:59:59.910 --> 01:00:03.520 concatenate this code together and does 01:00:01.930 --> 01:00:05.770 the right thing maybe we want to make a 01:00:03.520 --> 01:00:07.090 small change like this should be an if 01:00:05.770 --> 01:00:09.520 this should be an else--if and this 01:00:07.090 --> 01:00:12.760 should be an else that might make a 01:00:09.520 --> 01:00:14.530 little bit more sense actually I think 01:00:12.760 --> 01:00:16.870 it's necessary for correctness here so 01:00:14.530 --> 01:00:18.100 the programmer needed to modify the code 01:00:16.870 --> 01:00:20.200 a little bit in order to make it 01:00:18.100 --> 01:00:22.290 sensible when it's merged together but 01:00:20.200 --> 01:00:25.240 once the programmer has fixed the merge 01:00:22.290 --> 01:00:27.340 conflicts fixed the stuff between the 01:00:25.240 --> 01:00:30.370 conflict markers you can save this file 01:00:27.340 --> 01:00:35.380 and we can do get merged - - continue to 01:00:30.370 --> 01:00:37.990 tell git that we fix the issues it's 01:00:35.380 --> 01:00:39.310 necessary to re add animal PI to tell 01:00:37.990 --> 01:00:41.050 git that we've actually fixed these 01:00:39.310 --> 01:00:43.390 issues and then we need to get merged - 01:00:41.050 --> 01:00:44.710 - continue it pops up an editor and we 01:00:43.390 --> 01:00:46.150 can give a commit message for this new 01:00:44.710 --> 01:00:48.610 commit that we're about to create and 01:00:46.150 --> 01:00:52.330 now if we look at the git history we 01:00:48.610 --> 01:00:55.270 have the single commit that represents 01:00:52.330 --> 01:00:58.570 our merge commit that we just made which 01:00:55.270 --> 01:01:02.050 merges in the dog functionality and here 01:00:58.570 --> 01:01:03.820 this has as parents both the dog commit 01:01:02.050 --> 01:01:05.560 and the cat commit 01:01:03.820 --> 01:01:07.120 so both these branches appear in our 01:01:05.560 --> 01:01:09.100 history from this point backwards and 01:01:07.120 --> 01:01:10.960 this current commit that we're on 01:01:09.100 --> 01:01:15.280 incorporates the functionality from both 01:01:10.960 --> 01:01:16.750 of these branches so if we run animal 01:01:15.280 --> 01:01:18.160 duck fight with cat it does the cat 01:01:16.750 --> 01:01:19.810 thing if we run it with dog it does the 01:01:18.160 --> 01:01:21.520 dog thing and if we run it with anything 01:01:19.810 --> 01:01:23.920 else it falls back to the default 01:01:21.520 --> 01:01:26.890 implementation so this is a 01:01:23.920 --> 01:01:28.540 demonstration of how you branch and get 01:01:26.890 --> 01:01:30.310 to do development on different things in 01:01:28.540 --> 01:01:32.680 parallel and then how you can use the 01:01:30.310 --> 01:01:34.210 merge command and get to resolve those 01:01:32.680 --> 01:01:35.740 different branches and combine them 01:01:34.210 --> 01:01:37.540 together into a single snapshot that 01:01:35.740 --> 01:01:41.100 includes all the functionality that was 01:01:37.540 --> 01:01:43.390 developed in parallel with each other 01:01:41.100 --> 01:01:45.070 and then one thing that can happen when 01:01:43.390 --> 01:01:47.380 you're doing get branching and merging 01:01:45.070 --> 01:01:49.990 is you run into merge conflicts and 01:01:47.380 --> 01:01:51.670 these conflicts show up as conflict 01:01:49.990 --> 01:01:53.980 markers and text files you can manually 01:01:51.670 --> 01:01:55.360 resolve them and kit also has some tools 01:01:53.980 --> 01:01:57.100 that can help with this though these 01:01:55.360 --> 01:01:58.450 tools are kind of advanced and will only 01:01:57.100 --> 01:02:00.480 refer to them in the lecture notes and 01:01:58.450 --> 01:02:03.640 not actually demonstrate them for you 01:02:00.480 --> 01:02:08.560 so that's get branching and merging 01:02:03.640 --> 01:02:12.070 any questions no great so moving on to 01:02:08.560 --> 01:02:14.230 the next topic of this lecture we will 01:02:12.070 --> 01:02:15.760 talk about git remotes so this is 01:02:14.230 --> 01:02:19.990 basically how you collaborate with other 01:02:15.760 --> 01:02:21.660 people using git a git repository the 01:02:19.990 --> 01:02:24.340 stuff contained in this dot git folder 01:02:21.660 --> 01:02:26.080 represents kind of an entire copy of the 01:02:24.340 --> 01:02:27.940 history it has the objects in the 01:02:26.080 --> 01:02:30.520 references and contains all the previous 01:02:27.940 --> 01:02:32.680 snapshots and the way you collaborate 01:02:30.520 --> 01:02:34.510 with other people using git is that 01:02:32.680 --> 01:02:37.950 other people can also have copies of the 01:02:34.510 --> 01:02:41.710 entire git repository and then your get 01:02:37.950 --> 01:02:43.960 copy your local instantiation of the 01:02:41.710 --> 01:02:46.540 repository can be aware of the existence 01:02:43.960 --> 01:02:48.820 of other clones of the same repository 01:02:46.540 --> 01:02:51.850 and this is a concept known as remotes 01:02:48.820 --> 01:02:54.370 so the git remote command will list all 01:02:51.850 --> 01:02:57.220 the remotes that git is aware of for the 01:02:54.370 --> 01:02:59.260 current repository and in our case with 01:02:57.220 --> 01:03:01.090 this repository right here this command 01:02:59.260 --> 01:03:02.680 get remote just doesn't print anything 01:03:01.090 --> 01:03:05.590 because we haven't configured any 01:03:02.680 --> 01:03:07.210 remotes it is only aware of the single 01:03:05.590 --> 01:03:09.850 local copy of the repository that we're 01:03:07.210 --> 01:03:11.050 working with here but in practice if 01:03:09.850 --> 01:03:13.390 you're collaborating with other people 01:03:11.050 --> 01:03:15.580 your git might be aware of the copy of 01:03:13.390 --> 01:03:17.320 the code that is on github and then 01:03:15.580 --> 01:03:18.880 there's a set of commands to send 01:03:17.320 --> 01:03:21.490 changes from your local copy of the 01:03:18.880 --> 01:03:23.050 repository to a remote that your get is 01:03:21.490 --> 01:03:24.940 aware of so sending stuff from your 01:03:23.050 --> 01:03:26.620 computer to github for example and 01:03:24.940 --> 01:03:28.990 there's another set of commands for 01:03:26.620 --> 01:03:31.000 fetching changes made in a local 01:03:28.990 --> 01:03:34.450 repository to get changes from github 01:03:31.000 --> 01:03:37.060 into your own local copy in this 01:03:34.450 --> 01:03:38.860 demonstration here we actually won't go 01:03:37.060 --> 01:03:40.390 and configure a github account and log 01:03:38.860 --> 01:03:42.010 in and create a new repository on there 01:03:40.390 --> 01:03:44.050 you can find other tutorials for doing 01:03:42.010 --> 01:03:46.750 that we'll actually just use a separate 01:03:44.050 --> 01:03:49.330 folder on the same computer and treat it 01:03:46.750 --> 01:03:52.510 like a git remote so let me I'm in the 01:03:49.330 --> 01:03:54.280 demo folder here let me go up one 01:03:52.510 --> 01:03:56.190 directory I have a directory called 01:03:54.280 --> 01:03:59.680 playground that has this demo folder and 01:03:56.190 --> 01:04:04.350 I'll go ahead and create a new directory 01:03:59.680 --> 01:04:07.240 in here and I'll call it remote and then 01:04:04.350 --> 01:04:08.230 do get in it - - bear in here those are 01:04:07.240 --> 01:04:11.470 the command that you'll probably never 01:04:08.230 --> 01:04:13.660 need to use in regular usage but now 01:04:11.470 --> 01:04:15.820 what I've done is made remote into a 01:04:13.660 --> 01:04:16.750 folder that's appropriate to use as a 01:04:15.820 --> 01:04:19.060 git remote 01:04:16.750 --> 01:04:22.359 so now going back into my demo folder 01:04:19.060 --> 01:04:23.470 here might mean repository I can do get 01:04:22.359 --> 01:04:26.290 remote to list the remotes 01:04:23.470 --> 01:04:29.680 there's nothing yet but I can use the 01:04:26.290 --> 01:04:31.690 git remote add functionality to make my 01:04:29.680 --> 01:04:35.230 local repository aware of the existence 01:04:31.690 --> 01:04:37.060 of a remote so I can do git remote add 01:04:35.230 --> 01:04:39.790 and then the format for this is that 01:04:37.060 --> 01:04:42.700 remotes have names and then they have a 01:04:39.790 --> 01:04:45.130 URL so in this case I'll use the name 01:04:42.700 --> 01:04:46.869 origin does often use by convention as 01:04:45.130 --> 01:04:49.780 the name of the remote if you're only 01:04:46.869 --> 01:04:51.369 using one and then for the URL normally 01:04:49.780 --> 01:04:53.320 this will be like a github URL or 01:04:51.369 --> 01:04:55.150 something like that or bitbucket URL or 01:04:53.320 --> 01:04:57.790 get live URL if you're using an online 01:04:55.150 --> 01:05:00.430 repository hosting service but in this 01:04:57.790 --> 01:05:02.260 case it's just a path to a folder on my 01:05:00.430 --> 01:05:04.000 local machine there's a folder in the 01:05:02.260 --> 01:05:05.680 parent directory called remote that will 01:05:04.000 --> 01:05:08.880 act as the git remote for this 01:05:05.680 --> 01:05:10.780 repository so now once I've done that 01:05:08.880 --> 01:05:13.540 there's a set of commands for 01:05:10.780 --> 01:05:15.359 interacting with this remote one command 01:05:13.540 --> 01:05:18.520 that's useful is the git push command 01:05:15.359 --> 01:05:20.830 this command can send the changes from 01:05:18.520 --> 01:05:22.750 your computer to the remote and the 01:05:20.830 --> 01:05:25.119 format for this command is that git push 01:05:22.750 --> 01:05:27.640 takes in the name of a remote and then 01:05:25.119 --> 01:05:29.650 it takes in a local branch name : a 01:05:27.640 --> 01:05:31.480 remote branch name and what it does is 01:05:29.650 --> 01:05:33.730 it creates a new branch or updates a 01:05:31.480 --> 01:05:36.670 branch on the remote with the name 01:05:33.730 --> 01:05:40.240 specified here and sets it to the 01:05:36.670 --> 01:05:41.980 contents of the branch specified here so 01:05:40.240 --> 01:05:44.830 a concrete use of this might look like 01:05:41.980 --> 01:05:48.670 git push I've only one remote called 01:05:44.830 --> 01:05:52.000 origin and then what should I push let 01:05:48.670 --> 01:05:53.589 me look at my history graph I have a 01:05:52.000 --> 01:05:56.859 bunch of things I could push let me get 01:05:53.589 --> 01:05:58.599 pushed to origin the master branch from 01:05:56.859 --> 01:06:01.119 my local machine : 01:05:58.599 --> 01:06:03.730 master so I want to create a branch on 01:06:01.119 --> 01:06:06.339 the remote machine with the name master 01:06:03.730 --> 01:06:08.830 that is going to be the same as the 01:06:06.339 --> 01:06:10.089 master branch on my local machine so let 01:06:08.830 --> 01:06:12.250 me go ahead and run that command it 01:06:10.089 --> 01:06:14.380 prints out some stuff and it says on the 01:06:12.250 --> 01:06:16.480 remote I created a new branch remote 01:06:14.380 --> 01:06:19.150 master points to the same branch as 01:06:16.480 --> 01:06:23.290 master on my local machine and now if I 01:06:19.150 --> 01:06:25.839 do a git log it shows me so in blue is 01:06:23.290 --> 01:06:27.490 head where I currently am in green are 01:06:25.839 --> 01:06:29.560 all the branches in my local git 01:06:27.490 --> 01:06:30.400 repository and now we see one new color 01:06:29.560 --> 01:06:32.950 here that we had 01:06:30.400 --> 01:06:34.569 seen before so in red get shows 01:06:32.950 --> 01:06:36.730 references that are present on the 01:06:34.569 --> 01:06:39.760 remotes that my local copy is aware of 01:06:36.730 --> 01:06:41.470 so on the remote origin there's also a 01:06:39.760 --> 01:06:43.630 branch that happens to have the name 01:06:41.470 --> 01:06:47.740 master that points to the same place as 01:06:43.630 --> 01:06:49.720 my local branch master points and so now 01:06:47.740 --> 01:06:52.510 if I make updates to my local copies 01:06:49.720 --> 01:06:56.680 like suppose here I go in and change the 01:06:52.510 --> 01:06:59.500 capitalization of these things and then 01:06:56.680 --> 01:07:01.390 get had animal dot hi get commit here's 01:06:59.500 --> 01:07:03.010 a short form for commit with a message 01:07:01.390 --> 01:07:04.390 so it doesn't pop up the editor I'll 01:07:03.010 --> 01:07:08.020 give it a late and commit message and 01:07:04.390 --> 01:07:10.029 now if I look at the git graph now I see 01:07:08.020 --> 01:07:11.740 that I've created this new snapshot here 01:07:10.029 --> 01:07:15.760 that has this lower casing stuff in it 01:07:11.740 --> 01:07:17.980 but origin master is still back here so 01:07:15.760 --> 01:07:20.049 if somebody else looks at the remote 01:07:17.980 --> 01:07:21.520 they will only see the changes up to 01:07:20.049 --> 01:07:23.559 here and we can actually demonstrate 01:07:21.520 --> 01:07:27.190 this functionality so let me go ahead 01:07:23.559 --> 01:07:29.950 and open up a new tab here and go into 01:07:27.190 --> 01:07:31.990 my playground directory the git clone 01:07:29.950 --> 01:07:34.839 command is a command that somebody can 01:07:31.990 --> 01:07:36.460 use to start from some copy of a 01:07:34.839 --> 01:07:38.770 repository somewhere and make their own 01:07:36.460 --> 01:07:40.089 local copy so this is often a command to 01:07:38.770 --> 01:07:41.260 use when starting out with a git repo 01:07:40.089 --> 01:07:43.329 like there might be something available 01:07:41.260 --> 01:07:45.069 on github and you want to copy it all in 01:07:43.329 --> 01:07:46.960 your machine in order to look at it or 01:07:45.069 --> 01:07:49.000 start doing development and so the 01:07:46.960 --> 01:07:51.130 format for git clone is that it takes in 01:07:49.000 --> 01:07:55.420 a URL and then it takes in a name for a 01:07:51.130 --> 01:07:57.549 folder for where to clone it so in our 01:07:55.420 --> 01:07:59.680 case here we're just going to clone from 01:07:57.549 --> 01:08:01.029 this remote directory we're pretending 01:07:59.680 --> 01:08:03.609 that this remote folder is actually a 01:08:01.029 --> 01:08:06.819 remote machine and then we're all clone 01:08:03.609 --> 01:08:10.450 it into the folder called demo two so 01:08:06.819 --> 01:08:13.029 cloning into demo 2 done and I'm going 01:08:10.450 --> 01:08:14.829 to CD into that directory and then now 01:08:13.029 --> 01:08:19.569 here I'm going to rename these tabs at 01:08:14.829 --> 01:08:21.520 the bottom I will say this one's machine 01:08:19.569 --> 01:08:23.080 one and this one's machine too so you 01:08:21.520 --> 01:08:25.029 can think of these as two different 01:08:23.080 --> 01:08:27.850 people on different machines with their 01:08:25.029 --> 01:08:29.589 own copy of the repository and they're 01:08:27.850 --> 01:08:31.779 both interacting with the single remote 01:08:29.589 --> 01:08:34.120 so if I do my get log command that I've 01:08:31.779 --> 01:08:36.279 been doing on machine one I see on 01:08:34.120 --> 01:08:41.139 Machine 2 I see this portion of the 01:08:36.279 --> 01:08:43.060 history so master on machine 2 is 01:08:41.139 --> 01:08:44.139 pointing to the same places origin 01:08:43.060 --> 01:08:47.080 master 01:08:44.139 --> 01:08:49.420 and it says merge branch dog so if I 01:08:47.080 --> 01:08:51.310 look at animal dot pie here 01:08:49.420 --> 01:08:53.139 it doesn't have the changes that I made 01:08:51.310 --> 01:08:56.199 on machine to even though there are 01:08:53.139 --> 01:08:58.270 sorry on machine one where I have this 01:08:56.199 --> 01:09:00.429 new commit that is only present on this 01:08:58.270 --> 01:09:03.369 machine but not on the remote and not on 01:09:00.429 --> 01:09:05.350 machine too so if I want to fix that if 01:09:03.369 --> 01:09:06.940 I want to send these changes up to the 01:09:05.350 --> 01:09:09.130 remote like think of it as sending it up 01:09:06.940 --> 01:09:11.350 to github err up to the machine that's 01:09:09.130 --> 01:09:13.719 holding or maintaining the source code I 01:09:11.350 --> 01:09:18.940 can use the git push command again git 01:09:13.719 --> 01:09:20.560 push origin master colon master and this 01:09:18.940 --> 01:09:21.909 will work but this is kind of annoying 01:09:20.560 --> 01:09:23.850 to type every time you want to do this 01:09:21.909 --> 01:09:26.199 like this is a really common operation 01:09:23.850 --> 01:09:28.980 so git has a way of making this a little 01:09:26.199 --> 01:09:31.569 bit simpler it has a way of maintaining 01:09:28.980 --> 01:09:34.480 relationships between branches on your 01:09:31.569 --> 01:09:36.670 own local machine and branches on remote 01:09:34.480 --> 01:09:39.069 machines it is a way of knowing what 01:09:36.670 --> 01:09:41.409 branch on a remote machine a local 01:09:39.069 --> 01:09:43.060 branch corresponds to so that you can 01:09:41.409 --> 01:09:45.250 type in a shortened version of git push 01:09:43.060 --> 01:09:47.290 and it'll know what all the arguments to 01:09:45.250 --> 01:09:49.389 the expanded form would have been and 01:09:47.290 --> 01:09:51.609 there a couple different syntaxes for 01:09:49.389 --> 01:09:55.090 doing this one way is to use the git 01:09:51.609 --> 01:09:57.489 branch - - set up stream to command and 01:09:55.090 --> 01:09:59.350 what this does is for the branch that's 01:09:57.489 --> 01:10:01.780 currently checked out which is master it 01:09:59.350 --> 01:10:05.170 will set the upstream - and I'll type in 01:10:01.780 --> 01:10:06.550 origin master and see now it says branch 01:10:05.170 --> 01:10:09.219 master set up to track remote branch 01:10:06.550 --> 01:10:12.159 master from origin now if I type in get 01:10:09.219 --> 01:10:13.389 branch - VV remember this is tell me 01:10:12.159 --> 01:10:15.340 about all the branches that I know about 01:10:13.389 --> 01:10:17.770 in a very verbose way that's what the - 01:10:15.340 --> 01:10:20.139 VV means I have three branches on my 01:10:17.770 --> 01:10:23.440 local machine on machine one I have cat 01:10:20.139 --> 01:10:27.250 dog and master and master on my local 01:10:23.440 --> 01:10:30.070 machine corresponds to origin master so 01:10:27.250 --> 01:10:31.840 now I can type in just get push without 01:10:30.070 --> 01:10:33.369 all the extra arguments I could have 01:10:31.840 --> 01:10:35.409 done this as git push origin master 01:10:33.369 --> 01:10:38.020 colon master but it wasn't necessary 01:10:35.409 --> 01:10:40.650 it'll know that I want to push to origin 01:10:38.020 --> 01:10:42.969 master and it will make that change 01:10:40.650 --> 01:10:44.739 so now these changes are present on the 01:10:42.969 --> 01:10:46.119 remote we can go over to machine to 01:10:44.739 --> 01:10:49.150 pretend we're the other guy interacting 01:10:46.119 --> 01:10:51.429 with this repository and if I do might 01:10:49.150 --> 01:10:53.349 get logged command I still don't see the 01:10:51.429 --> 01:10:55.929 changes so what's going on here 01:10:53.349 --> 01:10:57.010 well it's necessary in order to run a 01:10:55.929 --> 01:10:58.450 separate command 01:10:57.010 --> 01:11:00.220 or it's necessary to run a separate 01:10:58.450 --> 01:11:03.070 command in order to have these changes 01:11:00.220 --> 01:11:05.140 present here by default all the get 01:11:03.070 --> 01:11:06.400 commands don't talk to the internet it 01:11:05.140 --> 01:11:08.590 all works locally which means it works 01:11:06.400 --> 01:11:09.880 very fast but then there are special 01:11:08.590 --> 01:11:11.320 commands for saying that you want to 01:11:09.880 --> 01:11:13.600 retrieve changes that have made 01:11:11.320 --> 01:11:15.190 somewhere else and the command that's 01:11:13.600 --> 01:11:18.610 used for doing that is a command called 01:11:15.190 --> 01:11:20.590 git fetch get fetch takes thee as an 01:11:18.610 --> 01:11:22.870 argument the name of the remote but if 01:11:20.590 --> 01:11:26.170 there's only one it'll just use that so 01:11:22.870 --> 01:11:29.890 you can type in git fetch and then it's 01:11:26.170 --> 01:11:32.890 talked to this remote repository and it 01:11:29.890 --> 01:11:34.510 says that there's some update on the 01:11:32.890 --> 01:11:37.000 remote and we can visualize it by 01:11:34.510 --> 01:11:38.410 running git log and now we see here 01:11:37.000 --> 01:11:41.290 another situation that we hadn't seen 01:11:38.410 --> 01:11:42.940 before we have master on our local 01:11:41.290 --> 01:11:45.400 machine the master branch doesn't change 01:11:42.940 --> 01:11:47.080 the git fetch command doesn't change any 01:11:45.400 --> 01:11:49.180 of our local history our local 01:11:47.080 --> 01:11:51.610 references like our branches but now 01:11:49.180 --> 01:11:54.640 it's aware that origin master has been 01:11:51.610 --> 01:11:56.650 updated to point to this new commit and 01:11:54.640 --> 01:12:01.320 there's a separate command we can do get 01:11:56.650 --> 01:12:03.460 merge in order to move master up to here 01:12:01.320 --> 01:12:05.560 or there's another command called get 01:12:03.460 --> 01:12:09.040 pull which is the same as doing git 01:12:05.560 --> 01:12:11.860 fetch and then get merge so if we just 01:12:09.040 --> 01:12:13.450 do get pull here for example it will say 01:12:11.860 --> 01:12:16.930 it's fast forwarding is merging in 01:12:13.450 --> 01:12:20.620 origin master into our master and now if 01:12:16.930 --> 01:12:22.330 we look at the git history graph we've 01:12:20.620 --> 01:12:24.070 currently checked out master master 01:12:22.330 --> 01:12:25.900 points to the same place as the origin 01:12:24.070 --> 01:12:27.580 master that we're aware of and all the 01:12:25.900 --> 01:12:30.790 changes between Machine 2 and Machine 1 01:12:27.580 --> 01:12:31.960 are in sync so those are the basic 01:12:30.790 --> 01:12:33.460 commands for interacting with git 01:12:31.960 --> 01:12:35.620 remotes so there's the git remote 01:12:33.460 --> 01:12:37.420 command for listing remotes and adding 01:12:35.620 --> 01:12:40.239 and removing them and things like that 01:12:37.420 --> 01:12:42.400 and then there's the git push command 01:12:40.239 --> 01:12:45.340 for sending changes from your local copy 01:12:42.400 --> 01:12:46.989 of the repository to the remote and then 01:12:45.340 --> 01:12:48.940 there's the git fetch command which is 01:12:46.989 --> 01:12:51.340 for retrieving changes to a repository 01:12:48.940 --> 01:12:54.270 that are present on a remote and getting 01:12:51.340 --> 01:12:56.620 the changes on your local machine and 01:12:54.270 --> 01:12:58.630 once you retrieve those changes you can 01:12:56.620 --> 01:13:00.730 use git merge to update your local 01:12:58.630 --> 01:13:03.100 branch to point to the same place where 01:13:00.730 --> 01:13:04.870 the remote branch does or you can use 01:13:03.100 --> 01:13:06.340 the git pull command which does 01:13:04.870 --> 01:13:09.100 basically the same thing as get fetch 01:13:06.340 --> 01:13:10.720 plus git merge and then of course 01:13:09.100 --> 01:13:12.730 separate from all these commands 01:13:10.720 --> 01:13:14.560 is the clone command that we talked 01:13:12.730 --> 01:13:16.950 about a little while ago which is for 01:13:14.560 --> 01:13:19.780 taking a copy of remote repository and 01:13:16.950 --> 01:13:23.950 initializing the local repository from 01:13:19.780 --> 01:13:25.930 that copy so that's a quick overview of 01:13:23.950 --> 01:13:27.940 the different commands used to interact 01:13:25.930 --> 01:13:29.650 with git remotes and now these are kind 01:13:27.940 --> 01:13:31.180 of complicated and it takes a while to 01:13:29.650 --> 01:13:32.650 master all the different variations of 01:13:31.180 --> 01:13:34.570 this and understand how they're actually 01:13:32.650 --> 01:13:36.460 used in practice but hopefully this acts 01:13:34.570 --> 01:13:38.380 as a quick introduction and you can see 01:13:36.460 --> 01:13:40.570 how the different commands relate to the 01:13:38.380 --> 01:13:42.670 underlying data model all these commands 01:13:40.570 --> 01:13:44.320 all they do is fetch new objects from 01:13:42.670 --> 01:13:46.510 other places or send objects from the 01:13:44.320 --> 01:13:51.220 local mission to other places and these 01:13:46.510 --> 01:13:54.340 commands mutate references so relating 01:13:51.220 --> 01:13:56.260 these relating the interface of git and 01:13:54.340 --> 01:13:58.270 some of these kind of badly designed 01:13:56.260 --> 01:14:03.880 commands to the underlying data model 01:13:58.270 --> 01:14:05.590 can help it make a lot more sense the 01:14:03.880 --> 01:14:09.460 final topic we're going to cover today 01:14:05.590 --> 01:14:10.930 is it's a kind of overview of other 01:14:09.460 --> 01:14:12.580 things that get can do that we're not 01:14:10.930 --> 01:14:14.680 going to go into detail in teaching you 01:14:12.580 --> 01:14:16.690 how to do but we just want to tell you 01:14:14.680 --> 01:14:17.980 that these functionalities exist in case 01:14:16.690 --> 01:14:19.330 you need to do these things yourself you 01:14:17.980 --> 01:14:21.820 can look up the documentation and find 01:14:19.330 --> 01:14:24.610 out exactly how to do it one thing is 01:14:21.820 --> 01:14:26.680 the git config command like a lot of 01:14:24.610 --> 01:14:27.760 tools we've looked at like the shell and 01:14:26.680 --> 01:14:30.100 T MUX and things like that 01:14:27.760 --> 01:14:32.410 git is highly configurable and it's 01:14:30.100 --> 01:14:33.640 configured using a plain text file which 01:14:32.410 --> 01:14:35.740 can be edited either through the 01:14:33.640 --> 01:14:37.630 command-line interface so git config can 01:14:35.740 --> 01:14:40.840 take in flags that will modify this text 01:14:37.630 --> 01:14:43.930 file or you can edit the dot git config 01:14:40.840 --> 01:14:47.350 file in the home folder with plain text 01:14:43.930 --> 01:14:49.270 configuration and so for this lecture 01:14:47.350 --> 01:14:52.510 I've actually cut out most of them I get 01:14:49.270 --> 01:14:55.330 config and only left in my username and 01:14:52.510 --> 01:14:56.830 email for what will go in to get commits 01:14:55.330 --> 01:14:59.590 but there's a lot of stuff you can put 01:14:56.830 --> 01:15:01.060 in here which will make it behave nicer 01:14:59.590 --> 01:15:02.860 it behaved the way you want it to and 01:15:01.060 --> 01:15:04.600 you can look online for different ways 01:15:02.860 --> 01:15:06.520 people have configured their get configs 01:15:04.600 --> 01:15:07.270 oftentimes people have documentation in 01:15:06.520 --> 01:15:13.330 their kit configs 01:15:07.270 --> 01:15:14.710 which can be found on github there's a 01:15:13.330 --> 01:15:16.270 couple other random commands that could 01:15:14.710 --> 01:15:18.640 be useful one is for when you want to 01:15:16.270 --> 01:15:21.760 clone a repository with git clone that's 01:15:18.640 --> 01:15:24.630 really gigantic get cloned by default 01:15:21.760 --> 01:15:25.860 copies the entire version history for 01:15:24.630 --> 01:15:28.110 the remote it's downloading the 01:15:25.860 --> 01:15:30.080 repository from but there's an argument 01:15:28.110 --> 01:15:32.580 you can pass it which is - - shallow 01:15:30.080 --> 01:15:33.989 which will avoid doing that so if 01:15:32.580 --> 01:15:35.880 there's some copy of some code on github 01:15:33.989 --> 01:15:37.440 say that you want to get a copy copy of 01:15:35.880 --> 01:15:38.850 on your local machine but that 01:15:37.440 --> 01:15:40.920 repository is really gigantic and has a 01:15:38.850 --> 01:15:42.870 billion commits he's get cloned - - 01:15:40.920 --> 01:15:44.219 shallow this will be much faster but 01:15:42.870 --> 01:15:45.719 then of course he won't have the version 01:15:44.219 --> 01:15:49.739 history on your local machine you'll 01:15:45.719 --> 01:15:51.810 just have the latest snapshot another 01:15:49.739 --> 01:15:53.250 command that we find really useful when 01:15:51.810 --> 01:15:55.980 doing development on real software 01:15:53.250 --> 01:15:57.960 projects is an interactive version of 01:15:55.980 --> 01:15:59.460 the git add command so to demonstrate 01:15:57.960 --> 01:16:01.730 this I'm going to go ahead and make a 01:15:59.460 --> 01:16:05.219 couple different changes to my animal PI 01:16:01.730 --> 01:16:07.679 one change I'll make here I'll change 01:16:05.219 --> 01:16:10.320 some text here and then I'll put a new 01:16:07.679 --> 01:16:11.730 print statement here so let's pretend 01:16:10.320 --> 01:16:13.440 that this first change was some real 01:16:11.730 --> 01:16:15.780 change I wanted to make say it's a bug 01:16:13.440 --> 01:16:18.150 fix and this other change here was a 01:16:15.780 --> 01:16:19.380 printf that I added for debugging but I 01:16:18.150 --> 01:16:21.840 don't actually want to commit in the 01:16:19.380 --> 01:16:23.280 next snapshot if I do a get diff it'll 01:16:21.840 --> 01:16:25.530 show me that yes I've made these two 01:16:23.280 --> 01:16:29.130 changes and if I do get add animal dot 01:16:25.530 --> 01:16:30.960 pi it will stage both of those changes 01:16:29.130 --> 01:16:32.909 for a commit and that's not what I want 01:16:30.960 --> 01:16:34.800 I could go manually remove this debug 01:16:32.909 --> 01:16:37.409 print and then do this get animal dog 01:16:34.800 --> 01:16:38.310 get add animal dot PI but there's an 01:16:37.409 --> 01:16:40.469 easier way to do it 01:16:38.310 --> 01:16:43.020 there's this get add - pika man which 01:16:40.469 --> 01:16:44.909 lets me interactively stage pieces of 01:16:43.020 --> 01:16:46.860 files for it commit and so there's some 01:16:44.909 --> 01:16:47.909 interface for working with this so here 01:16:46.860 --> 01:16:49.409 it's saying do I want to stage both of 01:16:47.909 --> 01:16:50.520 these changes and no I don't but I'm 01:16:49.409 --> 01:16:53.310 going to split it into two smaller 01:16:50.520 --> 01:16:55.380 changes this one I do want to keep so I 01:16:53.310 --> 01:16:57.719 say Y for yes and this one I don't want 01:16:55.380 --> 01:17:01.860 to keep so I say n for no and then if I 01:16:57.719 --> 01:17:04.199 do get diff - - cached this will show me 01:17:01.860 --> 01:17:06.030 what changes are staged for commit so 01:17:04.199 --> 01:17:07.949 now it shows only the actual change I 01:17:06.030 --> 01:17:09.900 wanted to keep if I do get diff it'll 01:17:07.949 --> 01:17:12.630 still show me the other change that is 01:17:09.900 --> 01:17:14.340 not going to be part of the next the 01:17:12.630 --> 01:17:16.050 next commit which is the change I didn't 01:17:14.340 --> 01:17:18.960 want to keep and then with this I can do 01:17:16.050 --> 01:17:21.120 get commit specify some commit message 01:17:18.960 --> 01:17:22.679 now I only have this change left and 01:17:21.120 --> 01:17:26.010 then I can do get check out animal to 01:17:22.679 --> 01:17:28.139 apply to throw away this change so get 01:17:26.010 --> 01:17:31.679 add - P for interactive staging is a 01:17:28.139 --> 01:17:33.600 useful thing a couple other commands 01:17:31.679 --> 01:17:36.750 that you can look up on your own are the 01:17:33.600 --> 01:17:38.530 get blame command so this commands kind 01:17:36.750 --> 01:17:40.630 of ominous but it can be used to figure 01:17:38.530 --> 01:17:42.130 who edited what line of a file and you 01:17:40.630 --> 01:17:44.020 can also find the corresponding commit 01:17:42.130 --> 01:17:45.760 that was responsible for modifying that 01:17:44.020 --> 01:17:46.840 particular line of that file and then 01:17:45.760 --> 01:17:48.850 you can look up commit messages 01:17:46.840 --> 01:17:50.110 associated with that and whatnot so this 01:17:48.850 --> 01:17:52.120 is not that interesting to do in our 01:17:50.110 --> 01:17:54.010 current toy repository but I'll go over 01:17:52.120 --> 01:17:56.590 to the repository for the class website 01:17:54.010 --> 01:17:59.170 and we can look at some particular file 01:17:56.590 --> 01:18:01.150 here and let me go to some particular 01:17:59.170 --> 01:18:03.340 line here and I can be looking at this 01:18:01.150 --> 01:18:05.080 me like oh why was this particular line 01:18:03.340 --> 01:18:07.510 added what does it mean and I can look 01:18:05.080 --> 01:18:11.680 at the git blame for this so if I do get 01:18:07.510 --> 01:18:13.480 blame config dot yml it'll print out all 01:18:11.680 --> 01:18:15.370 the lines kind of in the right column 01:18:13.480 --> 01:18:17.260 and then in the left side it'll show me 01:18:15.370 --> 01:18:20.260 what commits that change was made in and 01:18:17.260 --> 01:18:24.700 by whom and then looking at this like I 01:18:20.260 --> 01:18:27.520 can go down to this collections line it 01:18:24.700 --> 01:18:29.500 was made in this commit that's the last 01:18:27.520 --> 01:18:32.200 commit that modified that line and now I 01:18:29.500 --> 01:18:33.910 can use the git show command to get 01:18:32.200 --> 01:18:36.280 information for that particular commit 01:18:33.910 --> 01:18:37.930 oh and this is kind of useful redo 01:18:36.280 --> 01:18:40.120 lectures is a collection that's probably 01:18:37.930 --> 01:18:43.210 what was related to that collections 01:18:40.120 --> 01:18:45.490 line and then beyond just showing the 01:18:43.210 --> 01:18:47.650 commit and the commit message it also 01:18:45.490 --> 01:18:48.820 shows me the actual changes introduced 01:18:47.650 --> 01:18:49.870 in that particular commit and they can 01:18:48.820 --> 01:18:52.840 go look through them and understand 01:18:49.870 --> 01:18:55.300 what's going on another kind of cool 01:18:52.840 --> 01:18:56.860 command is a command called git stash so 01:18:55.300 --> 01:18:58.900 let's go back to our demo repository and 01:18:56.860 --> 01:19:04.840 demonstrate that here so say if some 01:18:58.900 --> 01:19:07.600 changes here and I temporarily want to 01:19:04.840 --> 01:19:09.520 put them away if I do get stash it will 01:19:07.600 --> 01:19:12.430 revert my working directory to the state 01:19:09.520 --> 01:19:15.610 it was in at the last commit so if I do 01:19:12.430 --> 01:19:16.990 cat hollow text that change is gone but 01:19:15.610 --> 01:19:19.960 it's not just deleted its saved 01:19:16.990 --> 01:19:22.360 somewhere and if I do get stash pop it 01:19:19.960 --> 01:19:25.960 will undo the stash so now if I look at 01:19:22.360 --> 01:19:28.780 hello text it has the changes I made so 01:19:25.960 --> 01:19:30.130 yet another useful command another 01:19:28.780 --> 01:19:32.590 really neat command is something called 01:19:30.130 --> 01:19:33.490 git bisect and this has a complicated 01:19:32.590 --> 01:19:35.710 interface that we're not going to 01:19:33.490 --> 01:19:37.240 demonstrate in detail but basically this 01:19:35.710 --> 01:19:38.260 is a tool that can be used to solve a 01:19:37.240 --> 01:19:40.200 bunch of problems where you need to 01:19:38.260 --> 01:19:42.550 manually search history for something 01:19:40.200 --> 01:19:43.750 suppose you're in a scenario where 01:19:42.550 --> 01:19:45.100 you've been working on a project for a 01:19:43.750 --> 01:19:47.020 long time you have lots and lots of 01:19:45.100 --> 01:19:48.790 snapshots you're a thousand commits in 01:19:47.020 --> 01:19:50.950 and then you notice that some unit test 01:19:48.790 --> 01:19:52.340 doesn't pass anymore but you know that 01:19:50.950 --> 01:19:53.989 this was passing like 01:19:52.340 --> 01:19:56.360 year ago and you're trying to figure out 01:19:53.989 --> 01:19:57.830 at what point did it break like at what 01:19:56.360 --> 01:19:59.630 point was this regression in your code 01:19:57.830 --> 01:20:01.550 introduced so one thing you could do is 01:19:59.630 --> 01:20:02.810 manually check out like go back one 01:20:01.550 --> 01:20:04.190 commit and see if the unit test is still 01:20:02.810 --> 01:20:05.810 failing go back one commit see if it's 01:20:04.190 --> 01:20:08.300 still failing and eventually you'll find 01:20:05.810 --> 01:20:10.099 the first commit where the test stopped 01:20:08.300 --> 01:20:13.159 working and it'll probably tell you like 01:20:10.099 --> 01:20:15.170 what broke but that's kind of annoying 01:20:13.159 --> 01:20:17.630 to do manually get by sight automates 01:20:15.170 --> 01:20:19.190 that process and it actually binary 01:20:17.630 --> 01:20:21.590 searches your history so it does this in 01:20:19.190 --> 01:20:23.630 the most efficient way possible and not 01:20:21.590 --> 01:20:25.280 only that get bisect can take in a 01:20:23.630 --> 01:20:26.929 scripts that it uses to try to figure 01:20:25.280 --> 01:20:28.610 out whether a committed looking at is 01:20:26.929 --> 01:20:31.099 good or bad so it can be a fully 01:20:28.610 --> 01:20:33.440 automated process like you can give git 01:20:31.099 --> 01:20:34.849 bisect a unit test and say find the 01:20:33.440 --> 01:20:37.460 first commit where this unit test 01:20:34.849 --> 01:20:42.320 stopped passing it's a really powerful 01:20:37.460 --> 01:20:43.670 tool another random thing that's kind of 01:20:42.320 --> 01:20:47.510 useful is something called a git ignore 01:20:43.670 --> 01:20:49.940 file so by default if you have random 01:20:47.510 --> 01:20:55.550 files in a directory like let me create 01:20:49.940 --> 01:20:57.980 the dot d s underscore store file whoops 01:20:55.550 --> 01:21:02.060 create the dot d s underscore store file 01:20:57.980 --> 01:21:03.679 and then do git status so D s stores 01:21:02.060 --> 01:21:04.820 like some nuisance file that Mac OS 01:21:03.679 --> 01:21:06.860 creates I don't know exactly what goes 01:21:04.820 --> 01:21:09.440 in here but basically once this file is 01:21:06.860 --> 01:21:10.969 in this directory now whenever I do get 01:21:09.440 --> 01:21:12.830 status it says oh there's this new file 01:21:10.969 --> 01:21:14.389 that I've never heard of it before but 01:21:12.830 --> 01:21:16.880 it apparently here like do you want to 01:21:14.389 --> 01:21:18.320 add it and this sort of tough stuff gets 01:21:16.880 --> 01:21:20.570 annoying and there's a lot of other 01:21:18.320 --> 01:21:22.489 stuff beyond OS specific garbage that 01:21:20.570 --> 01:21:24.199 might be in a directory like for example 01:21:22.489 --> 01:21:26.119 if you're working with C code you might 01:21:24.199 --> 01:21:28.130 compile it and produce dot o files or 01:21:26.119 --> 01:21:29.630 executable files or things like that and 01:21:28.130 --> 01:21:31.340 you probably don't want binaries to be 01:21:29.630 --> 01:21:34.040 part of your commit history you only 01:21:31.340 --> 01:21:37.099 want the source code and so git has a 01:21:34.040 --> 01:21:38.719 way of you being able to tell the tool 01:21:37.099 --> 01:21:40.429 that you don't care about a particular 01:21:38.719 --> 01:21:41.869 set of files and to ignore them and 01:21:40.429 --> 01:21:44.750 that's something called a git ignore 01:21:41.869 --> 01:21:46.639 file so if I go and modify the file 01:21:44.750 --> 01:21:49.190 called git ignore in the current 01:21:46.639 --> 01:21:52.070 directory I can specify particular file 01:21:49.190 --> 01:21:53.960 names or patterns of file names like say 01:21:52.070 --> 01:21:56.989 I can specify star dot o so any file 01:21:53.960 --> 01:21:59.810 ending in dot o along with da store and 01:21:56.989 --> 01:22:00.699 now if I touch food oh and now do a get 01:21:59.810 --> 01:22:03.380 status 01:22:00.699 --> 01:22:04.520 I'll see that git says okay I've 01:22:03.380 --> 01:22:05.630 hollowed out tax which I've modified 01:22:04.520 --> 01:22:07.310 sure and 01:22:05.630 --> 01:22:09.889 and I have get ignore so you should 01:22:07.310 --> 01:22:12.710 track your get ignore file using it but 01:22:09.889 --> 01:22:15.500 notice that it doesn't mention my dot d 01:22:12.710 --> 01:22:16.610 s store file or my food out o file 01:22:15.500 --> 01:22:20.540 that's present in the current directory 01:22:16.610 --> 01:22:22.699 because that has been get ignored so 01:22:20.540 --> 01:22:24.139 that's a quick overview of a little bit 01:22:22.699 --> 01:22:26.000 of advanced get functionality just to 01:22:24.139 --> 01:22:30.080 give you a flavor of what sorts of cool 01:22:26.000 --> 01:22:32.750 things this tool can do and then finally 01:22:30.080 --> 01:22:34.280 we have a couple other topics that are 01:22:32.750 --> 01:22:36.560 covered in the lecture notes in more 01:22:34.280 --> 01:22:38.719 detail I'll just quickly list them here 01:22:36.560 --> 01:22:40.760 so you know what to look for one is that 01:22:38.719 --> 01:22:43.909 there are many graphical clients forget 01:22:40.760 --> 01:22:45.980 we don't personally use them we like the 01:22:43.909 --> 01:22:47.120 git command line tool but some of them 01:22:45.980 --> 01:22:48.620 are kind of ok and you might want to 01:22:47.120 --> 01:22:52.639 check them out just to see if you prefer 01:22:48.620 --> 01:22:54.620 using those another thing is shell 01:22:52.639 --> 01:22:56.600 integration so you've noticed that in 01:22:54.620 --> 01:22:58.070 this tutorial I've done get status a 01:22:56.600 --> 01:23:00.620 whole bunch to see kind of what's going 01:22:58.070 --> 01:23:02.150 on with my repository well that's kind 01:23:00.620 --> 01:23:04.159 of annoying to do and a lot of people 01:23:02.150 --> 01:23:05.780 have their shell prompts set up so that 01:23:04.159 --> 01:23:07.940 just within this shell prompt itself 01:23:05.780 --> 01:23:10.040 like on every line it will show me a 01:23:07.940 --> 01:23:12.050 very succinct summary of what's going on 01:23:10.040 --> 01:23:13.880 with my repository so it might show me a 01:23:12.050 --> 01:23:15.710 summary of what branch I have currently 01:23:13.880 --> 01:23:17.840 checked out along with maybe if I've 01:23:15.710 --> 01:23:19.159 modified files or untracked files and so 01:23:17.840 --> 01:23:21.139 we have a link in the lecture notes on 01:23:19.159 --> 01:23:24.560 how to get some nice shell integration 01:23:21.139 --> 01:23:27.620 for displaying kind of get related 01:23:24.560 --> 01:23:29.300 information in your shell prompt similar 01:23:27.620 --> 01:23:31.460 to that you can get integrations with 01:23:29.300 --> 01:23:35.300 your text editor so for example I use 01:23:31.460 --> 01:23:36.590 vim and I have a plug-in for vim that 01:23:35.300 --> 01:23:38.270 does all sorts of interesting get 01:23:36.590 --> 01:23:39.860 related stuff one thing I can do with 01:23:38.270 --> 01:23:41.659 this plug-in is look at get blame 01:23:39.860 --> 01:23:43.159 information remember we just looked at 01:23:41.659 --> 01:23:44.840 this through the command line instead I 01:23:43.159 --> 01:23:47.000 can look at it with this plug-in and it 01:23:44.840 --> 01:23:48.830 lets me work with it a lot faster I can 01:23:47.000 --> 01:23:50.480 look at get blame press enter when 01:23:48.830 --> 01:23:52.639 hovering over a specific commit and it 01:23:50.480 --> 01:23:55.070 shows me that particular commit in my 01:23:52.639 --> 01:23:56.750 text editor it even hides all the other 01:23:55.070 --> 01:23:58.070 files and shows me just the one file I 01:23:56.750 --> 01:24:00.139 was looking at which is presumably what 01:23:58.070 --> 01:24:04.820 I care about so we have links to that in 01:24:00.139 --> 01:24:05.900 the lecture notes as well and there are 01:24:04.820 --> 01:24:07.630 a couple of there interesting things you 01:24:05.900 --> 01:24:11.150 could look at there if you're interested 01:24:07.630 --> 01:24:12.380 finally this lecture by itself is 01:24:11.150 --> 01:24:13.790 probably not enough to teach you 01:24:12.380 --> 01:24:16.219 everything you need to know about git 01:24:13.790 --> 01:24:17.510 it's a good start we think that the 01:24:16.219 --> 01:24:18.239 right way of learning get was to learn 01:24:17.510 --> 01:24:19.530 about 01:24:18.239 --> 01:24:21.059 the underlying data model the whole 01:24:19.530 --> 01:24:23.159 objects and references and how get 01:24:21.059 --> 01:24:25.050 models history and then we gave you an 01:24:23.159 --> 01:24:27.119 introduction to using the git commands 01:24:25.050 --> 01:24:29.219 and if you want to become really 01:24:27.119 --> 01:24:31.289 proficient at this tool in the resources 01:24:29.219 --> 01:24:33.539 section in the lecture notes for today 01:24:31.289 --> 01:24:35.639 we have a link to a book called pro git 01:24:33.539 --> 01:24:37.710 so this is a free book it's nicely 01:24:35.639 --> 01:24:38.880 written it's pretty short and I think 01:24:37.710 --> 01:24:41.130 going through the first couple chapters 01:24:38.880 --> 01:24:42.329 of that book should teach you basically 01:24:41.130 --> 01:24:44.400 everything you need to know in order to 01:24:42.329 --> 01:24:45.900 use get proficiently for real software 01:24:44.400 --> 01:24:47.639 projects and for contributing 01:24:45.900 --> 01:24:50.940 it's a project on github and things like 01:24:47.639 --> 01:24:51.900 that and then finally just like all the 01:24:50.940 --> 01:24:53.909 other lectures we have a number of 01:24:51.900 --> 01:24:55.889 exercises you can go to go through if 01:24:53.909 --> 01:24:57.659 you want some interesting and 01:24:55.889 --> 01:25:00.110 challenging problems that you can figure 01:24:57.659 --> 01:25:00.110 out how to do