Git Tutorial for Beginners: Command-Line Fundamentals
Corey Schafer
0:00 hey how's it going everybody in this video we're going to go over
0:04 get command line Basics we're going to talk a little bit about what git
0:08 is and then we're going to walk through how to get get installed
0:13 and then the basic commands for working
0:15 with local and remote repositories I'm going
0:18 to use a couple of images in this uh walk through and these images
0:21 were taken from the prit book written by uh these two authors here
0:26 and it is licens under the Creative Commons uh if you want to read
0:30 the book which is uh great resource you can go to the git website
0:35 click on the documentation and the book is listed there so this video is
0:40 going to be useful for three different types of people uh first of all
0:44 somebody who has never used Version Control before this is a great place
0:47 to start because git is the most widely used Version Control System out there
0:53 um second for people who have used Version Control but not get so
0:57 if you're coming from a version control system like SVN uh then it's going
1:03 to be great to learn about git also and third this will be useful
1:07 for people who have used git but have mainly used the guey visual tools
1:13 so the guey tools are really useful but it's better to learn these command
1:18 line tools from the very beginning because uh the goys can only do
1:22 so much and you'll eventually run into a situation where you get stuck
1:26 and the underlying knowledge of the command
1:29 line would be extremely useful so with all
1:31 that said let's go ahead and get started so first of all git
1:35 is a distributed version control system so
1:38 if you're coming from a version control
1:40 system like SVN which is a central Version Control System then what is
1:44 the difference between central and distributed Version
1:47 Control well a central version control system is
1:50 located in one place so people can check out from this central location
1:54 and make their changes and then check everything back in but this can be
1:58 problematic if you can't get access
2:00 to that Central server or that Central repository
2:03 um so for example if that server's
2:05 offline or you're working somewhere that doesn't
2:07 have a network connection then you'll only be able to see the files
2:10 that you've checked out from that repository
2:12 and no additional information about that Central
2:16 remote repository also if something happens
2:18 to that Central repository or it somehow gets
2:21 corrupted then you've got to hope that there's a backup of that code somewhere
2:25 now on the other hand a distributed
2:27 Version Control System like git in this situation
2:30 everybody has a local repository so you can have the option to have
2:35 that censal remote repository uh which we'll look at here in a little bit
2:40 um but your local repository has all
2:42 of the information that your that your remote
2:44 repository has based on the last time that you sync those two together
2:48 so the good thing about this is that if you don't have access
2:51 to that remote repository then you can still view every single change that's
2:55 been made to that repository since it was created so in a way it's
3:00 almost like every developer has an entire backup of the repository so
3:04 in the worst case scenario of something
3:07 happening to the remote repository every developer has
3:10 a copy of that same repository on their machine so that's why it's
3:15 called a distributed version control system so
3:17 now let's go ahead and get started
3:19 with Git now I'm not going to go into too much detail about
3:21 the installation here um if you go to the website which is g-s cm.com uh
3:29 and then you go to the downloads tab here then you can find
3:32 the download the download for any operating
3:35 system that you're working with and the installation
3:38 is pretty self-explanatory so after we get get installed there is a firsttime
3:43 setup that we have to go through so first of all after you get
3:47 get installed then you can check the version to make sure that it
3:52 installed correctly so if you run this command here get— version so I'm going
3:57 to open up my terminal window here now if I run get— version
4:04 and it pops up with some version here here it says get version 2.3.2
4:10 then that means that git is successfully
4:12 installed now once you have git successfully installed now we need to set up
4:16 some Global configuration variables now these variables
4:20 are important because if you're working
4:21 with other developers then they need to know
4:24 uh who is checking the code in and out and making changes and things
4:29 like that so this is a way to add your name to all
4:33 of your check-ins and code changes so this is the syntax here to add
4:37 these um variables in here so if I go back to my terminal
4:41 I can type get config D- Global user.name and then in quotes I can
4:51 type in my name here so I'll type in Corey Schaefer hit enter
4:55 and now we can do the same thing for email so I'll type in user.
5:00 mail and then here I'll type in my email address at gmail.com hit
5:07 enter and now after we've put in those values then to check th
5:12 those values we can do get config d-list and this will list all
5:16 of our configuration values here now I'm going to have a little bit
5:20 more than you do you'll probably only have a few values here
5:22 but I've customize my g a little bit over time so you can see
5:26 all the values that I have listed here but the important ones look
5:29 for are to make sure that we have our user.name set and our user.
5:33 email set so once you have those values working then you
5:37 are good to move on now get config was the first get
5:42 verb that we actually used it was the first action that we
5:44 used now if you ever need help with any of these actions
5:48 then you can use this syntax either get help in the verb
5:52 or get verb d-el and what I mean by that is
5:55 using config as an example so say I want to see what
5:59 you can do with the config action so I can do get
6:02 help config and hit enter and it'll take me to the manual
6:06 page and you can read all about it here um
6:08 or the other syntax that you can do is get config d-el
6:13 and read through there and you can do this with any get action
6:16 so you get add- dhel does the same thing it takes you
6:20 to the manual page for the add action so that's extremely useful
6:25 once you start doing uh more intermediate and advanced things with git
6:30 uh it's useful to look at those manuals and see exactly what
6:34 you can do with them now there are two common scenarios
6:38 for people to begin using git so the first scenario is that you
6:43 have an existing project on your local machine that you want
6:47 to start tracking using git and the second scenario is whenever there's
6:52 an existing project remotely that you want to start developing on so
6:56 first let's take a look at that first example where you have
7:00 a local code base that you want to start tracking using git
7:04 so in order to do this it's just as easy as running
7:07 the git and nit command from within the directory in your terminal
7:11 so for example let me pull up my terminal here now
7:14 the code that I want to start tracking if I do
7:17 an LS within this directory the code that I want to start tracking
7:21 is with within this local repo directory so if I CD
7:25 to local repo and then I do an ls- LA in here which
7:29 will will list all of the files in the directory you can
7:32 see that there is a project file here and there's a calc.
7:35 py file here so to begin tracking this code with Git it's just
7:40 as easy as running git and knit and if I hit enter you
7:43 can see that an init initialized an empty git repository and now if
7:48 I do n ls- La then you can see that it placed this dogit
7:53 file here now this dogit it's actually a directory this dogit directory contains
7:58 everything that's relateded to our repository so if we ever want to stop
8:02 tracking our project uh with Git then all we have to do is
8:07 remove this git directory just like we would any other directory and if I
8:12 do an lsla it's gone and we're no longer tracking this project
8:16 with Git but we don't want to do that we want to uh track
8:20 this project so let's do this again now you can see it put
8:24 that uh get directory back there and now we are using get within
8:27 this directory so now we're using git in our directory but we haven't
8:33 actually committed anything yet so before we
8:36 commit anything let's first run this get
8:39 status here so if I pull up my terminal and I run get
8:43 status you can see here that we have two untracked files project and cal.
8:48 py now this project file is just a file that I created
8:52 as an example of a file that we don't want in our repository
8:56 for other people to see so there's a lot of files that contain
9:00 personal preferences specific to our machine
9:02 or our operating system that aren't actually
9:05 part of the code that we want tracked so for example say
9:08 that I had my personal preferences within this project file I wouldn't want
9:13 to uh add those to the repository and whenever other people check
9:17 those out they would be getting my preferences and we don't want that so
9:21 what we want to do is ignore these files and to ignore
9:24 files uh you just have to create a do get ignore file so
9:29 I'm going to do a touch on a do get ignore file which
9:32 will recreate which will create that get ignore file and now let me
9:35 go ahead and open this up in my text editor okay so
9:41 the get ignore file is just a simple text file where we can add
9:47 files that we want get to ignore and we can also use wild
9:51 cards so for example here in um this slide I have this star.
9:58 pyc uh which will ignore all files with a pyc extension so that's
10:03 a python example but that's not important it's I'm just showing the concept
10:07 here so let's go ahead and add all these files here to our get
10:11 ignore file and I'll paste that in and save that and now let
10:16 me go back to my terminal now that we've added those to the get
10:19 ignore file and saved it now let's rerun get status and now
10:24 you can see here that the project file is no longer coming up
10:28 in our list of untracked files it's only theg ignore file and the cal.
10:33 py file and we want to commit the get
10:35 ignore file because we want the repository uh to know
10:39 to always ignore those files okay now let's take
10:42 a step back here and try to picture exactly where we
10:45 are right now now with Git there are three states
10:49 that we need to know about there's the working directory
10:53 the staging area and the committed files and right now
10:56 we're currently in our working directory so untracked and modified
11:01 files will be in our working directory and it
11:03 will list those when we ran get status so you
11:07 can see here if I open up my terminal then
11:09 these are the files in our working directory here now
11:12 the staging area is where we organize what we
11:15 want to be committed to our repository now the reason
11:18 for the staging area is so that we can pick
11:21 and choose what we want committed so if we've done
11:23 a lot of work spanning multiple files and we
11:26 want to make multip multiple commits from those changes then
11:29 you can stage individual files and commit those in small
11:32 chunks at once so that's going to allow us
11:35 to be more detailed with our commits so for example
11:38 you don't want to make a commit that where you
11:40 add a message that just say says like I made
11:43 a lot of changes to the code you want commits
11:45 that are very detailed as to what changes were
11:48 made so now that we know about that staging area
11:51 uh let's go ahead and add files to the staging
11:53 area so if we want to add all the files
11:56 that are currently untracked or that we've made changes
11:59 to to uh to the staging area then we could run
12:02 get add- capital a um or we could add these individually
12:07 so for example here if I did a get add.
12:12 get ignore then if I do a get status and that's
12:17 going to show us okay so here we have cal.
12:20 py which is currently untracked and then you can see that our get
12:24 ignore file is in our staging area because we ran get add.
12:28 get ignore and like I said in the slide if we want to add everything
12:32 to the staging area then we can just do get add- capital A and hit enter and now
12:38 if I run get status then you can see that all of our files are now
12:42 in the staging area so if we were to run get commit right now then it
12:46 would commit these changes to our repository
12:49 now if you ever want to remove files from the staging area then you can use
12:53 the get reset command so if I did get reset
12:58 calc py and then did a get status you can see that the G ignore file
13:04 is still in our changes to be committed
13:07 which is in the staging area and our calc.
13:10 py file is in the untracked files if you want to remove everything
13:14 from the staging area then you can run get reset without any other options
13:18 and it will remove everything so if I type get status now then
13:22 you can see that all these files are moved back to our working directory
13:25 as untracked files okay but we actually want to make a commit now so
13:30 let's go through this process again what we want to do is we want
13:33 to run get add- a to add everything to the staging area and now
13:40 if I run a get status you can see that all of these changes
13:44 will be committed and in order to get these uh in order to commit
13:48 these files we run get commit and then dasm which will put a message
13:53 now the messages are important you want to be detailed as to the changes
13:57 that you made uh to the code but this is our first uh
14:01 commit here so we're just going to put something like initial commit so
14:05 if I hit enter there you can see that it added the two files
14:08 to the repository now if I run a get status you can see that it
14:13 says that the working directory is clean
14:15 that's because um we've committed those files
14:18 and now we don't have any modified or untracked files those are being tracked
14:21 now and we haven't modify them since
14:24 we committed them now another useful command
14:27 here is the log command so if we run get log then we can
14:31 see the commit that we just made so this gives us the hash number
14:35 of that commit now all those hashes will be unique and then you
14:39 can see that the our author who made the commit and then the message
14:44 for that commit also so now
14:46 for this example we are successfully tracking our local
14:49 project and we have made changes
14:51 and uh committed those changes to the repository
14:55 so now let's talk about the situation that we mentioned earlier uh where we
14:59 want to track an existing remote project with Git now this is likely how
15:06 uh most of you will be using git if you're going to be using
15:09 it in the workplace so for example say that your company has a remote
15:14 repository and you want to clone
15:16 that remote repository and begin developing on it
15:19 now the Syntax for this is get clone then the URL and then
15:24 where you want to clone that repository so in the example that I'm going
15:28 to use I'm going to use this remote repo here which is actually just
15:33 a directory on my local machine now usually this is going to be
15:37 a URL so for example if this was coming from uh GitHub or something
15:42 like that then it may look something more like this so you do get
15:47 clone and then the URL of the remote repository and then where you want
15:53 to clone that repository so in this case the dot is just means
15:57 in the current directory but like I said in this example I'm going to be
16:01 using uh this directory here which is on my local machine but it's
16:06 going to behave exactly like a remote repository would so let me open up
16:10 my terminal and let me go back to this get Basics directory now if
16:15 I run an LS here then I have this directory called clone repo I'm
16:19 going to CD into that now if I do an ls- LA here then
16:25 you can see that this is completely empty these are just relative paths here
16:29 so now I want to clone a remote repository here so I want
16:33 to do a get clone and then the URL of the repository and then
16:38 this dot means that I want to clone all the files from that repository
16:42 into this current directory so if I hit enter you can see that it cloned
16:46 into the current directory now if I do an ls- LA then you can
16:50 see now I have files here now I set up this sample remote repository
16:54 to be very similar to the uh example that we just used in the local
16:59 directory so now that we've cloned that remote repository now let's see how
17:04 we can view information about that remote repository so in order to do
17:08 that we can use a couple of commands one of these commands is get remote-
17:12 V and another is get Branch d a so if I was to do
17:17 get remote- V then you can see it lists the information to the repository
17:23 here so um this is just the location on my local machine of where
17:27 this repository is and also if I was to do get Branch d
17:32 a then it will list all of the branches in our repository not only
17:37 locally but remotely as well now we haven't gone over branches yet but we
17:41 will do that here shortly now let's make a couple of changes
17:45 to the code base and we can take a look at how to uh commit
17:49 those files and how to push them to the remote repository so over here
17:57 I'm going to go into this uh clone repo and open up this cal.
18:01 py file and now I'm just going to make a simple
18:04 change here I'm just going to change this multiply function to return
18:08 what we want it to return so I'll do return x
18:11 x y and I'll save that so now we've made a change
18:14 to our code so now that we've made a change to our code
18:18 how are we going to push these changes to the remote
18:21 repository so first we need to commit these changes locally just like
18:25 we did before so if I open up the terminal here then
18:29 the first thing I can do is get diff and get
18:33 diff is going to show me the changes that I have made
18:37 to the code so you can see here that it has this minus
18:41 sign with the pass that's what I removed and then the plus
18:44 sign here return x* y That's What I added in so
18:48 those are the changes that I made to the code now if
18:50 I run get status we've seen this before then you can see
18:54 that in our working directory we have this modified do uh cal.
18:58 py file and now if you remember we want
19:00 to add those to the staging directory so that they can
19:03 be committed so we'll do a get add- capital
19:06 A to add all the changes now if I run get status
19:09 again then we can see that those are ready
19:12 to be committed and now we can do get commit DM
19:16 and then for a message here we can just do
19:19 uh you know multiply function okay so now we have committed
19:24 these files locally and now we want to push
19:26 these changes to the remote repository so that other people have
19:30 access to those now whenever you're ready to commit those changes
19:34 and push them to the remote repository there are two
19:38 things that you want to do a get pull
19:40 and a get push now people a lot of the times forget
19:43 the get pull but you have to remember that we're
19:47 now working on a project that could potentially have multiple developers
19:52 and people have been uh pushing code to that remote
19:55 repository while we've been working on our own featur so
19:59 what the get pull does is it will pull any
20:02 changes that have been made since the last time that we
20:06 pulled from that repository and as you can see after
20:09 we ran that pool it said that we were already up
20:11 to date because there have been no changes to that remote
20:14 repository since the last time that we pulled from it
20:17 and now we're ready to push and we will do
20:21 a get push and this origin here is just the name
20:24 of our remote repository and then the master is the branch
20:27 that we want to push to so so if we
20:29 run that then we have successfully pushed those changes that we
20:33 just made to the master branch of that remote repository
20:37 so now that we've worked a little bit with local
20:40 and remote repositories now let's go ahead and take a look
20:44 at a common workflow that uh a lot of developers
20:48 use when working with Git so I said before that we
20:51 were going to take a deeper look into branching so
20:55 so far we've been working directly on our Master branch
20:58 but this isn't really how you should be using it
21:01 from dayto day so let's say that for example now instead
21:05 of that multiply function we want to work on our divide
21:08 function so a common workflow that you're going to use
21:11 to do this is to create a branch for your desired
21:14 feature and then begin working off of that Branch so
21:18 the Syntax for creating a branch is get branch and then
21:22 the name of the branch which we'll just call calc
21:24 divide so I'm just going to copy that now let's
21:27 open up our terminal and now let's create that Branch so
21:31 get Branch Cal divide and now if I run get
21:34 Branch without the branch name then it's going to list all
21:37 of my local branches you can see that I have
21:39 Master here which has the asteris beside it that means
21:43 that I that's the branch that I'm currently working on if
21:46 I want to start working on the Cal divide Branch
21:49 then I have to check that Branch out and that's
21:52 using this syntax here get checkout and then the name
21:55 of the branch so I'm going to do get checkout Cal
21:58 divide now if I rerun that get Branch you can see
22:01 that I am working on the calc divide Branch so
22:04 now let's start working on the changes that we want
22:06 to make on this Branch so the changes I want
22:09 to make here I want to work on this divide function so
22:12 I want to return x/ Y and I'll save those changes
22:17 and now that I've made those changes now let's just
22:20 commit this just like we have been doing so if
22:22 I do a get status you can see that our calc.
22:25 py file has been modified I want to add those changes
22:29 to our staging area using the get add command then
22:32 I want to do a get commit with a message
22:37 of we'll just call this divide Funk well divide function and now
22:43 we we have successfully committed this change to our local calc
22:48 divide Branch now this had no effect on our local Master
22:51 branch and it's had no effect on our remote repository so
22:56 now let's say that we want to uh push this Branch
23:01 to our remote repository so this is the Syntax for doing
23:04 that here this get push dasu origin which is the name
23:08 of our remote repository and then the branch that we want
23:11 to push to now I'm not going to go too far
23:13 into what that dasu does since it's a basic git video
23:17 but basically the U option just tells git that we want
23:20 to associate our local Cal divide Branch with the remote calc
23:24 divide branch and then in the future instead of doing this get
23:28 push dasu uh origin Cal divide stuff like that we
23:32 can just do uh get push and get pull like
23:38 this and it will know that those two branches are associated
23:42 to each other but we're not going to go too far
23:44 into that right now so if I pull up the terminal
23:48 here and I do this command get push dasu origin Cal
23:52 divide hit enter now we have pushed that Cal divide Branch
23:57 to the remote reposit repository so now if you remember uh earlier
24:01 we did this get Branch d a command and if we
24:05 run this again this command was to see all of our branches
24:10 so if we run this then you can see that we
24:13 can see our two local branches here Cal divide which
24:16 has the asterisk which means we're currently working on that Branch
24:19 then we can see that in our remote repository we have
24:23 uh a cal divide branch and the master Branch now there's
24:26 a lot of reasons for why you would want to push
24:28 your branch up to the remote repository and a lot
24:31 of companies that's where they run their unit test and things
24:35 like that to make sure that all the code runs
24:37 well before it's merged with Master but let's say that all
24:41 of those unit tests and everything ran really well and now
24:44 we're ready to merge that Branch with Master now the way
24:47 we want to do this is we want to check out
24:50 our local Master Branch so we'll do get checkout Master you can
24:55 see here that we switched to our Master branch now
24:58 we want to pull all the changes down uh remember before
25:02 we commit anything to master we always want to pull down
25:05 the changes in case any changes were made while we were
25:08 working on our feature you can see here that it says
25:10 that we're already up to date because nobody else has made
25:13 changes to that remote Branch since we've been working on the Cal
25:16 divide branch and now we can do this uh option
25:21 on get Branch here which is D- merged and what
25:24 that's going to tell us is the branches that we've merged
25:27 in so far bar and you can see here that if
25:30 I run that Cal divide doesn't pop up here because it hasn't
25:34 been merged yet so in order to merge that Branch
25:37 with Master you do a get merge and then the name
25:41 of the branch so I want to merge Cal divide with master
25:45 so I'm in the master branch and I do a get
25:48 merge Cal divide and it will merge those changes into Master
25:52 now that I've have merged those changes into the master Branch
25:55 then I can push these changes to our our remote Master
25:59 Branch by doing a get push origin Master just like we
26:03 did before and then now those changes have been pushed
26:06 to the master uh Master branch on the remote repository so now
26:11 that we have finished uh merging those changes from Cal divide
26:16 uh now that feature is done and we're ready to delete
26:19 that Branch so that same command that I ran earlier
26:23 just to double check that everything was successfully merged if we
26:28 rerun get Branch D- merged here now you can see
26:32 that Cal divide shows up here so that means that we have
26:36 already merged in all the changes when in that Branch
26:39 into master so now we're ready to delete that Branch since it's
26:42 no longer necessary so we can do get branch and then-
26:46 D which will delete it and then Cal divide which is
26:50 the name of our Branch so now that has been deleted
26:54 locally but remember that we also push that Branch to the remote
26:58 repository so that command that we did earlier get Branch
27:02 d a if we run that again then you can see
27:06 that we deleted our local branch and all we have is
27:08 Master but we still have this Cal divide branch on our remote
27:12 repository so to delete a branch from the remote repository
27:17 then it's this syntax here we can do a get push
27:23 origin which is the name of our remote repository D- delete
27:27 then the Branch so if we run that and then we
27:30 rerun get Branch d a you can see that all we
27:33 have is our local Master branch and our remote Master Branch
27:38 okay and I know that that was a lot to take
27:40 in especially if you're new to something like git but um
27:45 it's really not that bad once you get the hang
27:47 of it and this becomes part of your daily routine now uh
27:52 really quick I'm going to run through a faster example here
27:55 because I know that that seemed like a very long process
27:58 but uh if I'm not talking through step by step then
28:03 you'll see how fast it is to actually make these changes
28:07 with this workflow so for example run the master Branch here
28:11 and say I wanted to work on the subtract function so
28:13 I can do get Branch subtract and then get checkout subtract
28:21 so now I'm working on the subtract Branch I can come
28:24 in here make the changes we want to return x-
28:27 y y save that do a get status over here we've
28:32 modified that we need want to add that to our staging
28:36 directory now we want to commit those changes and you want
28:41 the commit uh messages to be more detailed than that but this is
28:45 just an example and then we can do a get
28:50 push you origin subtract so now we've pushed that Branch
28:56 to our remote Repository and let's say that all those tests ran
29:01 well so now we're ready to merge this with Master we
29:04 can check out our Master branch and now we can do
29:08 a get pull because we want to pull in all
29:11 the changes that have been made so now we pulled in all
29:13 the changes now we can do a get merge of the subtract
29:18 Branch this will merge Subtract with master and now we
29:25 can push those changes and then you can go through
29:28 the process of deleting that Branch just like we looked at earlier
29:31 but you can see how that process isn't actually as slow
29:35 as it was with me uh going through and step
29:38 by- step explaining it um along the way so that was
29:42 a broad overview of using the get command line on local
29:45 and remote repositories I know that was a lot to take
29:48 in for one video but I really hope it was useful
29:51 for you guys if you do have any questions just ask
29:54 in the comment section below now there's a lot that we didn't
29:56 get to in this video and I'm going to make additional
29:59 videos soon on other topics like if you run into merge
30:04 conflicts if you need to undo your mistakes um some other
30:07 common pitfalls uh tagging versions in git and also Advanced topics
30:13 like um your git history rebasing cherry-picking and things like
30:18 that so be sure to subscribe to the channel to make sure
30:22 that you catch those later videos and again I hope
30:25 this video was useful for you all and thank you for watching