navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

Git Essential Training
John Hersey

Git Essential Training

with Kevin Skoglund

 


The course shows how to use Git, the popular open-source version control software, to manage changes to source code and text files. Using a step-by-step approach, author Kevin Skoglund presents the commands that enable efficient code management and reveals the fundamental concepts behind version control systems and the Git architecture. Discover how to track changes to files in a repository, review previous edits, and compare versions of a file; create branches to test new ideas without altering the main project; and merge those changes into the project if they work out. The course begins by demonstrating version control in a single-user, standalone context, before exploring how remote repositories allow users to collaborate on projects effectively.
Topics include:
  • Exploring the history of version control
  • Installing Git on Mac, Windows, and Linux
  • Initializing a repository
  • Writing useful commit messages
  • Understanding the Git three-tree architecture
  • Tracking when files are added, edited, deleted, or moved
  • Viewing change sets and comparing versions
  • Undoing changes and rolling back to previous versions
  • Ignoring changes to select files
  • Creating and working with code branches
  • Merging branches and resolving merge conflicts
  • Stashing changes for later
  • Working with hosted repositories and remote branches
  • Developing an effective collaboration workflow

show more

author
Kevin Skoglund
subject
Developer
software
Git , GitHub
level
Beginner
duration
6h 26m
released
Aug 24, 2012

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Introduction
00:04Welcome, to Git Essential Training. My name is Kevin Scotland.
00:08In this course we're going to learned how to use Git to manage files and source code.
00:12We'll look at the fundamental concepts behind all version control systems and
00:15then gain an understanding of the architecture that Git uses.
00:18We will use Git to track changes to files and source code, whether those changes
00:23are adding, editing, deleting, or moving files.
00:26And we'll discuss how to write clear messages that describe the changes that you
00:29made and learn to compare different versions of a file to see a line by line
00:33comparison of what changed.
00:35We'll learn how to undo changes that you've made even if you already recorded
00:39those changes in Git.
00:41We'll create branches of our code to try new ideas without altering the main
00:45project, and then we'll merge those changes into the project when those
00:49features are finished.
00:50And last we'll see how to use our remote repository to enable collaboration
00:54with other Git users.
00:56It doesn't matter if you're a complete beginner or if you have some prior
00:59experience, we're going to cover all the fundamentals that you need to use Git
01:02for source code management. So let's get started learning about Git.
Collapse this transcript
How to use the exercise files
00:00If you're a Premium Member of the lynda.com training library or if you're
00:04watching this tutorial on a disk, you will have access to the exercise files
00:07that are used throughout this title.
00:09The exercise files for this title are arranged by chapter and by movie, and you
00:13can find the exercise files that correspond to the movie that you're watching by
00:17first looking for the chapter number and the then movie number.
00:20You want to copy the folder of exercise files into your user directory or to
00:23another convenient location, it's always a good idea to make a copy so that you
00:27still have the original to refer back to if you make changes.
00:30On my Mac, I do that by opening up a new window using Command+N, which by default
00:34opens to my user directory.
00:36Then I'm going to open up my Documents directory, and that's where I'm going to put my files.
00:40Then I can Option+Drag over the folder from the exercise files to create a new copy.
00:45Now your files will be in the exact same state as mine at the start of that
00:49movie, and you'll be able to follow right along with me, you can also just use
00:51the exercise files as a reference to check your work as you go along.
00:54The software you will need for this tutorial is Git and a basic text editor.
00:58In chapter 1, we will learn how to install and configure the software and later
01:02when we get to the chapter on remote repositories, you'll also need a remote
01:05hosting account, don't worry if you don't have one already, I'll walk you
01:08through those steps to get you signed up for a free account.
01:11If you're a monthly, or annual subscriber, to lynda.com, you'll not have the
01:15exercise files that have come to this tutorial, but you can still follow along with me.
01:19While you won't have the exact same files as I do, you can easily substitute in your own.
01:23The exact content of the files won't be as important as tracking changes that we make to them.
01:27If you want to use a real project of your own, I recommend that you use a copy
01:31so that you don't accidentally lose valuable work while you're learning.
01:34Remember, you can pause the video, or rewind, if you need more time to copy something down.
Collapse this transcript
1. What is Git?
Understanding version control
00:00Let's begin our exploration of Git by gaining an understanding of what it is, and what it can do for you.
00:05Git is software that keeps track of changes that you make to files and directories, and
00:09it is especially good in keeping track of text changes that you make.
00:13So let's imagine that you have a document, you have version 1 of that document, you make
00:16some changes to it, now you have version 2, you make some more changes, and now you have version 3.
00:21Well, Git keeps track of those three different versions for you, and it allows you to move
00:26back and forth between different versions, to compare the different versions and to see
00:30what changed between each one.
00:32Because what it does is manage versions for you, Git is referred to as a Version Control
00:37System or VCS for short.
00:39Now certainly not the first Version Control System ever created, we're going to look at
00:42a history of some of the most popular Version Control Systems in the next movie.
00:46But virtually all Version Control Systems that have ever been created had one single
00:50primary purpose in mind when they were created, and that was for managing source code.
00:55Computer code that programmers and developers were writing to create programs.
00:59They want to be able to track the changes they made over time as they added features,
01:03fixed bugs, and that sort of thing.
01:05So as a result, because that its primary purpose, I would say 90% to 95% of the time VCSs are
01:11used for source code management. So we call them Source Code Management Tools or SCM for short.
01:17So you'll see both of these abbreviations they can be used almost interchangeably.
01:21Source Code Management is just a little more specific, because it really says we're using
01:25a VCS for the purpose of managing our source code, but you'll want to become familiar with
01:30both of these terms and recognize them as being almost synonymous.
01:34Now whether you've ever worked with a Source Code Management tool before, or not, you've
01:37definitely dealt with Version Control. Let's look at some examples of Version Control that
01:41are non-source code related.
01:43For example, you may have had different versions of files and given them different names so
01:47that you could keep track of the versions.
01:49So you have a budget that you are working on, you have version 1, version 2, version
01:533, you put a little text to the end of it to let you know which version this is so that
01:57we can look back at old versions and see how it has changed over time.
02:01You may do it as you create graphics so you have version 1 of a logo, version 2 of a logo, and so on.
02:05I think we've probably all done this at some point, a lot of applications also offer some
02:10form of Version Control as one of their features.
02:12For example, Microsoft Word allows you to track the changes that you make to a document.
02:15So you turn on Track Changes, and then you send the document to someone else, when they
02:20make changes to that document they'll keep track of what changes they made, and when
02:23they send it back to you, you'll be able to review those changes.
02:27Adobe Photoshop has something called the History, you can bring up the History palette, and
02:31you can look back at each of the changes you've made to an image, and you can even move backwards
02:35through those changes, you can undo those changes and move back up in the History or
02:40back forward in the History as well. You can move forwards and backwards and see how the
02:43document changed over time.
02:45Now if you've ever worked with a wiki, like Wikipedia, then you'll know that there is
02:48also some form of version control that's there as well so that when someone contributes a
02:53change to a Wiki page the editors have the ability to undo that change and go back to
02:58a previous version if they need to, we call that process rolling back to a previous version.
03:03And of course we've all done the most simple type of version control of all which is Undo,
03:07Ctrl+Z on Windows, or Command+Z on Mac, it will just undo something that we've typed
03:11or some change that we've made and allow us to go backwards, and you can do undo multiple
03:15times and undo multiple changes, so to keep going backwards and backwards and backwards
03:19through the different changes that we've made to a document.
03:22Now these are all very, very primitive examples of Version Control and they are no match at
03:27all four we're going to see with a Version Control System, but I think they do provide
03:31useful metaphors for you to have in your head as to how we're keeping track of different
03:35versions, how we're tracking the changes that happen to the document and how we're able
03:38to move backwards and forwards to the history to bring up different versions at different
03:42points in the change process.
03:44But I think they do still provide useful mental metaphors for you to have in your head to
03:49think about the way that a VCS works. Because ultimately they are all doing the same thing,
03:53they are keeping track of different versions, they are allowing us to go forwards and backwards
03:57in time to see different changes that have been made, and to even compare those changes
04:01between different versions, and that's what we'll be doing with Git.
04:04In the next movie let's take a look at the History of some of the most important Version Control Systems.
Collapse this transcript
The history of Git
00:00There are five important version control systems that predate Git that I want us to look at.
00:04There have been many others over the years, but these are some of the most
00:08popular and the most influential.
00:09The first of these is SCCS, it wasn't the first, but it was the first to become popular.
00:14It was released in 1972 and was developed by AT&T and bundled free with Unix.
00:19Now Unix was also free, and as a consequence it spread quickly to places like
00:22universities, so therefore universities also taught their students how to do
00:26version control using SCCS.
00:29So if you were writing Unix programs that's what you learned to use.
00:32And then when these students left the universities to go work in jobs, the
00:36Version Control System that they were familiar with, and they took with them, was
00:39SCCS, so you can see why it became very popular.
00:42We talked about very primitive version control earlier, that you might have
00:45something like a budget, and you might save version 1 of the budget and version
00:492 and version 3 just giving a different file name each time.
00:52When you do that you are actually saving the full document three different times.
00:56That's not the most efficient way to do it.
00:58What SCCS does is it keeps the original document, but then instead of saving the
01:01whole document a second time, it just saves a snapshot of what the changes were.
01:06So if you want version 5 of the document, you just take version 1 and apply four
01:11sets of changes to it, to get to version 5, that's a much more efficient way to
01:15store the changes over time.
01:17So SCCS stayed dominant until the early '80s when RCS was developed, Revision
01:22Control System, and it just made lots of improvements over SCCS.
01:25For one thing it was cross-platform, whereas SCCS was Unix only. With the rise
01:31of the Personal Computer it was important to have a Version Control System
01:34that could work on PCs.
01:35It was also more intuitive, had a cleaner syntax with fewer commands, but more features.
01:40And most importantly it was faster and a lot of its speed increase came from
01:44the fact that it used a smarter storage format whereas SCCS stored the original
01:49file and then kept track of all the changes that went after it, RCS flipped
01:53that around so that it kept the most recent file in its whole form, and if you
01:58wanted previous versions, then you applied the change snapshots to go backwards in time.
02:03If you think about it, that's a lot faster because most of the time what we want
02:07to work with is the current document.
02:09With SCCS if we wanted the current document, and there were 20 sets of changes,
02:13we had to pull up the original and then apply 20 sets of changes to get there,
02:17with RCS we can just bring up the original file, and it is already stored in its full state.
02:22Now one of the problems with both SCCS and RCS was they only allowed you to work
02:26with an individual file one at a time.
02:28So you could track changes in a single file, but not in sets of files, or in a whole project.
02:33CVS allowed you to do that, that's for Concurrent Versions System.
02:37Now the real innovation now to CVS is not just the fact that you can work with
02:41multiple files, it's the concurrent part, the fact that we can have a place
02:45where we store our code, called a Code Repository, you can put that on a remote
02:49server, and more than one user can work on the same file at the same time, they
02:54can work concurrently.
02:55With previous versions only one person could work with a file at a single time.
03:00So CVS adds a lot of features for users to be able to share their work and be
03:04able to update their file with changes that other people have made and placed in
03:08the remote repository.
03:10This idea of working with remote repositories was further improved upon with
03:14Apache Subversion or SVN for short.
03:16SVN was faster than CVS, and it allowed saving of non-text files, like images,
03:21whereas CVS couldn't do that.
03:23Most importantly, the big innovation for SVN was that it was tracking not just
03:27changes to files, or to groups of files, but actually watching what happened in a
03:32directory as a whole, watching the files in the directory and actually taking a
03:37snapshot of the directory not just the files.
03:40Now it may seem like a small difference, but it's important.
03:43In CVS you would talk about having revision 7 of some file.
03:47In SVN, you talk about some file as it appears in revision 7.
03:52SVN could track the history of directories.
03:55For examples, CVS had a hard time if you renamed a file.
03:58SVM though would track that change with no problem.
04:01If you add a file directory, remove a file, rename it, it's watching the
04:04directory as a whole to see what happens and taking a snapshot of that, whereas
04:09CVS was just looking at a collection of individually named files.
04:13CVS would also update files one at a time as it went to either apply or read back changes.
04:19SVN would instead do a transactional commit and apply all of the changes that
04:25happen to the directory or none of them at all.
04:27The snapshot was bigger than just the individual files, it was the entire
04:31directory, the entire set of changes that were happening to that directory at one time.
04:35It's a subtle but important difference.
04:37Now SVN stayed the most popular Version Control System for a very long time
04:42until Git came out, but there is one other Version Control System that I want us
04:46to look at before that, and that is BitKeeper SCM.
04:50It was a closed source proprietary source code management tool.
04:55That means that a company owned it and sold it, the same way that Adobe sells
04:58Photoshop or Microsoft sells Word.
05:00One of the important features the BitKeeper had, and it wasn't the first to have
05:04it, but is Distributed Version Control.
05:06But before we get to that, let's talk a little bit more about this idea of being
05:10closed source, whereas all the other ones that we have been looking at for a
05:14while had been open source.
05:15The community version of BitKeeper was free, it had a few less features and
05:19some usage restrictions, but there was a version that they gave away for free,
05:23and that version was used for source code management of the Linux kernel from 2002 to 2005.
05:28Now it was controversial to use a proprietary SCM for the Linux kernel because
05:34the Linux kernel is an open source project, no one owns it, whereas the SCM is
05:39owned and controlled by a company.
05:41So a lot of people objected saying, well what if they change the rules in
05:45the future, suddenly we're going to be screwed because we are stuck using
05:48this company's software?
05:49Well, guess what, in April 2005, the community version stopped being free and
05:54all those predictions came true.
05:56Now BitKeeper was never as popular CVS or SVN, but it is super important with
06:00the creation of Git because of its connection to Linux, because in April 2005,
06:04when the community version stopped being free, that's the same point at which
06:08Git was born, Git was created by Linus Torvalds, and you may recognize that
06:12name as the person who created Linux and still drives the development of the Linux kernel.
06:17When BitKeeper stop being free they needed an alternative for managing their source code.
06:21Linus looked around, and it didn't like the other VCSs that were out there, like
06:25CVS and SVM, he did like some of the concepts of BitKeeper, but he thought he
06:29could do even better, so he wrote a new VCS from scratch.
06:32Now Git is Distributed Version Control, like BitKeeper, and we'll talk more about
06:37Distributed Version Control in the next movie.
06:39It's also open source and free, which is great for us, because it means that
06:42people like you and me can download it for free and use it for free with no
06:46license fees or anything like that.
06:48It also means that because it's open source the community can see the source
06:51code and contribute to it as well.
06:53So they can submit bug fixes, add new features, all of those things we get to be
06:58the beneficiaries of because it's an open source project.
07:01It's also compatible with most platforms, Unix-like systems and Windows, and
07:06it's faster than most other Source Code Management tools.
07:09100 times faster in some cases for some operations, and has better
07:13safeguards built into it to guard against data corruption, and we will talk
07:17about that a bit later. Now these improvements worked.
07:20Git became a hit, as people discovered the power of Distributed Version Control
07:23as they got used to all of Git's nice features, Git has experienced an
07:27explosion in popularity.
07:28Now there is no official statistics on this but to give you an example, GitHub
07:32launched in 2008 to host Git source code repositories.
07:36In 2009, there were over 50,000 repositories with a 100,000 users.
07:41In 2011 just two years later, there were 2 million repositories with over a million users.
07:47So you can see this rapid growth in just two years.
07:50So Git has definitely taken off.
07:52In the next movie, let's talk about Distributed Version Control and see why
07:56that's such an important feature.
Collapse this transcript
About distributed version control
00:00In this movie I want to explain what Distributed Version Control means so we can
00:04understand why this is such an important feature of Git.
00:07In the previous movie where we looked at the history of version control systems,
00:10we talked about SCSS, RCS, CVS, and SVN, four of the most popular version control
00:16systems of the past.
00:17And all four of these use a central code repository model, that is that there is
00:22one central place where you store the master copy of your code, and when you're
00:26working with the code you check out a copy from the master repository.
00:29You work with it make your changes, and then you submit those changes back to
00:33the central repository.
00:35Other users can also work from that repository submitting their changes.
00:39And it's up to us as users to keep up-to-date with whatever is happening in that
00:43central code repository, to make sure that we pull down and update any changes
00:47that other people have made.
00:49Git doesn't work that way, Git is Distributed Version Control, different users
00:53--or teams of users--each maintain their own repositories instead of working from
00:57a central repository.
00:58And the changes are stored as change sets or patches, and we're focused on
01:03tracking changes not the versions of the document.
01:06Now that's a subtle difference, you may think, well, CVS and SVN those track
01:10changes too, they don't.
01:12They track the changes that it takes to Git from version-to-version of each of
01:16the different files or the different states of a directory.
01:19Git doesn't work that way, Git really focuses on these change sets in
01:23encapsulating a change set as a discrete unit and then those change sets can be
01:28exchanged between repositories.
01:30We're not trying to keep up-to-date with the latest version of something instead
01:35the question is, do we have a change set applied or not?
01:38So there is no single master repository, there is just many working copies each
01:43with their own combination of change sets. Let me give an illustration to make this clear.
01:47Imagine that we have changes to a single document as sets A, B, C, D, E, and F,
01:52we're just going to give them arbitrary letter names so that we can help see it.
01:57We could have a first repository that has all six of those change sets in it.
02:01We can have repository 2 that only has four of those changes in it.
02:04It's not that it's behind repository 1 or that it needs to be brought up-to-date,
02:09it's just simply that it doesn't have the same change sets.
02:12We can have repository 3 that has A, B, C, and E, and repository 4 that has A, B, E, and F.
02:18No one of these is right and no one of these is wrong.
02:21None of them is the master repository and the others are somehow out-of-date or
02:25out of sync with it.
02:27They all are just different repositories that happened to have different
02:30change sets in them.
02:31We could just as easily add change set G to repository 3, and then we
02:36could share it with repository 4 without ever having to go to any kind of
02:40central server at all.
02:41Whereas with CVS and SVN, for example, you would need to submit those changes to
02:46the central server and then people would need to pull down those changes to
02:50update their versions of the file.
02:52Now by convention, we often do designate a repository as being a master
02:58repository, but that's not built-in to Git, it's not part of the Git
03:01architecture, that's just convention, that we say, okay, this is the master one
03:05and everyone is going to submit their changes to the master one, we're going to
03:08trying all stay in sync from that one or we don't have to.
03:12We can actually have three or four different master ones that have different
03:15versions, different features in them, and we could all be contributing to those
03:18equally and just swapping changes between them.
03:20Now because it's distributed that has a couple of advantages, it means that
03:24there is no need to communicate with a central server, which makes things faster,
03:27and it means that no network access is required to submit our changes, we can
03:31work on an airplane, for example.
03:33And there is no single failure point, with CVS and SVN if something goes wrong
03:37with that central repository that can be a real showstopper for everyone else
03:40who is working off of that central repository.
03:42With Git we don't have that problem, everyone can keep working, they've each got
03:46their own repository that they are working from, not just a copy that they're
03:50trying to keep in sync with a central repository.
03:52It also encourages participation in forking of projects, and this is really
03:56important in the open source community.
03:58Because developers can work independently, they can then make changes, bug
04:02fixes, feature improvements, and then submit those back to the project for
04:06either inclusion or rejection.
04:08And if you decide you don't like the way that a open source project is going,
04:12you can fork it, take it to a completely different direction and say, you know
04:15what, I'm going to just make a clean break and make my repository now the one
04:19that I'm going to work from, all of my changes will be submitted to there, and I
04:24can still pull change sets from the master one into my project whenever I want.
04:27But I don't have to, I can go my own way.
04:30That becomes a really powerful and flexible feature that's well suited to
04:33collaboration between teams especially loose groups of distributed developers
04:36like you have in the open source world.
04:38Distributed version control is an important part of the Git architecture that
04:41you need to keep in mind.
04:42Especially, if you have previous experience with another Version Control
04:45System like CVS or SVN.
04:46We'll talk a lot more about how Git tracks and merges these change sets as we go forward.
04:52For now just make sure that you understand that there is no central repository
04:55that we were from, all repositories are considered equal by Git, it's just a
04:59matter of whether a repository has change sets in it or doesn't.
Collapse this transcript
Who should use Git?
00:00In this movie, I want to talk briefly about who should use Git.
00:04Now, as I said before, primarily people working with source code are going
00:08to get the most utility out of Git, but it's not just for them, it's really for
00:12anyone who wants to track edits, especially edits for text documents.
00:15It offers you the ability to review a log of changes that were made, to view
00:18differences between versions, and to retrieve old versions.
00:21Those features are not just limited to programmers, those are things that anyone
00:25working with the text file might want to be able to do.
00:27It's also useful for anyone needing to share changes with collaborators.
00:31So one person makes a set of changes to document, someone else makes a set of
00:35changes to the document, and we want to merge those together or share changes
00:39between each other, then Git can help us to do that.
00:42However, Git is most useful for people who are not afraid of command-line tools.
00:45There are graphical user interfaces that we can use with Git, and we'll look at
00:49some of those later on, but it is first and foremost a command-line tool which
00:53is part of why it stays so popular with programmers and developers who aren't
00:57afraid of those command-line tools.
00:59So out of programmers and developers it doesn't really matter what language you're
01:02working in, doesn't matter of simple HTML or if you're working in a compiled
01:06language, you can use Git to track the changes in your source code.
01:11Now the list of programming languages that I've got on the screen there is not
01:14just a list that I made up.
01:16These are some of the most popular languages that are used with Git.
01:20That Git is use to track projects on.
01:22There're many others as well, but if you work in any of these, you definitely
01:26will get a lot of utility out of Git.
01:28Now it's not as useful for tracking non-text files, images, movies, music,
01:33fonts, it will keep track of each of them, it'll keep track of the fact that you
01:37made a change to an image, it'll keep both the old image and the new image in
01:41the repository, but you won't be able to see the difference between the two, the
01:45same way that you can with text.
01:47With text, they can say, oh, this bit of text on line 27 which changed from this to this.
01:52It can't really do that with these other files that are called binary files.
01:56It also doesn't work well with files that have to be interpreted by an
01:59application, word processing file, spreadsheets, PDF's, Photoshop PSD's, these
02:04kinds of files need an application to interpret them otherwise they're just a
02:08bunch of letters and numbers that Git won't understand.
02:11So Git will again keep track of the fact that you've a Microsoft Word file in
02:15version 1 and in version 2, but it won't be able to show you the difference, the
02:19text that you changed between those two files.
02:22It has to be a pure text file, not interpreted by Word Processor.
02:26So if you think Git can be helpful and helping you to track changes and
02:29manage different versions, let's move forward in the next chapter by getting it installed.
Collapse this transcript
2. Installing Git
Installing Git on a Mac
00:00In this movie we're going to learn how to install Git on Mac OS X.
00:04Now this is not just for any particular version of Mac OS X, this is for all
00:08versions of Mac OS X. The same process should work.
00:11So the first thing we need to know is where to find Git, and that's on the main Git web site.
00:16The URL for that's http://git-scm.com--the scm, remember stands for source code management.
00:25Now we're going to go to that URL in just a moment, but there's one other URL I
00:30want to give you, which is the direct URL to the Mac download.
00:33So it's the same URL we just had follow by /download/mac, and that'll take
00:38you directly there. Let's go over to Firefox and take a look.
00:42So here I'm on the main Git web site you see git-scm.com up here, and it
00:48detected the fact that I'm coming from a Mac and offers to take me directly
00:51to the Mac download. I'm going to ignore that for now.
00:54It would be a shortcut for me, instead I'm just going to show you that here's a
00:59link for all the downloads, and then that takes you to a page here where I can
01:03pick the operating system that I want.
01:05And of course, I want Mac OS X so that takes me directly where shortcut would've gone.
01:09As soon as I go there, it starts downloading the file, see it says, your
01:11download is starting up here, and it starts downloading it and my browser is asking
01:16me, what would you like to do with this file? Do you want me it to download and save it?
01:19Before I do say yes, I just want to show you that I have already configured
01:22Firefox to download my files onto my Desktop.
01:27You may have yours configured to download somewhere else, like a downloads folder.
01:31That's fine, just make sure that you can locate it once we've downloaded it.
01:34So now I'm going to say Save File, and there it is it's going to finish the
01:38download in this progress window here and then here's the file sitting on my Desktop.
01:42So now we're done with Firefox, we can hide that and what we want to do is just
01:47open up this disc image, and this is pretty much like any Macintosh install
01:50that you've done before.
01:51We're going to open this package, and then it'll guide us through the steps to install it.
01:57Do you want to install for all user users of this computer? And yes we do.
02:01Now it's going to say install one more time, it's going to want our main
02:05installation Password for installing software, so we'll type that in, and now
02:09it's going to install it for us. Installation installed, voila.
02:13Now there's one more thing that we want to do, which is that there's also this
02:18uninstall.sh script here, it's a shell script that will uninstall Git for you.
02:22So if you need to uninstall Git, this is the script that'll help you do it and the
02:26README file should give you more information about how to do that.
02:29So now what we want to do is we want to open up the terminal application that's
02:31the Command Line tool on the Mac.
02:33And the way that we'll find out is we will go into the Applications folder and
02:38in Utilities, down here at the bottom, if we open that up, one of the very last ones
02:41will see in alphabetical order is Terminal. Now we're going to using this a lot.
02:45So I am actually going to just drag it down here to my doc so that I have it.
02:48And then I'll go ahead and launch it as well. Let's just close this window behind it.
02:53Now yours probably looks different than mine.
02:56That's because I've adjusted the preferences in Terminal and in Preferences
03:00under Settings here you can change the look of yours.
03:03So I've changed the look to have a dark black background with yellow text, I
03:07think that's going to be easier for you to see. Yours is probably white, by default.
03:11That's fine there's nothing wrong with leaving it that way or you can go in and
03:15change the colors around until you get something that you like.
03:18Now to find out if we've Git installed, there's two ways we can do it, we can say
03:23which git, and that will tell us if Git exists, it'll tell us the path to get
03:27there so did find it and then if we say git --version, it comes up and tells us
03:32which version of git we have installed.
03:34So we know that it can find it, and we can see what version it is.
03:38So that's it, we now have Git installed, and we're ready to move on to the video
03:42where we talk about configuring it.
Collapse this transcript
Installing Git on Windows
00:00In this movie, we are going to learn how to install Git on Windows.
00:03I'll be installing it on Windows 7, but the process will be similar for any version.
00:07The first thing you need to know is where to find Git.
00:10In the main Git web site, it's going to be at http://git-scm.com.
00:17SCM stands for source code manager.
00:20When you go to that web site, there will be a link that will allow you to
00:24download and then install Git.
00:25Before we do that though, I want to also mention another good resource to you,
00:29which is that GitHub, one of the popular Git hosting companies, provides very
00:33detailed step-by-step instructions with screenshots at this URL.
00:38So if for any reason, things change in the future or if you get stuck, this
00:42might be a good resource to help you get unstuck.
00:44But I am also going to walk you through the install step-by-step.
00:48So this is the Git web site, see git-scm.com up here in the URL, and when you go
00:54to the page, at least at the moment, it has a link right here that detects that
00:58I'm coming from Windows and offers to give me the latest stable release.
01:01So this is the one that we could download, but instead of just clicking that
01:05link, I want to show you that you can also click Downloads here, and you can see
01:09all the different versions that are available for different operating systems,
01:12we can click Windows, and then it will take us to that same page, the other one
01:16was a shortcut to get to this page that would download Git for us.
01:20We could see that it's offering to download Git-1.7.11-preview with a date after it .exe.
01:26The version that it offers you may be different, go ahead and take whatever it
01:30gives you, and don't let the fact that it says preview here, throw you at all.
01:34The Windows version of Git is still considered to be beta software, it's very
01:38stable, you shouldn't have any worries about using it, but it's still officially
01:41considered beta software.
01:43So it wants to know would we like to save this file, and we'll say yes, we
01:47would like to save it.
01:49It's doing a scan for viruses and download, and then now it has
01:52actually downloaded. All right. So let's close that up.
01:56I had my version of Firefox set to put all my downloads, in my Downloads folder
02:02so that's where you can find this, you may have yours set to go somewhere else.
02:06So here it is inside my Downloads folder. I am just going to double-click on that.
02:10It's an exe file, Security Warning, we do want to run it, do we want to go ahead
02:15and let them make changes, yes we do.
02:17And now we have a Setup Wizard to help walk us through the process.
02:20You are basically going to pick the defaults for everything, it's going to put
02:22it in our Program Files x86, under GIT, that's great.
02:27As far as what things to pick here, go ahead and just accept the defaults for everything.
02:31Then it says it will create shortcuts, and it will call it Git, that's fine, and
02:36as far as choosing our PATH environment, again we are going to choose the top
02:39option Use Git Bash only.
02:41Unless you know that you want to use another one, let's stick with the top one.
02:45And then for line endings, now because Git is primarily UNIX-based, and that's
02:50where sort of where it's got to start and a lot of users are still on UNIX.
02:54The style of UNIX line endings in a text file is different from what Windows has.
02:59So it wants to know how do you want to handle that difference.
03:02The one you want to pick is the top one.
03:04Basically, when we get files from Git, convert them to Windows style so that we
03:08can use them in Windows, but then when we put things back for other people to
03:12use we are going to use the UNIX style line endings.
03:15So that's the polite way to do it unless you are working on a Windows only
03:19project, in which case you might want to choose this last one, but I really
03:23recommend that you try and go with this top one in most cases.
03:26Okay, so now it's actually going to do the install for us, and it's all done, we can say Finish.
03:34We are now done with the download.
03:36You can see that it added Git Bash to my Desktop here, has some Release
03:41Notes here that we can read, we won't worry about those right now, and now Git is installed.
03:46So what is this Git Bash business over here?
03:48We were supposed to be installing Git, and we got something called Git Bash.
03:52Well, Bash is an environment in UNIX.
03:54It's the environment that probably most UNIX users use.
03:57So it's essentially like Git UNIX, and when we open this up, what it does is
04:02it puts us into an environment that is very similar to the environment that
04:06UNIX users will have. I am going to make my font a little bigger here.
04:10We'll make my Window 24 point and Consolas, there we go, now it's bigger, that
04:20will make it easier for you to see.
04:22So now that we are here, this works just like UNIX, if you were in the Command
04:26line in windows, you would see a directory listing by typing dir.
04:29But we are using UNIX here so it's ls - la, and it will show us a listing of all
04:34our files, exactly like you have in UNIX.
04:37It's going to make it really easy for you to follow along because you can use
04:41the exact same commands. Now we can see which version of Git we have.
04:44Let's first type which git, that's a UNIX command again that shows where Git is
04:48installed and located, and if we type git --version, it comes up and tells us
04:53which version we have.
04:55This msysgit is letting us know that it's the Windows version.
04:58So we have now successfully installed Git on windows.
05:02There is one additional note that I want to give you about Git Bash, which is at
05:06least in the current version that I'm using of Git Bash, you don't have the
05:10ability to copy and paste text.
05:12So I can't, for example, select any of the text that's up here.
05:15If I want to paste something in, you can't do it directly into the command
05:19line, what you have to do is come up here and choose Edit and then choose Paste from here.
05:23So if you see me doing paste from a text file into the command line, that's how
05:28you're going to do it when you're working inside Git Bash.
05:30Now that may be a feature that they'll fix in the future, but at least at the
05:34moment copy-paste doesn't work the way it probably should.
Collapse this transcript
Installing Git on Linux
00:00In this movie, we are going to learn how to install Git on Linux.
00:03The first thing you need to know is where to find Git.
00:06The main Git web site is going to be at http://git-scm.com, SCM stands for
00:13Source Code Manager, and this web site is going to have everything you need to
00:18know about Git, including links to information about how to download.
00:20For Linux, that link is going to be git-scm.com/download/linux. Let's take a look.
00:27So here I am on the Download Linux page and unlike the Mac and Windows
00:32versions where you actually download an installer or a package to install on
00:36your operating system.
00:38With Linux, they break it up by distribution and tell you what package
00:42manager you ought to use.
00:43So if you are using Debian/Ubuntu, you should use apt-get, if you are using
00:47Fedora, you should use yum, and so on, and it has a list of all the distributions
00:52and the different package managers you can use to install it.
00:54If your package manager asks you to make any choices, they will just want to
00:58pick the default settings for everything.
01:00After the package manager finishes running, you should have Git installed.
01:04You can make sure of that my typing which git, which should return the location
01:08of how to find Git and git --version, which will port the current version of Git.
01:13Don't be concerned if your version is different than mine.
01:16Now that you have Git installed, you can follow right along with me in what I do
01:20on the Mac because Mac OS X has Unix under the hood.
01:24So everything that I do from the command line is actually Unix, so it will work
01:27exactly the same as what you have in Linux.
Collapse this transcript
Configuring Git
00:00In this movie we are going to learn how to do some basic configuration of Git in
00:04order to get us started.
00:05The first thing we need to know is that there's three places that get stores
00:09configuration information and depends on how widely we want those
00:12configurations to apply.
00:13The first and largest is System level configuration, that is configurations that
00:18ought to apply to every user of this computer.
00:21Now each user, of course, can overwrite it with their own, but these are going to
00:25be default configurations. Now in truth you won't use this very often.
00:29It's much easier and much better to set it up on a per user basis, but I just
00:33want you to know that it exists.
00:35On Unix that's going to be inside the etc directory, in a file called gitconfig.
00:38It's also going to be in the same file, inside the same folder on Windows, but
00:43it will be stored in a different place.
00:45Most likely it will be inside your program files, inside the application for Git.
00:49Now the most useful place to store configurations is going to be User level configurations.
00:54These are going to apply to a single user, which most of us, most of the time
00:58are working on a single-user machine and so we can have our single-user configuration.
01:04On Unix, that's going to be in your home directory, inside a file called .gitconfig.
01:09On Windows, it's also going to be in your User directory that's the HOME directory .gitconfig.
01:15If you're not familiar with where your HOME directory is chances are it's
01:18going to be inside your Documents and Settings folder, and you should find
01:22your username there, and inside that username folder, that's where you will see gitconfig.
01:27And then the third place that we can store configurations is on a
01:31project-by-project basis.
01:32So in a single project we can have configurations that apply only to that project.
01:36Now most configurations, you are probably don't want to use from
01:40project-to-project, and you want to put them in the User configuration.
01:43But if there is something specific to a single project you can put it inside of
01:46the project, look for a folder inside there called .git, and then inside there
01:50we have file called config.
01:52Now the names of these configuration files vary depending on the location, and
01:57some of that is just because of some of the different conventions that Unix
02:00uses, and that's what this follows.
02:02But if you know generally where to look for these files, the fact that their all
02:04named slightly different, shouldn't throw you off, they should stick out,
02:07you should be able to find them.
02:10Now we can go in and directly edit these files and put in our configuration
02:14information, but that requires us to know something about the format of those
02:17files, we don't have to do that.
02:19Git gives us some commands that we can use to make editing these configurations easy.
02:24For all three of them, it's going to be git config, followed by a modifier that
02:29tells at what level we want to do the configuration, and then followed by the
02:33configuration itself that we want to do.
02:35So if we want to do a system-wide configuration, then it's --system at the end,
02:39if it's User level then that's --global, don't let that throw you, global
02:44doesn't mean system, it means global to the user, and then if we don't have any
02:49modifier then it's just on a single project basis.
02:52So that's what the command looks like, and that tells it how to direct it, what
02:56are the kinds of configurations that we can set?
02:58Well, let's set a few. So here I am in my command line.
03:02You'll want to make sure that you're there as well, it doesn't matter where we're
03:05located because we are going to be doing configuration that's global.
03:08So as long as we are logged in as a user, we will be making edits to our global user file.
03:13So we can call git config and then --global, and then whatever we want to configure.
03:20Well, the first thing we need to configure is our user.name, so user.name, space,
03:25and then in double quotes put in your name.
03:29So obviously you've used your name and not my name and then when you are done hit
03:33Return and Git added it to the config file.
03:35Let's add another one, git config --global user.email, space, and then you can
03:43put in your email address there.
03:45I am going to put in just a fake one here rather than give out my real email
03:50address, someone@nowhere.com but you will put in your real one.
03:53Now if you want to see these configurations, you can say git config --list, and
04:00it will then pair it back to the list of configurations that it has set for you,
04:04or if you want to look at a specific one, you can say user.name, and it returns
04:09just that one, same thing, user.email, and it returns the email address.
04:13So we can take a look, we have the ability to set them, and we have the ability
04:18to retrieve them and look at what they are. Now let's look at where those are located.
04:22I am inside my user directory already right here.
04:24On Unix, you can do cd space followed by the tilde, and that'll make sure
04:28that you are in your user directory, and let's do ls -la, for Windows users
04:34that's going to be dir, that will show you the directory listing, and you will
04:38right here is a file called .gitconfig.
04:40Now there are number of ways that you can open up this file, the fact that it is a
04:46dot file means that it's going to try to hide it from you, you are not going to
04:48see it when you look at it in the finder, you are only going to see it from the
04:51command line here, that's part of what that dot does.
04:54One good way to take a look at it real quick with Unix is just to use the cat
04:58command, cat .gitconfig, I'll just clear my screen so you can see, and there is the file.
05:04That's what it actually looks like inside there.
05:06So this is the minimum that you need to configure and to start working with git.
05:10You will come back to this file and add other configurations over time.
05:13I want to show you two more useful ones now.
05:16The first is to tell Git what Text Editor you will be using.
05:20This allows Git to open up text that needs editing in that editor by default.
05:25There are times when Git is going to want to have you edit a message and so
05:29it'll pop up that message in a Text Editor, let you change it, and then close it.
05:31And Git will go ahead with what it was going to do.
05:34The way we do that is with git config --global and then core.editor and then
05:42after that in quotes let's put the name of the editor that we want to use.
05:46So if you like using Unix's nano, you can put that there, you can use vim,
05:51or emacs, if you are on Windows, you can use notepad.exe, that comes by
05:56default with Windows.
05:58I'd like to use TextMates, so I am going to be using M A T E, which is a little
06:02program that TextMate provides that sits inside Unix, and it can then launch TextMate.
06:07In addition to just launching it though, we need to provide a couple of options
06:10with it, which is the -w option, which says, hey after you launch it, wait until
06:16TextMate is done before you keep going with what you were going to do Unix, so
06:20we need that W option otherwise Unix will open it and then just keep going
06:24further as I was doing without waiting for you to finish the message, and then l1
06:28also tells it to start at line 1.
06:30So wait and put the cursor at line 1 of the message.
06:32If you have a different text editor you'd like to use, you can try plugging it in
06:37here or you can Google around and find out what configuration other people are
06:40using, so they can use that program.
06:42Okay, so now that I've got that in there, that will add it to my config file,
06:46the second configuration we will add now is to tell Git to use colors when
06:50outputting things to the command line.
06:52If we don't use this, it will just give us monochromatic text, just one single color.
06:57Instead, by setting this option, it will allow Git to try and use colors like red
07:01and green and blue to help illustrate what point it's trying to get across, what
07:05information it's trying to convey.
07:07So we can use git config --global, and then we are going to say color.ui set to true.
07:16So that's it, tell it to color the user interface.
07:18Once we do that, cat .gitconfig, you can see now our config file has a few
07:24more options listed.
07:25We will come back and add more later, but this is enough to get us started.
Collapse this transcript
Exploring Git auto-completion
00:00In this movie I am going to help you to get auto-completion set up for Git.
00:04Now this is a nice bonus feature, it's not something that you have to have, you can safely
00:08skip over this movie if you want to.
00:09However, I think it's something that you're going to want over time, and it makes sense
00:13for us to go ahead and set it up at the start.
00:15Now these instructions are going to be for Mac and Unix only, because Windows should already
00:19have auto-completion included, so you shouldn't have to do anything there.
00:22So if you are on Windows, you can go ahead and skip this movie, if you are on Mac and
00:26Unix, follow along with me.
00:28Now the first thing we are going to do is download it from GitHub.
00:30I am going to walk you through all these steps one at a time and actually show you how to do it.
00:34I wanted to give you the commands here.
00:36The first is we're going to change to our user directory, then we are going to use the
00:39Curl tool which is going to go to the URL at GitHub and download the auto-completion
00:45script into our home directory. Then we will rename it.
00:48Essentially what we are doing is just changing the name to have a dot in front it so that
00:51it becomes a dot file rather than just a regular file, and then the last thing we'll
00:56do is we are going to add it to our login configuration, so it's either the .bash_ profile
01:01or that's the bashrc file.
01:03Now if you are not familiar with these two files, and you don't know the difference between
01:06them, the best thing is to add it to your bash_profile.
01:09If you know the difference, then add it to the one that's best for you, but otherwise
01:13you just want to add it to bash_profile and have it there, and that will be the simplest.
01:18Now what are we going to put in that .bash_profile?
01:20Well, what we want to put is a bit of code, and again, I am going to actually do this with
01:24you, but I wanted you to see it nice and big, we are going to put in if the file .git-completion.
01:30bash exists then load in the file .git-completion.bash.
01:36That's what this code does.
01:37There is a little bit of shell scripting code that does that.
01:40If the file exists, then load it. So let's see how to actually do that.
01:44So here I am in the command line.
01:45As I said, you want to just make sure that you're in your user directory, you should
01:49be by default when you first open the window.
01:51And then we are going to use curl with the -OL-- that's not a zero, that's an O--followed by
01:57and I am just going to paste in the URL here so I don't have to type the whole thing
02:03out while you watch, it's https://github.com/git/git/raw/ master/contrib/completion/git-completion.bash, very long.
02:20Take a moment and pause it if you need to, to make sure that you copy it all down, and
02:23once you do, hit Return, and it should download the file for you.
02:27Now we can actually see that file with ls -la, and here it is right here, git-completion.bash.
02:34Now the next step is we want to turn that into a dot file.
02:37So we are just going to say move that file, and I am just going to put the tilde in front
02:42of it just to make sure we are targeting the right file, and I can hit the Tab.
02:45And if you start typing the file name, hit Tab, and it will auto complete which is exactly
02:50what we're trying to do inside Git, we are trying to add this exact kind of auto-complete feature to Git.
02:55And then we can type it again, but this time we have to type it out, we can't auto-complete
02:59what we wanted to be, so auto-completion.bash, make sure you spelled it right, and then I
03:04am actually going to go ahead just to be sure and put the ~/ in front of it. So there it is.
03:11Now if we do ls -la again and see the listing, you will see that now it's listed up here
03:16with all the dot files, and it's been renamed with a dot in front of it.
03:20Now the next thing is we want to edit this bash_profile.
03:23Now again if you have a bashrc file, you can edit that instead, but I'm going to edit .bash_profile.
03:29And the way that we want to do that--I am going to do it with the nano text editor--you
03:33can also do it with TextMate if you have TextMate installed,.
03:35But I am going to show you with nano because everyone should have nano installed .bash_profile.
03:42There it is. You can see that I've got a couple of things in there already for my configurations.
03:47You may have something different or nothing at all.
03:50Now what we want to put in here is that little bit of shell scripting code. Again, I am going
03:54to copy and paste it rather than type it all out, we just change the indenting here, there it goes.
04:05So if and then in square brackets, space, -f, and then in my user directory, look for that git-completion file,
04:15close the square bracket, semicolon, then so that says if it can find the file, then load it.
04:21That's what this source does, it says read the file in and actually load everything that's
04:24in it, run it as a script.
04:26So that's what source does and the last line is fi. That's closing this if statement there,
04:32that's not a typo, it is fi, and it's what let's us know that we've finished from if
04:38down to fi is everything in the script.
04:40I know it's kind of an odd way of doing things, but that's how the shell scripting works.
04:43And then when we are done, you will see down here it says Exit and to get this character,
04:48it's Ctrl+X, so Ctrl+X will exit, save it, and type a Y, and it will say what do you
04:55want to call this file just hit Return because it already has the old name there.
04:59And now when we close this window and reopen it, now it will have loaded in that git-completion code.
05:06Now we'll see that later, we'll work with it later, but if you follow those steps, it is installed now.
05:11This is nice because it means we can do things like type git, and then we can start typing
05:14a word like H, and we hit Tab, it will now complete that word for us.
05:19It will do the same thing for commands and branches and a lot of the different things
05:23that we are going to be working with in Git, it will have those ready to auto complete
05:27on the command line for us and help us speed things up.
05:31Now in the next movie, we'll talk about what the command git help does for you.
Collapse this transcript
Using Git help
00:00In this movie I want to talk about the help command inside Git.
00:04And the way that you invoke it is just to type git, which is how we preface
00:08all of our commands that are going to go through Git, followed by a space, and
00:12then help, so that's the command, so we have git, we are telling Git execute the command help.
00:17This is the most basic command there it is because what git help does is it
00:21returns a page that will help us out about using Git.
00:24So here's how to use Git, here is the different things that we can use after it,
00:29and here's the most commonly-used Git commands with an explanation of each of
00:32them, and if you scroll to the bottom, you will see git help followed by the
00:37command will give us more information on a specific command.
00:40So, for example, there is the log command that will show commit logs.
00:45If we want to find out more information about that, we type git help log, and
00:50then returns the Git Manual page up here, you'll see it says Git Manual, and it
00:55has information about git log, how to use it, description of what it does, and
01:00the various options that we can use with the command.
01:03Now to move forward to the next page, you can either hit the spacebar just to
01:06move forward one page at a time, or F for Forward, or B for Backward, and that
01:11will move you forwards and backwards as well.
01:13When you are finally done, you can hit Q for Quit, to get out, and that will
01:18take you back to the command line again, so F for Forward, B for Backwards, Q for Quit.
01:23Those of you who are Unix users may recognize that Manual page is being a
01:28typical Unix manual page--or man page for short. And in fact, it is the exact same
01:32thing, if we say man git-log, that's the exact same page that it brings up, it's
01:38100% the same, so git help log and man get-log are the same thing.
01:44It just gives you a more consistent user interface through Git to get to
01:48those manual pages.
01:50It also reads nicely, get help on the log, right?
01:54Get help as in G E T, get help on log, and it will then provide us with the help page.
02:00So it makes it easy to remember.
02:02So I encourage you to use these help pages whenever you get stuck, whenever
02:05you're trying to figure out how to do something when you want to go a little bit
02:09deeper or when you want to try and find out how different option works.
02:12That's what it's there for.
02:13These help pages are really going to be an indispensable tool when you finally
02:16strike out on your own with Git.
Collapse this transcript
3. Getting Started
Initializing a repository
00:00Once you have Git installed and configured, the next step is to initialize Git
00:05in a project, essentially to tell Git to start tracking things in this Git project.
00:10And the way we are going to do that is with another Git command, which is
00:14git space I-N-I-T, init, short for initialize.
00:18So we are going to tell Git to initialize the project to get everything ready to
00:22start doing its tracking.
00:23Now the first thing we have to decide is where we want to put this project.
00:27So what I am going to do is I am going to put it inside my Documents folder--you
00:32can put yours absolutely anywhere you want--but inside my Documents folder, I am
00:36going to open that up, and I am going to create a new folder, and I am going to
00:38call it first_git_project, and this is going to be the folder that I am going to
00:45use to track, it's going to be my example folder.
00:47Now, I am also going to wanted to go there from the command line.
00:51So if I'm inside my user directory, and then I should be able to change into my
00:55Documents directory, and then into that first_git_project directory, so now I am
01:00inside that folder, right, I am actually right here, right inside that folder
01:05from the command line.
01:06So from here, inside the root of my project, this is where I need to do my Git
01:11initialize, so git init, and this will tell Git, set up this as your homebase,
01:18make this a Git repository, and track all the files that come and go, the
01:23changes that are made inside this directory, things outside this directory, it's
01:27not concerned about, things in this directory, Git will be aware of, and it
01:31doesn't matter how deeply nested they are, Git is going to watch for them.
01:35So you can see it comes up and tells you Initialized empty Git repository in,
01:39and then it gives you the full path to get to that directory, and you can see
01:43that it also added .git, that's where it's actually going to do all of its
01:47storing and tracking.
01:48We are going to look at that directory closer in the next movie, but that's it,
01:52that's all there it is to telling Git hey Git, this is going to be a directory
01:56where you need to do your tracking.
Collapse this transcript
Understanding where Git files are stored
00:00In the last movie, we initialized Git with our first_git_project.
00:04I want us to look at what that did and also understand where Git stores the
00:08files that it uses to do version control on our project.
00:11You can see that I have got the first_git_project directory open here in the
00:14Finder, and you can see that it's empty, actually it appears to be empty,
00:17it's not in fact empty.
00:18If we come to the command line, I can use the UNIX ls command to list what's
00:22in that directory, you can see that that's empty, on Windows that would be the dir command.
00:27I can pass in a special option here which is -la, and that will show me the
00:32hidden dot files as well, and that's any file that has a dot in front of it is
00:36normally going to be hidden.
00:37So .git is a directory that is created by that initialize command.
00:42And this directory is a directory where Git stores all of its tracking information.
00:46Now that's all of its tracking information, it doesn't matter how deep down in
00:50other folders that we've got files going on, they are always going to be stored
00:55at the top level of our project inside this .git directory.
00:58You can think of it as Git's workspace where Git does everything that it's
01:01going to do, and if we wanted to remove Git and remove version control from our
01:06project, well, then it would just be a simple matter of removing this .git directory.
01:09If we remove that, then suddenly Git is no longer tracking our project.
01:13Obviously, we don't want to do that at this point.
01:15Let's take a look at what's inside that directory, ls -la .git, and we can see a
01:20list of the files and folders that Git uses while it's doing its tracking.
01:24Now again this is Git's workspace, you don't want to come in here and start
01:28messing around and changing things, leave it alone, let Git manage these files
01:32and let it put things where they need to be.
01:34The only exception to that would be the config file, that's the only thing
01:38that you would really ever come in here and either take a look at or even possibly edit.
01:43This is for our project level configuration.
01:46Now we have an interface through Git that we saw in the Configuration chapter
01:49where we don't have to come in here and edit it directly, you can just use git
01:53commands to set the different values that you need.
01:55But if you did ever need to, that's where this file is located.
01:58Everything else, you want to leave alone.
02:00Now again, I want to just emphasize the point that everything that Git does
02:04is going to be stored in this single top-level directory, that's very
02:06different from svn.
02:07If you've worked with svn before, svn puts little tracking files in every single
02:12directory down the line.
02:14So if you wanted to remove svn, you have to go through and actually pull
02:17out those .svn files from every single directory so that it will stop tracking those.
02:21Git doesn't do that, Git puts them all right here in one place at the top level.
02:25Now that we understand where Git maintains information about our project, let's
02:29go ahead and create our first commit so that git can start tracking things
02:32inside of our project.
Collapse this transcript
Performing your first commit
00:00Now that we have initialized our project, we are ready to make our first commit
00:04that is to tell Git to track the first change.
00:07So we need to do something to our project, to make a change so that it can track it.
00:11So what we are going to do to start with is create a new file.
00:15So I am going to do that using TextMate, you can use any text editor--again
00:19that's a basic text editor, not a word processor to do this.
00:22So I'll open up TextMate, and I am just going to create a new file, I am going
00:24to say, This is my first file, and then I am going to choose Save, and then I'll
00:31just call it first_file.txt, and I'll just put it on the Desktop for now. All right.
00:37So now I've got this first file, I am going to move it in my project, so there it is.
00:40Now I have made a change to my project, I have added a file, that's the
00:44change that's been made.
00:45So now what I want to do is switch over to the command line and tell Git to add
00:49all changes that have been made to this entire project, everything that's been
00:55made, and I do that with the dot, dot is short for, this directory.
00:58I am already inside my project directory first_git_project, so git add every
01:03change that's been made inside this directory, and now, I am going to commit
01:08that change, tell Git to put it in permanent memory, to put it in the
01:11repository. So git commit, and then I am going to give it a message, -m and in
01:18quotes I am going to put "Initial commit".
01:21Now I could put something more specific in there, but this is going to be good
01:24enough to get us started, this is just a simple message telling it that it's
01:28going to make this commit, and you can see that it did one file change, one
01:32insertion, create mode, first_file, so now it has added that to our project.
01:36Now we have just tracked our first change in Git.
01:38So this is the basic process that we are going to follow throughout working with Git.
01:42It's really quite simple, you just make your changes, then you add the changes,
01:46and then you commit the changes to the repository with a message, and that's it.
01:49That's really the basic cycle that we are going to be following, make changes,
01:53add the changes, commit the changes.
01:54Now of course, there is a lot more going on with each one of these steps and a
01:58lot of options and other things that we can do, but this is the basic flow of
02:01making commits that we are going to be doing over and over and over.
Collapse this transcript
Writing commit messages
00:00In this movie I want us to talk about writing commit messages and the best
00:03practices for doing that.
00:04Now in the last movie we did our first commit, and we gave it a really simple
00:09single-line commit message that was just initial commit, pretty bland and boring
00:13and even worse, it doesn't really describe what we were doing.
00:17What you really want to do is have a commit message that describes the changes
00:21that you're making in that commit set, so added file to project, that would be
00:26more descriptive saying that we added this first file. That you added the
00:29JavaScript to something, that you were fixing a bug.
00:31We are labeling what we were doing in this change set so when we come back and
00:35look at it later, we can just look at the commit message and know what's inside,
00:39what's contained in that set.
00:40So we want to have good descriptive commit messages.
00:42There are also some other best practices that we should follow.
00:45We want to start with a short single-line summary, less than 50 characters, keep it short.
00:50Optionally, we can follow that by a blank line and then a more complete description.
00:54Now if you are just making a tiny little change, a single-line summary will do
00:57it, but if you're committing a change that has lots of changes, that take place
01:01in lots of files, it might be worthwhile to have a more complete description.
01:05Now the way we were doing it before from the single command line, that's a
01:08little tricky to do inside those double quotes, but we can also use a text
01:12editor to make these commit messages well, and that makes it easier to do
01:15multiline commit messages.
01:16Even then you want to keep those additional lines to less than 72 characters,
01:20and that's because different people may be looking at your commit log from
01:23different types of tools, they may be using Mac or Windows, viewing it on the
01:27web, graphical user interfaces, they may be receiving this commit information
01:31via email, so we want to limit it to 72 characters.
01:35And you want to write commit messages in the present tense, not in the past
01:39tense, you are labeling what this commit does, not what you--as the creator--were doing.
01:44Label what it does. This fixes a bug, not I fixed a bug.
01:50It's not about you, it's about what this commit is.
01:52If you need to have bullet points that describe what happens you usually use
01:55asterisk or hyphens, and you can add ticket tracking numbers from bugs
02:00or support requests or develop a shorthand for your organization.
02:03So maybe you put, for example, in square brackets at the beginning of your
02:06message that you are messing with the CSS or the JavaScript or maybe you label
02:11all bug fixes with bugfix:,
02:13or put a tracking number in the front letting it know what sort of support
02:16request ticket it goes with.
02:18These kinds of decisions are really the personal preferences that you or your
02:21organization will need to decide on.
02:22But it's a good idea to pick standards like this and then stick with them and
02:26get everyone to agree to it so that everyone working on the repository is using
02:30the same set of conventions for their commit messages.
02:33So you want to be clear and descriptive, so, for example,
02:36Bad: "Fix typo", would be an example of a bad commit that doesn't really tell what's going on.
02:40A good example would be "Add missing > in project section of HTML" much more
02:46descriptive of what we were doing, what was going on, what is the typo, what
02:49were we in here trying to fix.
02:52Bad: "Update login code" that's pretty general, a good example "Change user
02:56authentication to use Blowfish", right, much more descriptive about what was
03:00going on and what we were doing with this change. Again, providing good labels on
03:04the outside of the envelope and then another bad example would be to include
03:08other comments in there that really aren't about the commit, so "Updates member
03:12report, we should discuss if this is right next week".
03:15Well, this commit is going to live in our repository potentially for years
03:19and years and years having a comment that that says we should discuss if this
03:23is right next week.
03:24This isn't email, right, this in not a way to communicate with our team members,
03:28we can do that using other tools.
03:30What we want to do here is just provide a good label for what's inside the commit.
03:34So let's take a look at an example of one good commit.
03:37So here's an example of a good commit message, it's got a tracking number, this
03:41is the convention that this company is going to use for tracking support tickets,
03:44t23094 - Fixes bug in admin logout.
03:49That's a little bit vague, but we've got something underneath it that gives it
03:53more description, When an admin logged out of the admin area, they could not
03:56log in to the members area because their session :user_id was still set to the admin ID.
04:00This patch fixes the bug by setting session :user_id to nil when any user
04:04logs out of any area.
04:06Notice that it describes what the problem was and then describes what the
04:10solution was as well. So it's all there.
04:13If we come, and we just look at this, we don't have to actually look at the
04:17code, and we have a good idea of what the creator of this commit was trying to do.
04:21It's a good label on the commit to let us know what it's going to do when we add
04:26this change set to the project.
04:27Now I mentioned that you should keep the first line to less than 50 characters
04:31and then subsequent lines to less than 72 characters.
04:33Just as a reference, the longest line in this commit is about 60 characters wide.
04:37So that gives you an idea of how much you can fit on a line, you can go a little
04:40further than this, this is about 60 characters wide, and then you just need to
04:42hit a Return, and then you can keep typing.
04:44So hopefully right here from the start, I can get you thinking about what a good
04:47descriptive commit message is so that all of our commits will be well labeled.
04:51That's going to be really important with Git, because remember Git works with
04:54these commit snapshots and allows us to exchange them between repositories.
04:59So it's very important that we have well labeled commits so that if Bob makes a
05:03commit and then Mary is thinking about incorporating that commit into her
05:08project, she can look at it, see what that commit is, and decide to merge it into
05:12her project so that it becomes part for her project as well.
05:14So having well-labeled commits is really important.
05:16In the next movie we'll take a look at how we can look at the log of previous commit messages.
Collapse this transcript
Viewing the commit log
00:00Now that we've made our first commit, and we've talked about how to write good
00:03commit messages, let's take a look at where those commit messages show up by
00:07viewing the commit log.
00:08The way that we do that is with git log, very common sense, and this will show
00:12us the log of commits that have taken place so far, right now there is only one.
00:17If there have been more than one then we would see them listed one after another.
00:21Now each one of these commits has some basic parts to it.
00:24So here it is, I am going to highlight it, we've got the commit ID, this is the identifier
00:28for this commit, we'll talk more about that a little while later.
00:31But each commit has a unique ID, that's what this number is here, it tells the
00:35Author of the commit, you can see that it pulled this information from my global configuration.
00:39So that's how it knew who was making this commit, that's why that was the very
00:42first configuration that we did, it's very important to do when you first set
00:46up your Git Repo, put in your information so that it can tell with each commit
00:50who is making the commit, and then the date that the commit was made and then the message.
00:55Now if we'd had a longer message here then of course, it would have one line
00:59followed by a space followed by a multi-line message that was below that.
01:02So this is the way to see what's happened in the past in a project.
01:06So, for example, if I am collaborating with team members on a project, and we
01:09all are making commits to a single repository, if I want to log on in the
01:13morning, and I want to see the changes that they've made, and I want to take a
01:16look at what those are, then I use git log to look and see what changes they've committed.
01:21Now I can then go in and view detail on any one of these if I want to get a
01:26little more information.
01:27But the commit log uses those commit messages which hopefully are very
01:30descriptive to let me know what has changed about the project.
01:32Now there are a number of options that you can use with log, we'd use git help log.
01:37We can bring the manual page up that will show you what a lot of those are.
01:39I am going to show you just a couple of them real quick.
01:41So if we use git and then log with -n followed by a number it will limit the
01:47number of commits that it returns to us.
01:49Now I only have one commit, so if I say git -n 1 it returns that single commit,
01:53same thing if I say git 2, it returns just this single commit.
01:57Let's go ahead and put git 0, which is kind of silly, but that will return no commits.
02:01So you can see that it limits the number of commits that get returned to us.
02:03So if we only want to look at the most recent five, we can use this to see just
02:06the most recent five.
02:08We also have the ability to specify the time periods that commits took place.
02:12So git log --since=, and I'll put in a date that is going to be everything
02:19since that date, and you see nothing comes up, but if I do it from the day
02:23before my last commit, then you see everything since that date does pop up, and
02:27that commit shows up.
02:28Same thing with until, let's go ahead and just do come back to this one, and
02:32I'll edit since to say until, so everything leading up until the 15th of June shows up.
02:38If I change it to the 14th then the commit doesn't show up, because the commit
02:42was made on the 15th.
02:43So I can use since and until, and I can use them both together, so if we want to
02:47just see commits between a certain range.
02:49Notice that I have the Author here, I can also say that I only want to see
02:53commits by a certain Author.
02:55Author= and then in quotes or without quotes, I can put just part of the name
02:59that I want to look for.
03:00Look for Author that is Kevin, and you'll see that it brings up my commit.
03:04But if I had another person in here, let's say it's Joe, then of course it
03:06doesn't find anyone with commits named Joe.
03:08This kind of searching in the Author field can also be done in the commit
03:11message field using grep, that's very handy.
03:15We can use grep, that's for a regular expression search.
03:18So global regular expression search is what it stands for, and we'll put it
03:21inside quotes, and let's say we want to search for everything that has Init in it.
03:25And we'll search the commit messages for any text in the commit message that
03:27matches the regular expression that you've put here so that can be very handy.
03:30If we want to look for changes that took place where someone fixed a bug, all
03:35right, we can look at all of the bug fixes.
03:36If we want to look for every time someone added something happening to do with
03:39JavaScript, we can search for JavaScript changes, see what pops up there.
03:43So once again you can see why having good commit messages is important
03:47because then we have the ability to do things like use grep when searching those log files.
Collapse this transcript
4. Git Concepts and Architecture
Exploring the three-trees architecture
00:00In this chapter we're going to examine a few key concepts in Git that will help
00:04you to better understand how it works, and the first of these is the three tree
00:08architecture that it uses.
00:10Let's begin by looking at a typical two-tree architecture.
00:13This is what a lot of other version control systems use.
00:15We have a repository and a working copy, and those are our two trees.
00:20Now we call them trees because they represent a file structure.
00:23All right, our working copy begins with the top of our project directory and
00:27below of that might be four or five different folders that have a few files in
00:31them, maybe a few more folders, each of those folders has a few more folders in
00:35it, and you can imagine that if you map that out, that each of those folders
00:39would then branch out like the branches of a tree.
00:42It's really a directory tree whose trunk begins with the root of our project.
00:45Now the repository also has a set of files in it.
00:49And when we want to move files between the repository or the working copy, we
00:53check out copies--that's the term that we use--we check it out from the
00:57repository into our working directory, and when we finish making our changes we
01:00commit those changes back to the repository.
01:03Now the reason why there are two distinct trees is that these files don't have
01:07to be the same between them.
01:09If I check out copy from the repository, I make some changes into it, I save
01:14those changes on my hard drive.
01:16Now those changes are saved, they are permanent, they are saved in my working
01:20copy, but they're not yet committed to the repository.
01:23So my working copy looks different from the repository.
01:26Both are saved, it's not like I haven't saved the files, I've done that.
01:30They just aren't saved and tracked in the version control repository.
01:34Now if the repository is a shared repository, and there are many people working
01:38from it, they may commit their changes to the repository.
01:41And if I haven't checked out a copy recently to get those changes, then my
01:46working copy doesn't have their changes.
01:48So once again the repository and the working trees will not have the same
01:52information in them.
01:53So that's a typical two-tree architecture. Git however uses a three-tree architecture.
01:58It still has the repository and the working copies, but in between is another
02:03tree which is the staging index.
02:05Remember when we did our first commit in the last chapter, we didn't just do a
02:09commit, we did an add first.
02:12We added, then we committed, it was a two-step process.
02:16That add, added our files to the staging index, and then from there we
02:21committed to the repository.
02:23Now it is possible to go ahead and just commit directly to the repository and
02:26skip that staging step. We'll learn how to do that later.
02:29But it's important that you understand that this is part of the architecture of
02:32Git, and it's a really nice feature.
02:34Because then what it means is that we can make changes to ten different files
02:38in our working copy.
02:39And then we can say, all right, I am ready to make a commit, but I don't want to
02:44commit all ten of those, I just want to commit five of these as one changed set.
02:48So what I am going to do is I am going to put those on the staging index, add
02:53them to the staging index, get those five files ready to go, and as soon as I am
02:58satisfied that they are ready, now I will commit those five files in one changed
03:01set to the repository.
03:03The other five files are still saved in my working tree, but they never got
03:07added to the staging index or to the repository.
03:09They are sitting there waiting for me to make another commit, to stage those
03:13changes and then commit them to the repository.
03:15And of course we can pull things out of the repository in the same way.
03:19It's possible to pull them from the repository to the staging index, from the
03:23staging index to the working directory, usually that's not what we do.
03:26Usually we go ahead and pull them straight from the repository down to
03:29the working directory.
03:30And in the process the staging index will be updated too.
03:32We have our working copy, where we have our changes that we've made, and we've
03:36saved, and saved to our hard drive, but we have not yet committed them to the
03:40repository, we haven't told Git to make this a changed set and to track it.
03:43Then we have the staging index, which is where we prepare things, we stage them
03:47for the commit, and then after they've been staged, we commit them to the
03:51repository so that they are permanently tracked and they now have a commit
03:55message attached to them.
Collapse this transcript
The Git workflow
00:00In the last movie we gained an understanding of the three-tree architecture that Git uses.
00:05Now I want us to go further with that and look at the workflow that one
00:09typically uses when working with those three trees.
00:11This is the exact process that we're going to do in the next chapter as we begin
00:15to work with Git commands.
00:17But I think it's helpful for us to have an illustrative overview first.
00:21So let's look at the process.
00:22First, we are going to work with just having a new file.
00:25Now remember Git doesn't just work with single files, it works with sets of
00:28files that it puts together into a changed set.
00:31But for now, we're just going to be working with a single file to make the illustration simple.
00:36So we've got our three trees, we've got our working directory, the staging
00:39index, and the repository.
00:41We are going to add a file to the working directory, this is exactly what we did
00:44when we made our first commit, we added a file to our working directory, we are
00:48going to call this set of changes A just to have a simple reference for it.
00:52When we called the git add command, what it does is it pushes that set of
00:56changes that we've specified up to the staging index.
00:59So now the file.txt exists in staging index as well.
01:03You may notice that I'm using git add with the exact file name, when we did our
01:07first commit we did git add and had a dot after it.
01:10A dot just says gather all the changes that have been made to this entire
01:14directory and push all of them up to the staging index.
01:17So if I'd changed five files, it would have moved all files up to the staging
01:21index at the same time. Here I am just adding a single file.
01:24Now once we've got everything in our staging index exactly like we like it,
01:28we're ready to bundle it all up and send it as a commit to the repository, we
01:33used the git commit command.
01:34So git commit will take that set of changes and push them up to the repository
01:39so that now that file exists in the repository.
01:42It's there permanently, it's tracked, and it has a commit message about the
01:46change that we made.
01:48That's exactly what we did when we made our first commit.
01:51Now let's take a look at what happens when we make an edit to the file.
01:54So we've got our same state as before, we now have that change in the repository
01:58and our three trees all look identical.
02:01The repository, staging, and working index have the exact same files in them.
02:05But now we are going to make a change to the file that's in the working directory.
02:09So now when we save that we have version 2 of that file, all right, it's a
02:13changed version of the file, and we are going to call the difference between
02:16them, that changed set, we are going to call B.
02:19So when we are done making our changes, then we want to stage the changes, and
02:23we do that with git add, that then pushes change B up to the staging index so
02:27that now version 2 of the file exists there as well.
02:30And then when we finally have everything altogether, we can commit that set of
02:33changes that are represented by B to the repository, using git commit.
02:38So that will push it up to the repository, and now version 2 of the file exists
02:42in all three of those places. We can do this process one more time.
02:47We have change C with version 3 of the file.
02:49We'll push that change up to the staging index, and then we'll commit it, and it
02:54will go to the repository.
02:55So this is the typical Git workflow that we are going to follow.
02:59And as we saw before if we used git log, it would show us the sequence of those
03:03changes that would show us changes A, B, and C that have been made over time.
03:07Now of course, Git doesn't simply refer to these commits as being A, B, and C, it
03:10has a more complex way of dealing with it.
03:12We are going to take a look at that in the next movie.
Collapse this transcript
Using hash values (SHA-1)
00:00In this movie we're going to talk about the way that Git refers to its commits.
00:04Remember in the last movie where we talk about the workflow we had different
00:08changes that we moved from our working directory, to our staging index, and to the repository.
00:12And I just went ahead and gave those the very simple labels A, B, and C.
00:15Now that's not what Git calls them, and that's what we're going to looking at in
00:20this movie is how Git refers to each of these snapshots of changes.
00:23Now be careful don't mistakenly think that A, B, and C refer to a single file in anyway at all.
00:29In our example we were using a single file, but these are changed sets, sets of
00:33changes, and more often than not they wil refer to multiple files.
00:37So in a typical Git workflow, A would represent changes to five files, B would
00:42represent changes that were made to three files, C might be two new files that
00:47were added to the repository.
00:48So A, B, and C are snapshots of the changes that were made not anything to do
00:54with files or versions of files.
00:56So let's take a look at how Git does refer to these files.
00:59When we submit these changes to the repository at that point Git generates a
01:04checksum for each changed set.
01:07A checksum is a number that's generated by taking data and feeding it into an
01:12algorithm, so checksum algorithm converts data into a simple number, and we call
01:17that simple number a checksum.
01:19The same data put into the algorithm always equals the same checksum coming
01:23out that's important because if we change the data going in we get a different checksum out.
01:28So one of the most common uses for checksums in computers is to make sure
01:32that the data didn't change, if the data changed well then the checksum will be different.
01:36And this data integrity is fundamentally built into Git that's very different
01:41from other version control systems, they don't use checksums to validate that
01:44the data hasn't change.
01:46Git does it makes sure that you can't change what's in a commit or else you'll
01:50change the checksum that comes out of it. Changing the data changes the checksum.
01:54Now the way that Git generates this checksum is by using the SHA-1 hash algorithm.
02:00You don't need to know anything about that hash algorithm itself, but
02:05you do need to know that it's called that because you will often hear people
02:08refer to this checksum or hash as being the SHA, or S-H-A value.
02:14The number that the algorithm generates is always going to be a 40 character
02:18hexadecimal string. Hexadecimal means they can have the numbers 0 through 9 and
02:22the letters a through f.
02:24So an example might look something like this 5c15e8bd540 and so on, 40
02:31characters long made up of those characters.
02:34So what Git does is it takes the entire set of changes, runs them through in
02:38algorithm, and in the end comes out with this one 40 digit number, we've seen
02:44this number before.
02:45When we get our Git log command here is that ID that I told you to get uses to
02:50track each one of our commits, its right there this is the SHA, S-H-A value, or
02:56the commit ID, you can call it whatever you want really.
02:59But it is a number that will be unique to the changes that are in this commit.
03:04So the way they get actually attaches that information is that if we have those
03:07three snapshot those sets of changes it feeds them into its algorithm to come
03:12up with the S-H-A value, and then it attaches a bit of meta information to each
03:18one of those snapshots, it has that commit number at the top, it has the parent
03:23commit the commit that comes before it, the author of the commit, and then the commit message.
03:28So here you can see how the series of those commits are linked together, you
03:32can see that the parent for each one refers to the SHA-1 value of the other one
03:37before the identifier that come before, and that's how it knows the sequence of those commits.
03:41And then each one of those, each bit of meta information, points at a snapshot a
03:46set of changes or a Git object.
03:49Understanding how Git generates these hash values is important, because it helps
03:53us understand how Git summarizes these snapshots, it illustrates the data
03:58integrity that's built into Git, and most importantly we're going to be using
04:02these SHA-1 hash values to refer to the commits.
Collapse this transcript
Working with the HEAD pointer
00:00In this movie we'll gain an understanding of the HEAD pointer in Git.
00:04Git maintains a reference variable called HEAD, all capitals, H-E-A-D.
00:09And we call this variable a pointer, because its purpose is to reference, or
00:12point to, a specific commit in the repository as we make new commits the pointer
00:17is going to change or move to point to a new commit.
00:20HEAD always points to the tip of the current branch in our repository.
00:24Now this has to do with our repository, not our staging index, or our working
00:29directory, we're talking just about the repository the commits that we've
00:32actually made to the repository by checking them in.
00:36Another way to think of it is the last state of our repository or what was last
00:40checked out, and because it's where the repository left off or the last state,
00:44you can also say that the HEAD points to the parent of the next commit or it's
00:49where commit writing is going to take place.
00:51I think a good metaphor to think about this is the playback and record head on a
00:55cassette tape recorder.
00:57As we start recording audio the tape moves past the head, and it records onto
01:03it, when we press Stop the place where that record head is stopped is the place
01:07it'll start recording again when we press Record a second time.
01:11Now we can move around, we can move the head to different places, but wherever
01:15the head is positioned when we hit Record again that's where it's going to start recording.
01:20The HEAD pointer in Git is very similar, it points at the place where we're
01:24going to start recording next.
01:25It's the place where we left off in our repository for the things that we've committed.
01:29Let's take a look of some illustrations that will make this clearer.
01:33In the last movie we saw how we could refer commits by using the SHA values, and
01:37I gave you an illustration like this.
01:40Now I want to distill this down and make these three different commits just the
01:44first six characters of each of the shots, so I'm going to represent each one of
01:48these three by just having 5c15e8, 38e73d, and a614b5.
01:54Now can you guess where the HEAD points after we've made these three commits?
01:58It points to the tip of the current branch in our repository that's the last
02:02commit that we made, it's the parent of the next commit.
02:06So when we make another commit will be attached to the end there a614b5 will be
02:11the parent, and then we'll make the new commit.
02:13Now HEAD becomes especially important when we start talking about branches and
02:17branches is something that we'll talk about little later on, but I want to go
02:21ahead and just give you the basics of it here.
02:23By default the branch that we're working on is the master branch that's our main
02:27branch, so let's walk through the master branch and see how the HEAD pointer
02:30moves as a make our commits.
02:32So we're going to start out with 5c15e8 as the first commit. At that point the
02:37HEAD pointer points to that commit.
02:39When we make a new commit it says, oh the parent is going to be 5c15e8, it puts in that
02:46new commit, and it moves the HEAD pointer to point to that last commit, the tip
02:51of our master branch.
02:52And then we make another one it does the same thing it attaches it to the end
02:57and moves the HEAD pointer.
02:58It's essentially like it moved the record head of the tape recorder forward.
03:02Now in Git we have the ability to create new branches that is to create a new
03:06set of code that we're working, and it's separate from our master branch,
03:10we'll learn how to do that later, but for now let just say that we have a new
03:14branch, and that new branch is going to start having its own commits that are
03:17separate from master.
03:18When we make the first commit HEAD moves to that commit, and then we make
03:23another commit HEAD moves along that and along that.
03:26Now we can switch between these branches we can check out one or the other, so
03:30if we've have our new branch checked out well then HEAD is pointing at the last
03:34commit of the current branch, new branch.
03:37If we check out our master branch and switch back there. Well guess what?
03:42HEAD moves to point to the tip of the current branch that we have checked out their, master.
03:46And if we were to check out new branch again it would switch back and forth.
03:50So HEAD always points to the tip of the currently checked out branch from the
03:55repository, don't worry too much of this branching stuff doesn't make total
03:59sense just yet we'll get to that later on, and you can always come back and
04:02review this movie than if you need to.
04:04Let's go to the command line and see how Git actually keeps track of HEAD.
04:08So here I am inside my first Git project directory, and you'll remember that
04:13inside there we had a folder called .git.
04:17So let's change into that folder and just take a peek here, you don't have to
04:20follow along with me, if you don't want you can just watch.
04:23Let's look what's in that directory and look here there is a file called HEAD,
04:26and that's what Git uses to know where the HEAD is pointing.
04:29What is HEAD currently pointing to?
04:31I'll take a look at what's inside that file just say cat HEAD, and you'll notice
04:36that it says it refers to refs/heads/master, it doesn't point to a current
04:42commit, it points to a current branch, but that current branch has a tip it has
04:48a latest one, and that is maintained in this refs folder.
04:51So it's pointing into this folder, let's go inside refs, let's take a look at
04:57what's in there, you'll see that it has heads, and it tells us it's inside
05:01refs/heads and master.
05:03So sure enough if we go in heads, we'll see that there is something in there
05:08called master, and if we take a look at master, there it is there is the commit
05:12that's the current commit that HEAD is pointing to. so it says all right, Git
05:16you want to know where HEAD points? Go look in a file called HEAD.
05:19HEAD tells me to go look inside refs/heads/master, and when I look in that file
05:24refs/heads/master points to 7aa195bd44ea et cetera, yours maybe different.
05:32Now what is that commit?
05:33Well, if we take a look at our log, git log, there it is 7aa195bd44a.
05:40So that's the first commits the initial commit that I've made that's where it points to.
05:44You can use HEAD a lot in Git as a reference to the tip of the current branch, right.
05:50That's what we're saying when we say HEAD is the tip of the currently
05:53checked out branch.
05:54And in fact when I say git log it's actually the same thing is saying git log HEAD.
06:00Starting at the HEAD tell me what's their, start logging from the HEAD going backwards.
06:04So I think it's important to demystify this concept of HEAD. I think a lot of
06:08people start with Git and don't have a good understanding of what the HEAD is at
06:12the beginning. And then when it starts popping up later on, you start seeing
06:15references to HEAD you're like, wait a minute what is this thing, what is HEAD?
06:19Well, now you know.
06:20Now you have an understanding that HEAD is just a pointer that goes to the tip of
06:23the current branch in the repository.
Collapse this transcript
5. Making Changes to Files
Adding files
00:00In this movie we're going to talk about how to add files to you Git repository.
00:04Now we already did that once we did that when we did our initial commit, but now
00:08we have a better understanding of the Git architecture and how that works.
00:11So I want us to revisit again, and we'll get some more insights.
00:14If you remember that we have our Git project here, and I have first_file.txt,
00:18which I've already committed during my initial commit.
00:20In the command line I'm in that same project directory and the first Git
00:23command that I want us to learn is git status. Git status is going to report
00:29back to us the difference between our working directory, the staging index, and
00:33the repository. It's going to let us know, what is the status between those
00:37three different trees?
00:38Right now, it says we're on branch master we talked about that the default
00:42branch is called master. We're going to be working on master all the way up
00:46until we start talking about creating new branches, so you can pretty much just
00:49ignore that, we're on the master branch.
00:51And it tell us there is nothing to commit our working directory is clean,
00:55that's letting us know that there's nothing in the staging directory and the
00:58working directory exactly matches what is in the repository and the current
01:02branch where the HEAD pointer points to that exactly the same things that we
01:07have in our working directory. Now let's add some files.
01:12So in order to put some new files inside this project I'm just going to open up
01:15my text editor, I'll create a new file we'll call, This is a second file, and
01:21I'll save that as second_file.txt, and I'll just save it to my desktop and then
01:27let's go ahead and make another one here, this is a third file, and we'll do
01:31Save As third_file.txt.
01:36So now I've got two file second file and third file, and I'm just going to drag
01:40both of those into my project.
01:43So now I've added two new files to the project, let's do git status again and
01:48see what Git tells us about it.
01:49Now Git tells us that there is a section called untracked file. Essentially what
01:53Git saying is, I have information about what's in the repository, and I can see
01:58your working directory.
01:59Your working directory has some new things, they're things that I'm not
02:02currently tracking. That is, if you make text edits to these, I'm not going to
02:07be able to tell you information about what changed because I'm not currently tracking these.
02:11And then it helpfully tells us that if we want to add them we use git add
02:16followed by the file name to include what will be committed.
02:19Now if we want to include one file we just say git add and the first file name. If we want
02:23to include multiple files we can say git add one file name after another, or as
02:28we saw before, we could just do git add with a dot to add everything that's in this directory.
02:33Now we are not going to do that this time, we're going to go ahead and list it out.
02:37If I start typing the name of the file then hit Tab it'll auto-complete it for me,
02:42git add second_file.txt, I'm going to tell it to add it to my staging directory.
02:48Remember how we did that with the illustration, we move it from the working
02:51directory into the staging directory with git add.
02:55Now when I do git status, let me clear the screen just so it's clearer between the two.
03:02Now it tells me two different sections, it say changes to be committed, that is
03:06my staging index that's things that are being staged and ready to be committed.
03:10You can see that here because it also tells us helpfully what the command is to
03:14unstage things, to take them out of the staging index. And then we still have
03:18our untracked files down here, these have not been added yet, these are just in
03:22our working directory.
03:24One file is now in my staging index, one file is still in my working directory.
03:29Now let's do a commit.
03:30So we're going to commit, remember the command for commit it just git commit, and
03:36then we want to provide a message, so -m and then in quotes we'll put our message,
03:40Add second file to project.
03:45So that's going to be the message that goes with my commit.
03:49Now, what is it going to commit here?
03:51It's going to commit what's in my staging index, I've staged things to be
03:54committed so that's what gets committed.
03:57So now it makes my commit, gives me the commit message, gives me the first part of
04:02the SHA back so I can see that.
04:04And then it tell me some information about what changed, about sort of the
04:07amount of things that were changed. We don't have to worry too much about that.
04:11Now let's do git status and see what it tells us, git status, I'll clear it just
04:15so that's easy to see the difference.
04:17Now it no longer reports anything about second file, because second file has
04:21been added to our repository, it doesn't tell us anything about it if what
04:25we have in our working directory is exactly the same, it's just reporting
04:29the differences to us.
04:30And the difference here is that there's a third file and third file is not
04:34tracked still, it didn't get added in my commit it got left in my working
04:38directory, only the thing that I staged got put into the commit.
04:42If we do a git log, I'll clear the screen again just so it's nice and clear,
04:47you'll see that here's my second commit with my second message right after my initial commit.
04:53So they're always going to be in reverse chronological order the oldest ones
04:56will fall further down the list the most recent things will be at the top.
05:01Now of course, if we want to git status again if you want to add third file to
05:06our repository git add third_file.txt.
05:10Now that's going to be in our staging index, see it there, changes to be committed
05:16git commit with another message add third file to your project.
05:23Now of course, you would probably be doing something more descriptive than what we're
05:26doing with these sample files, but now you can see an example of this third file
05:30being committed, git status, now it'll report to us that there's nothing to
05:33commit, our working directory is clean, git log shows us all three of those
05:38comments, and we have all three of the files in our projects.
05:41So these three files are now in the repository exactly as they are in our
05:45working directory, the two are exactly the same, and if we made changes to them
05:50it reported to us using git status.
05:52In the next movie that's what we'll do, we will see how to make changes to these
05:56files and how those get reported and how we commit those changes.
Collapse this transcript
Editing files
00:00In the last movie we reviewed how we add files to our Git repository.
00:05Now what we want to see is how to edit files and how to Git works with those edits.
00:09I have my git project, and I have my three files here, let's make some edits
00:13to one of these files. So let's pop up in first_file.txt, it's called, This is
00:17the first file that I added to my project. So we've made an edit to it, let's save
00:24our change and close it.
00:27So now that change has been made to first_file.txt.
00:31Now when we come back over to our command line we say git status now it comes
00:36up and it tells me, owe something is changed.
00:40Changes that are not staged for commit essentially just changes, and it tells me
00:45you've modified first_file.txt. Remember before I said there were untracked files,
00:50this is different. It's telling us about changes and tells us what those
00:54changes are, you've modified first_file.txt, if you want to add it, Git add it with
00:59add it, and then it tell us how we can discard those changes, which we will take a
01:02look at a little later.
01:04Adding it is exactly the same process for a new file versus a changed file.
01:10Essentially it's the process of moving it from our working directory into the
01:13staging directory, git add first_file.txt. It will now add that change to our
01:20staging directory, git status, clear it so you can see it.
01:24Now it says changes to be committed is the modified file first_file.txt.
01:29Now before we make that change, and we commit that, let's make some more changes, second_file.
01:36This is the second file that I added to my project, and let's go ahead and
01:43open up third_file.
01:45This is the third file that I added to my project.
01:50So now we've got all three of those, let's now take a look at git status and see
01:56what's going on now.
01:57It's got still the thing that I changed in the staging directory first_file
02:02still there ready to be committed it also notes the new changes that I made
02:07those are new in the staging directory yet.
02:08If I want to put those in the staging directory if I want to package them as
02:12this next commit then I need to add them.
02:15So let's say that I want to do that with the second file git
02:19add second_file.txt.
02:22Now if I do git status, you'll see that two files are listed as being modified,
02:27ready to be committed, one file is still in my working directory, I haven't added it
02:31to my staging directory yet it just notes the fact that it's changed, that it's
02:35different from what's in the repository. So let's do a git commit with a
02:41message, and we're going to say made changes to first and second files.
02:50So now it makes note of that change git status, clear the screen so you can
02:56see it, and you'll see that it's still tracking the changes for that third
03:00file, it took those first two, packaged them up together as a snap shot, sent
03:04them to my repository, git log, and we see there it is. Now here is the new
03:10commit that it just made.
03:12So that's all there is to being able to add files and edit files, it's the same
03:16process for both of them. We can say git status, and we can see the changes git
03:20add, and we can then put the file name that we want to add--doesn't matter if it's
03:24a new file or an edited file--and then finally git commit with the commit
03:28message telling it, Modified the text of the third file, and now it's in the
03:37repository as well just like that git status, git add, git commit.
03:42These are the basic steps that we're going to be using with Git.
03:45Now what if before you made the commit you wanted to remind yourself what did
03:48you change any to these files maybe you were surprised that one of them came
03:52up as being changed.
03:53How can we see what those changes are? We'll look at that in the next movie.
Collapse this transcript
Viewing changes with diff
00:00In the last movie we saw how we could edit files and commit those to the repository.
00:05In this movie I'd like us to take a look at how we can see what changes have
00:09been made before we make a decision about whether to commit those to the repository.
00:12Before we begin that, let's make some edits.
00:14So let's open up our first_file.txt, and this is the first file added to my
00:19project, and I'm going to say space, it comes before all other files. Hit Return.
00:27I'll save the whole thing, close it up.
00:29Now, we know what's going to happen if we do git status, it's going to tell us
00:34that the file was modified, right?
00:35What we want to do now though is find out what were those modifications.
00:39This is very useful, especially if we've been working for a couple of hours,
00:42we've been making lots of changes to lots of files in our project, and maybe we
00:46were a little surprised even to see that the file popped up here in the modified
00:50list, we don't remember making a change to that file.
00:53How can we refresh our memory? What changed about this file?
00:55In the UNIX world it's very common to use a program called diff, D-I-F-F, in order
01:00to compare two files.
01:02And so Git uses that as the term that it uses to show us a diff between the old
01:09version and the new version. And we do that just with git diff.
01:13So git diff will compare the two, that's comparing what's in the repository, the
01:17version that HEAD is pointing at, versus what's in our working directory.
01:21So the version in the repository is the one with the minuses, the one that has
01:25the pluses is going to be what's in the new version.
01:29So the old version was, this is the first line that I added to my project.
01:33The new version replaced that line with this line, this is the first file added
01:37to my project, and added two more new lines, it comes before all other files.
01:42Of course, what I changed here was just this little bit of text, it doesn't tell
01:47us that, it tells us on a line by line basis what is different.
01:51It also notes that there's no new line at the end of this file, which means that
01:55we don't have a line return after the period. We do have a line return after this one here.
01:59So you can kind of ignore this line, don't worry too much about it.
02:03Main thing that you want to see is that this line has been removed, this
02:07line has been added, as well as these two lines have been added, that's what it's telling us.
02:11Now, if we'd had a long document, let's say it was 300 lines long, it would just
02:16highlight just the little bit that had changed.
02:19It wouldn't show us the whole document, it would just say, oh, you know what,
02:22this is the bit that's changed, and this little bit right here would actually
02:25tell us what line numbers we were looking at. That's a subtle but important point.
02:28In most text editors there is a way to view line numbers.
02:31For example, in TextMate, under the View Menu, in the Gutter, I can tell it to
02:35show me line numbers.
02:36Then it will show the line numbers out here, and that will help you locate these
02:40changes relative to what's being told to you in the diff file.
02:43Now, if we'd had changes to more than one file, let's take a look here, let's
02:47open up a third file, and we'll just say, This is the last file in the project right now.
02:55Save that, come back over here, and let's take a look at git diff again.
02:59And you'll see that it tells me, here is the changes in first file, here's the
03:03changes in third file, it lists them one after the other.
03:06If I wanted just one of those, of course, git diff with first_file.txt would
03:11just report the changes to that single file.
03:13So we can see all of the changes that have been made, that's all of the
03:18changes listed here under modified, or we can go file by file and take a peek
03:23at each one of them.
03:24Now, when we do this we're looking at the difference between the repository
03:27version and our working directory.
03:29In the next movie let's look at how we see the changes that are in our staging directory.
Collapse this transcript
Viewing only staged changes
00:00In the last movie we saw how we could use git diff to get details about the
00:04changes that were in our working directory.
00:06In this movie we are going to see how we can do the same thing with our staging index.
00:11Now the first thing, of course, we need to do is put something in our staging
00:15index, so let's do that with first_file.txt.
00:17We know how to do that with git add first_file.txt, now it's in our staging index.
00:22Git status will show us, first_file, those changes are now staged.
00:27The changes to third_file.txt are just in our working directory.
00:31If we were to do a git diff now, it would just report the changes that are in
00:36our working directory.
00:38So when I told you earlier that it was comparing your working directory with the
00:40repository, that's not quite true, it's actually comparing it against the
00:44staging index and the repository.
00:46So it's things that are unique, things that are different about the
00:49working directory only.
00:50So what about those changes for first_file, how do we see those?
00:55Well, we do the same thing using git diff, but now we pass in another option,
00:59which is staged, git diff --staged.
01:03It's the option to diff that tells it to look at what's in the staging index and
01:07compare that against the repository.
01:09So now you can see we're only seeing changes that we made to first_file.txt.
01:14So git diff by itself will return the changes that are in the working directory.
01:19I also just want to note for you that git diff --staged in versions before 1.6
01:27of Git, it was actually called cached.
01:30But that wasn't as clear to people and so they standardized on calling it the
01:34staging index, and it became called staged.
01:36Now, you should be working with version 1.7 of Git or later, so it should be
01:41staged for you, but cached also still works, it does the same thing, it returns
01:44the exact same information. But we are going to stick with using staged.
01:49So now just like before, of course, if we git add our third_file, now git status,
01:56you can see that both of those files are now in the staging index and git diff
02:00returns no changes, git diff --staged will show us both sets of changes.
02:07So the last thing we want to do is let's go ahead and just save our changes.
02:11So we've got these to be committed already, these are in our staging index, so
02:16we're just going to do git commit, and let's just give it a simple message,
02:20we'll say Minor text edits.
02:22So there it is committed, now if we do git status, our working directory is clean again.
Collapse this transcript
Deleting files
00:00In this movie we're going to learn how to delete files and track those
00:04deletions using Git.
00:06To do that, let's create a couple of files that we can throw out.
00:08We're going to keep first, second, and third file, let's make a couple of new
00:12ones here, and I'll just call this one This is a file to delete.
00:18We'll save that as file_to_delete1.txt, and then we'll just do a Save As,
00:28make it file_to_delete2. So, we'll close that up.
00:32We've now got two files here. I'm going to add those to the repository.
00:36If I just do git status now, these show up as untracked files.
00:41So, if I delete these, well then they just stop being tracked files, right?
00:45When we talk about deleting files, we're talking about deleting them from the repo.
00:48We're talking about the things that are tracked files.
00:50So, the first thing we need to do is add these to our repo, and then we can go
00:55about deleting them.
00:56So, let's do git add, and we will add everything that's in our working directory.
01:00So now, if we do git status, we'll see that those are ready to be committed, git
01:06commit with a message Adding I'm going to call these 'red shirt' files.
01:13That's like the red shirts in Star Trek.
01:16We're adding them just for the sole purpose of them being able to be deleted.
01:19So now, if we say git status, we'll see that there's nothing ready to commit,
01:23everything here is in the repository, including these two files that we're going to delete.
01:28Now, I wanted to have two files because there's two different ways that we're
01:31going to look at doing deletions.
01:33One way is that we just simply come over here, and we'll take file_to_delete1,
01:37and we're just going to drag it down to our trash, throw it away, that's it!
01:42Now, if we say git status, what does git tell us about it?
01:45It looks in the repository and says, hey!
01:47I have a file that I was tracking called file_to_delete1.txt.
01:51I'm looking in what you've got in your working directory, and that file is not
01:56there, and it tells you it's been deleted.
01:58Now if we want to delete this file, we say git add file_to_delete.
02:07It looked in the directory and saw 2, we want file_to_delete1.txt.
02:11We're going to git add, and it comes up and doesn't tell us anything.
02:14Let's do git status again and take a look at what it says.
02:18Nothing changed, it's still listed as Changes not staged for commit.
02:21It's because when we do a delete, well we're not doing an add then we do add
02:26whenever we're adding a file or whenever we're adding changes.
02:29With the delete, now we have to do something different, and it tells us that here.
02:33It says add/rm, either add changes or use rm to update what will be committed.
02:40So rm is for remove, and that's the Unix shorthand for remove as well.
02:45So, if we want to remove this file, I have to say git rm files_to_delete, and
02:51we can't use auto complete, because it will pick up the one that's in the directory.
02:55We have to actually type it out, or use auto complete and then make the edit,
02:59git remove file_to_delete1.txt. Now, we hit Return.
03:04It says okay, I'm going to remove that. Now, we'd git status.
03:09Now, it comes up and says okay, changes to be committed.
03:12That's things that are in our staging area.
03:14Now file_to_delete1.txt is in our changes to be committed.
03:20Now, we do a regular commit, git commit with a message Deleted first red shirt file.
03:30First, one has gone now.
03:32Notice that it tells us Delete mode here that was deleted, one deletion was
03:35made, git status now.
03:38Says everything is clean, git log, we now see that, that first red shirt
03:42file has been deleted. Now, it's the first way to use files.
03:46We just go into the file system and delete the file by hand, and then tell
03:50git remove that file.
03:52Just like we were adding changes, well now, we're doing a remove change.
03:55An easier thing though is just to do the whole remove from Git, tell Git remove
04:01file_to_delete2.txt.
04:03Now auto completion does work. It finds the file.
04:06When I hit Return, it did the exact same thing, it removed the file from
04:10the current directory.
04:12It did have one slight difference though, which is that it completely erased it.
04:17It used a Unix remove, not a let's put things in the trash remove.
04:22So, in my trash, I have file_to_delete1 because I drug it in there, file2 is not
04:27in the trash, it has just vanished, it just completely gone.
04:30That is a difference, if you do want to keep things around, if you want to have
04:33that sort of fallback of having things in your trash, you can do that.
04:36Of course, it's in our repository, so we've got a saved version of it.
04:40If we ever need the saved version, we can use that one.
04:43Let's do git status now and see what it tells us.
04:46It's already in our staging area.
04:48So, now in one step, we've both eliminated the file and added it to staging,
04:52whereas the other one was a two-step process.
04:55The other one we took the file to the trashcan, then used remove to put it in
04:59the staging area, and now let's add that last file with the commit, git commit
05:05-m and "Removed second red shirt file".
05:10So there we go, our two files to be deleted are now removed, and we learned two ways to do it.
05:16The first is to move the file out of the working directory, in this case into
05:20the trash, and then tell Git about it, and the second is to tell Git to do the
05:25delete for us, and add it to the staging directory all at the same time.
Collapse this transcript
Moving and renaming files
00:00In this movie we're going to talk about how to move and rename files.
00:04And like we just saw with deleting files, there's two ways that we can do it.
00:08The first, is that we can just go into the regular operating system, and do all
00:12of our moving and renaming, and then come back and tell Git about those
00:15changes, and tell it to stage those changes. The second, is that we can do it
00:19from Git, and let Git handle working in the operating system for us, just like
00:24it did with delete. So let's look at both of these.
00:26First, let's look at renaming. So, let's say we've got first_file.txt.
00:30Let's go in here, and let's just change it to primary_file.txt.
00:36So, we've given it a rename, and we did it from the file system.
00:40Let's switch back over to Git and ask Git what's the status now.
00:44Notice that it didn't tell us that it was a renamed file, it tells us that it
00:49was a file that was deleted, and then, there is a new file that's untracked.
00:54That's how it sees what happened.
00:56It sees the fact that the file that it was expecting to find is not there, and
01:00now I have a new file there instead.
01:02Let's try adding those changes to the staging index, git add primary_file,
01:07that's the new one, and git remove first_file.txt.
01:13So now, it has both of those changes in its staging index, git status.
01:19But now, it says ah, I noticed that now they're renamed.
01:23So, once it gets to the staging index, it actually compares the data between
01:27the two and says oh, these are pretty close.
01:29It doesn't have to be exactly the same, some changes could have taken place at the same time.
01:34I think the threshold is about 50%.
01:36As long as the data is about 50% the same between the two of them, it says oh,
01:40okay, this is the same file.
01:42So you've renamed it from first_file.txt to primary_file.txt.
01:47And now, of course, we know how we can commit that change just using a regular commit.
01:51Let's take a look at how we're going to have Git do the process for us.
01:55So, if we do another rename, let's do git--and a rename and a move are the same thing in Git.
02:01It's similar to the way it works in Unix.
02:03So, if we want to rename the second file as secondary file, let's git move
02:11second_file.txt to secondary_file.txt.
02:18So, we're moving second_file.txt to secondary_file.txt, which is essentially the
02:22same thing as a rename. We tell Git to do it though.
02:26If we come over here, and we look in the operating system, you see that it took
02:31care of changing it for us there.
02:32And if we do git status, you'll notice that it went ahead and added it to the
02:37staging index for us just like delete did. It said, all right,
02:40I'm going to change it in the file system, and add it to the staging index all in one step.
02:45So, I think the lesson from both deleting and the moving and renaming is that
02:48it's easier to have Git handle it because Git will take care of adding it to
02:53the staging index for you right away.
02:55Now, if you're doing lots and lots of changes and moving things around in
02:58the file system, it maybe better for you to go there first and come back and
03:02deal with git later.
03:03But if you really are just changing one thing, a lot of times it's better just
03:07do it here and let Git go ahead and add it to the staging index for you.
03:12Now, I said moving was the same process, we don't have anywhere that we can
03:15actually move things to yet.
03:17Let's create a new folder here, and let's call this first_directory, and let's
03:23move our third file into that directory.
03:26So let's do git move, and we're going to do third_file.txt, and we're going to
03:33move it into first_directory/third_file.txt.
03:39Now, we can rename it at the same time, because like I said, move and rename are
03:43basically the same thing, and now it's moved it there, git status, and you can
03:47see that it tells us that it's been renamed, but the rename was actually moving
03:52it to this new location.
03:53So like I said, move and rename are synonymous, most of the time it's better to
03:57do your moving and renaming from inside of Git instead of from the file system.
04:02Let's go ahead last of all, and let's commit those, commit, and let's say
04:07Reorganized file structure by moving files. There we are.
04:16And you can see that it lists off those renames there, the git status shows us
04:20that our working directory is clean, and our working directory is now the same
04:24state as our repository.
Collapse this transcript
6. Using Git with a Real Project
Introducing the Explore California web site
00:00In the last chapter we went over the basics of how to track files using Git.
00:04We saw how to add files, how to edit them, how to delete them, how to rename them,
00:09and how to see differences between the files using git diff, and then how to use
00:12git status and git log.
00:14Those commands together probably make up 75% of what you are going to do with Git.
00:20They are the core actions that you are going to repeat over and over and over again.
00:24Now, there is more that we can do, and we are certainly going to go into that to
00:26make sure that you have a rounded out view of how to use Git.
00:29But before we do, I want us to switch from using the sample files that we have
00:32been using so far in our first_git_project and start using something that feels
00:36more like a real project. Hang on to this first_git_project.
00:40It still can function like a sandbox for you, a place where you can go if you
00:43have questions or you want to try things out, you can go there and not do
00:47anything that's destructive to your main files.
00:50But I want us to start working with a real project, and you can use your own
00:53project if you have one.
00:54I am going to use one that's from the exercise files, which is called
00:57explore_california, it's the Explore California web site.
01:00I am going to drag that, with Option held down, into my Documents directory so
01:04that now it exists right alongside my main project.
01:07So inside explore_california we've got a bunch of HTML files, some folders,
01:12those folders contain some things like some CSS and some JavaScripts, but
01:16this is all basic HTML.
01:18In order to get this to work, all you should have to do is drag index.html onto
01:24a browser, or you can go into a browser and locate it that way.
01:27Now, you won't have to put these files in any kind of special web directory
01:31or anything like that, because they are just basic HTML files, our browser can render them.
01:35We don't first have to go through a web server like we would if we had PHP or
01:38Ruby on Rails files.
01:41In the rest of this chapter we are going to get familiar with this project, we
01:43are going to initialize it as git repo and see how we can make some edits and
01:46commits that might be like the kinds of edits and commits that one would make in
01:49the real world, and then we'll go on with learning more of the features of Git.
01:53This will allow you to practice some of the techniques that we learned in the
01:55last chapter while giving you some real world exposure to how we would use Git,
02:00and then we can go on to learning more features in Git.
Collapse this transcript
Initializing Git
00:00In this movie we are going to use Git to start tracking changes inside our
00:04explore_california project.
00:05Now, the project already has a number of files in it, but Git is not being used
00:09to track them right now, right now Git does not have any knowledge about them,
00:13there is no repository established to keep track of these files, it's just a set
00:17of files at the moment.
00:19To bring Git into play, we need to switch to the directory.
00:22Now, you can see I am in first_git_project, I'll go backwards a directory, and
00:27you can see here's the explore_california project.
00:29And I am going to go inside that folder, and let's just go ahead and take a
00:34look at the listing.
00:35You will notice that it doesn't have a .git folder up here, it does have
00:39.DS_Store, ignore that, that's just a small file that the Macintosh uses to keep
00:43track of some basic file information.
00:45We can also do git status, and you will see that it comes up and says, oops,
00:49this is not a Git repository or any of the parent directory, so it actually goes
00:53up and tries all the parent directories above it to the top of the hard drive
00:55looking for that .git folder, and it said, nope, couldn't find it anywhere, so
00:59this must not be a Git repository.
01:02We remember how to initialize repository, right? It's git init, and once we do
01:06that, now we have this .git file inside our project directory, and that's where
01:12all of the tracking information about these files is going to be.
01:15Now if we do git status, you can see that it comes up and tells us about all the
01:19untracked files that are in there.
01:21Before we add those to it, let's first do a git log and just see what that does.
01:26Git log comes up and says oops, the HEAD doesn't point to anywhere useful yet,
01:30that's basically what it's telling us that HEAD isn't pointing anywhere
01:33useful, and it's trying to find the HEAD because remember the HEAD points to the last commit.
01:38Well, there hasn't been a commit yet, so HEAD hasn't been established, and that
01:42really just happens right when you first initialize your project.
01:45Once we make our first commit, then it will all be there.
01:48So to make our commit, we'll do git add, and we'll do the entire directory,
01:52git add everything that we've got using that dot, everything that's in this current directory.
01:56git status will show us all of those things, you can see it's a whole lot of
02:01stuff, that's all going in there, all these new files.
02:03Typically if you're first starting with a new project, and you've got existing
02:07files, this is what it's going to look like and typically you also just do get
02:11commit -m, and you can just call it Initial commit.
02:16So there it is it created a whole bunch of files.
02:20You can scroll up if you want to see the sum total of what it did, 69 files
02:24changed, and it gave us a commit now, so now we have git log shows us something
02:28useful that shows us our Initial commit.
02:30Before we move onto making changes, I just want to make sure that one thing is
02:33super clear to you, which is that the explore_california repository and the
02:38first_git_project repository are completely separate.
02:41Remember, all the repository information is stored in that .git folder at the
02:45top level of those two directories, so the two are completely separate.
02:49So here we have git log for what's inside the explore_california project.
02:53If I go backwards and go into my first_git_project, do git log there, you can
02:57see all the things that are in that project.
02:59Go back into explore_california, and I'll do git log again, and you can see
03:05that it is just that Initial commit.
03:07So that may have been obvious to you, but I just want to make sure that's super
03:11clear that the two are completely separate, and that you can have as many Git
03:15repositories as you like on your computer.
03:17So if you're working with 20 different web sites, you can have 20 different
03:20folders and each one can be its own Git repository, and it's no big deal to just
03:24move between them and each one contains the information about what has changed
03:28in that repository, that is absolutely common.
03:30Just don't make the mistake of thinking that anything that you do in one
03:33project has something to do with what happens inside the other repository, they are each separate.
03:37Now that we have told Git that it should start tracking files, and we have given
03:41it its first set of files that it should track from, we are ready to start
03:45making edits to our project, and that's what we'll do in the next movie.
Collapse this transcript
Editing the support phone number
00:00In this movie we are going to start making edits to our explore_california web site,
00:04to get a feel for what real world edits might look like.
00:06So to start us off, we are going to edit the 24-hour support contact number.
00:11We come down here to the bottom of the page.
00:13You will see at the Contact, this is 24 hour support number at the bottom, and
00:17it's listed as being 4315. We are going to change that to 4314.
00:20Now it's at the bottom of every single HTML page in the footer.
00:24It's also listed in the text sometimes like on the Contact page.
00:28It's listed here on a paragraph of text. So we are going to want to change all of those.
00:33So you could go in and open up each one those files and change them one by one.
00:37I am going to use TextMate to edit the project altogether.
00:40So I can drive the folder on top of TextMate, it opens it up as a project, and
00:44the big advantage to doing that is then I can do Find in Project and find all
00:49occurrences of 4315 in the entire project.
00:51Double-check them, make sure that they are all relevant, that none of them are
00:55something besides the support phone number, and then I can change them all to
00:584314 using Replace All.
01:01Now it's changed them all, but it hasn't saved those changes to disk yet.
01:04I have to use Save All to do that.
01:06Now all those changes are saved in my working directory.
01:10Not in a staging index, not in the repository, just in my working directory.
01:14If we come back over here, and we do git status, you will see that it lists now
01:19all those files as having been changed.
01:21Now before we commit them I want to show you something, which is we saw how
01:24we could use git diff before, and we saw we could use it with single file like contact.html.
01:29Let's take a look at that diff. Notice a couple of things.
01:33Notice first of all that it gives us two chunks that were changed here.
01:38One chunk up above, one below.
01:40This one is showing us starting at line 71, seven lines.
01:44So here is line 71, countdown seven lines.
01:47Now you will actually count eight lines, because this line is in the minus
01:51section, while this line is in the plus section and the plus section is showing
01:56me from line 71, seven lines.
01:57So this line here that's changed is showing twice.
02:02Seven lines one of them is repeated twice making eight lines total.
02:05Same thing down here.
02:06Now these line numbers are very useful, because then we can look over here in
02:10our contact file, and we can scroll down until we get to line 71, and that's
02:15where our change is, or the context for our change is, if you are on this page.
02:19If you're currently on a tour, is the text that actually changed, that's right here.
02:24If you're on a tour.
02:26So here is the support phone number that's the bit of text that was changed.
02:29Now notice that doesn't show that bit of text is way off over here on the side.
02:33If I keep stretching out there, it will try and expand until I get there, but
02:37it's such a long line that it won't get there.
02:40It's a good reason to try and keep your line short if you can and for HTML it
02:44doesn't really care about the line breaks. It's not whitespace dependent.
02:47However, the another trick that you can do is that what we are looking at here
02:51is actually being run through what's called a pager.
02:53It's showing me pages of results and in fact if I scroll this up like this, you
02:58can see that it's now asking me.
03:00Here, it's prompting me, waiting for me to hit the spacebar to show me the rest
03:04of the results, and I can use F and B to go forwards and backwards through those results.
03:08What this is the less pager that's built into UNIX.
03:13So I'm using the less pager to see these results.
03:16The less pager has a feature where I can either start it up using the -R
03:20command, and you can set that in your global configuration or while I'm inside
03:25of it I can press the minus key and then Shift+S and then hit Return, and it
03:31will fold those long lines.
03:33So to wrap it around instead of having the lines be truncated.
03:36And if I want to switch it back -S and Return chops the long lines instead.
03:41Now as I said that is something you can use a configuration for in your config
03:46file if you wanted to always be that way.
03:48So it's really up to you and how you like to work.
03:51Notice here we can see the change between these lines really easily, 4315
03:55got changed to 4314. I am going to hit Quit.
03:58We are going to do the git diff again just like we did before, but this time I
04:03am going to add in an option here which is color-words.
04:07So git diff with the option color-words contact.html.
04:12Now notice that it comes up, and it gives me that same information, but instead
04:16of having two separate lines it gave me a different format, and it put the
04:20change here side by side.
04:21This is just one of many options that you can use with a diff to get it to show
04:26you information in a different way.
04:27So if you prefer instead of saying one line above the other, you prefer having
04:31it actually color the output for you so you can see the difference between them,
04:35you can use the color-words option. So we have seen enough of that.
04:38We are ready to go back here, and we are ready to make our commit.
04:40Right now, these are in our working directory, we haven't staged them yet.
04:45We know that we would use git add, and then we could do them one at a time or we
04:50could just use git add. and put all of them into the index.
04:53I want to instead show you another way to do it. It's a shortcut.
04:57From here, we can do git commit with the -a option, that's telling it to add it
05:02to the staging index and then commit it. All in one big move.
05:06So it's going to add it and commit it and allow us to skip that process of
05:10actually having to say add them one by one.
05:12Now there are couples of big caveats to this, and you need to be careful about them.
05:17The first is that, of course, this grabs everything that is in your working directory.
05:22So if there were some things that you didn't want to include in the change,
05:25they're going to get pushed up there as well.
05:27The second caveat, is that files that are not tracked, or files that are being
05:31deleted, do not get included in this.
05:34So it works well for modifications, but for new files and deleted files
05:38it doesn't work well.
05:40In this case, I'm only making modifications I know that as soon as I finish
05:45doing the add of everything, I am going to commit it all,
05:48it's okay to do the shortcut. And then I am going to use the -am option after
05:52it is well to provide the message, and I am going to say, Changed 24 hour
05:57support number to 4314. So there we are.
06:02I have committed my change, git status, you can see that my working directory is clean.
06:07It went right from my working directory, right on past the staging index, and
06:11into the repository, git log will show us that second commit.
06:16So again you should use that -a option very carefully.
Collapse this transcript
Editing the backpack file name and links
00:00In this movie we're going to make another edit to the Explore California site, and
00:04that is that we're going to rename one of our HTML files.
00:07From the root of the web site if you go to the menu for Tours, you open that up,
00:12scroll down the first tour here, it's called Backpack Cal.
00:14It has a nice little graphics are called Backpack Cal.
00:17The learn more link will take you to information about it, Backpack Cal, but
00:21notice that the name of the file up here is tour_detail_backpack, and that's it.
00:25It doesn't say Backpack Cal.
00:26And I'm thinking that there maybe a lot of things that are
00:31tour_detail_backpack in the future. We could have lots of backpacking adventures.
00:35We need to be more specific.
00:36So we're going to change this file name to be tour_detail_backpack_cal so that
00:40it matches what's on the rest of the page.
00:42So that's going to involve renaming the file and also changing some content on
00:46some of the pages where we have links to this file.
00:49The very common sort of task that one might do within an HTML web site.
00:52So from inside my project I could just rename this file.
00:56I could go into the operating system and rename the file, but I think it's
01:00better to do the rename from inside git so there's no changes to my working
01:04directory right now.
01:05Let's do the rename git move, and it's going to be inside the tours directory
01:11and the tour_detail_backpack.html that's its current name.
01:16We're going to move it to tours/tour_ detail_backpack_cal.html. So that moved it.
01:24If we take a look here we see that it's moved. In the project it shows it's moved.
01:28If we were to go to it in the finder we'd see it was moved as well, and if we do
01:32git status, it now shows it in the staged items that the item has been renamed.
01:38So now we need to track down all the link references to this HTML page.
01:42So we'll do that with a global search I'll look for everything that was
01:46_backpack.html _backpack.html.
01:50You see came up with three instances I'm going to click on those three instances
01:54so that they open up for me and those are the ones I'm going to change.
01:58So here's the first one backpack_cal, save it, and close it.
02:01This one is right backpack_cal, save it, close, and the last one save it and close it.
02:06So I made those three changes.
02:08If we do our global search for backpack. html we don't find any, and if we do a
02:12search for backpack_cal, we see that all three are there.
02:15So now we've changed our working directory, git status.
02:19So our working directory has those three changes in it.
02:22Our staging index has the rename in it.
02:25Now I want to make sure that something is super clear to you, which is, that if we
02:29go right now without committing anything to our repository, if we go right now
02:33to Firefox, and we take a look at this let's go to the top-level Explore
02:36California, Tours here's the tour.
02:40The learn more link, notice where it's going to take me.
02:43You can see it at the very bottom of my screen, or I'll go ahead and go there,
02:47and you can see it up here. It takes me to backpack_cal.
02:50It changed the link already. Just make sure that that super clear to you.
02:54Our working directory is what we're working with.
02:56So that's what we're looking at in the browser.
02:58The browser has nothing to do with what's in the repository or what's in staging directory.
03:02It's about what's on the file system.
03:04So that is our working directory as we change files we see them right away in the browser.
03:10So we change them we've look at them again, we see if they're right.
03:13If you're doing something besides web, if you're compiling code, you can compile
03:17your code to see if it runs, but once you've got exactly like you want you want,
03:21maybe you're restyling the page or something and everything looks just right,
03:24then we can come over to git and say, okay git, I've now got my working
03:28directory in a state that's ready to commit, I'm ready to commit it.
03:31I just want to make sure that you realize that your working directory is what
03:35you're working with all the time. That's what you're seeing.
03:37What's happening in the staging and the repository are just for git to use,
03:42they're not something that you can work with from your browser or compile and any thing like that.
03:46You've to bring changes into your working directory in order be able to work with them.
03:50So now we're ready to make commits, let's go ahead and do git add, and let's add tours.html.
03:56So now it added tours to the list.
03:58We also want to add these two files that we made changes to.
04:02They're both in the same directory, the tours directory.
04:05We can actually just say git add tours and then usually put the slash after
04:09it to make sure it knows it's a directory and everything that's inside of it,
04:13you also put the asterisk after it, which lets it know everything inside of
04:16is a wildcard, but you don't have to.
04:18Add everything in the tours directory to the staging area, git status.
04:24Let me clear my screen so you can see it better, and now we see those things there.
04:28Notice that we don't see separate entries for the rename that we did and for the
04:34changes that we've made from one file to other. Is it peculiar?
04:38I needed you to be aware of.
04:40We made changes to the file detail_backpack, we've changed the URL in it.
04:44But git reports it to us as just being a rename, in this case.
04:49Let's say that we're about ready to do our commit and suddenly we get a phone
04:53call from the client and the client tells us that we've need to change something
04:56on the Contact page that on the account page there are all these contractions.
05:00So we want take out all those contractions.
05:02So let's switch over here while we've got the client on the phone, we go ahead
05:06and just make sure that we've got it all straight, and we say if you are on this
05:11page, we are guessing you have got something to say! Drop us a line.
05:17If you are looking for our seasonal tours--take out that extra space--and (we do
05:23not publish these for everyone!), but we will be sure to throw in some cool
05:28discounts if you are currently on a tour.
05:32So there we've taken out all the contractions and turn them into--oops, I missed
05:35one here, let us know what you are thinking. So we've got them all now.
05:39I'm going to save that. We come back over here to git, git status.
05:43Now we've got this additional change here that we've made to the Contact page.
05:47So we get off the phone with the client, we've now made the changes, and we're
05:51ready to deal with it in git.
05:53The best practice here is to deal with these as two separate commits.
05:56You wouldn't want to add contact into the commit that you are making about
06:00tours, because the one about tours is about something different, and we want to
06:04try and make our commits related to each other.
06:06There's no need for us to break those top three files down any further.
06:10They're all related, they are all one conceptual change that we're making at that time.
06:14But the conceptual change that we're making to contact is a different one.
06:17So let's make them as two different commits.
06:19So we're going to say git commit -m and the first commit is going to be, "Renamed
06:27Backpack Cal file for clarity".
06:32And then right afterwards we will do git commit--and remember I told you the
06:37shortcut, git commit -a with an m after it--and then we'll say, "Removed
06:43contractions from contact page text", and now we've made that one git status.
06:51Our working directory is clean, git log, and we can see both of our commits that we've made.
06:56Now it's very clear what each one of those commits is doing, the goal that each
07:00one is trying to achieve.
07:02It takes practice to learn how to group files together and to write good commits for them.
07:06But you'll get better at it over time.
Collapse this transcript
7. Undoing Changes
Undoing working directory changes
00:00In this chapter we're going to talk about how you can undo changes in Git, and
00:04that can be changes that you make to your working directory, changes that you've
00:08staged into the staging index, or even changes that you've actually committed
00:12all the way to the repository.
00:14It's very common that you say, "Oh you know what? I want to undo what I just did,"
00:18and Git can help us do that.
00:20In this movie we're going to start by looking at how we can undo changes that
00:24we've made to our working directory.
00:26So let's say, for example, that we're working with our project, and inside
00:30Export California index page we open that up, and this whole site navigation
00:36here, where do you want to go, all of this--scroll down until I get to the
00:41bottom of it, here it is-- the bottom of that div, we delete.
00:45Maybe it was on purpose, because we we're thinking about to deleting it, or maybe
00:49was just an accident. We didn't mean to delete it.
00:51But we save the change to the file, and then we close it.
00:54Now that file has been changed.
00:56If we go to Firefox, and we open it up, we reload the page, the
01:00navigation disappears. Well, that's not what we wanted.
01:03That was a mistake. So how do we get that back?
01:06If we go to Git, and we say git status, it shows us that the file has been modified.
01:10If we do git diff, it comes up and it tells us what the change was.
01:15The change is that all of this text has been removed.
01:17You see all of the minuses next to it.
01:20So what we want is we want the repository version back.
01:23We want the version that Git has saved for us to be restored.
01:28It's using that version to compare when it does the diff.
01:30What we're going to do say, "Git, go back to the repository, get that version, and
01:35check it out for me and replace what I have in my working directory with it."
01:39And to do that, we use the git checkout command. You could say git checkout index.html.
01:48I think in a lot of cases that will work.
01:50However, the thing about checkout is that it's used for more than one purpose.
01:55It's also used for working with branches.
01:57Because what checkout does is go to the repository, get the named thing that
02:02I've gave you, and make my working directory look like that.
02:06That's what it does.
02:07So if that named thing is a branch, it brings the branch down. If that named
02:12thing is the file, it brings the file down.
02:14Imagine for a moment that we wanted to bring down this resources folder.
02:19So we say git checkout resources.
02:22Well, that's fine, but what if we also have a branch named resources?
02:26Then it's hard for Git to tell which one we need and in that case it actually
02:29would give us the branch resources instead of the folder resources.
02:34So as a result, it's a good practice when we're not trying to checkout a branch
02:39to put dash--dash, followed by index.html that says stay on the current branch.
02:44That bare double dash is just there to indicate that we're not checking
02:49out a new branch, we're just talking about a file in the current branch.
02:54We'll talk more about switching branches later, and we won't use the double dash in that case.
02:59But here we want to use it to say stay on the same branch, go get this file, I
03:03don't care what's in my working directory, I want to make my working directory
03:07index.html file look like what the repository has.
03:11So let's hit Return.
03:13You can see it changed there briefly in the background as this file went away
03:16and then came back again.
03:18Before we even go look at the file, let's just come back here and reload the web page.
03:22Sure enough, our working directory now has the menu again.
03:25The menu shows up, and if we pop back over here to Git, git status, the working
03:31directory is clean again.
03:32It when I got that version and completely throughout our working directory changes.
03:37That's all there is.
03:38Git checkout with a double dash and then the file or the directory that we
03:43wanted to pull down from the repository will blow away the changes and restore
03:47them back to what we had in the repository.
Collapse this transcript
Unstaging files
00:00In the last movie we saw how to undo changes to our working directory.
00:03In this movie we're going to see how to undo changes to our staging index or in
00:07other words to un-stage things that we've staged there.
00:10Before we can get started doing that, we need to add something to our staging area.
00:15So let's open up the resources document, resources.html, and if we scroll
00:20down here, there's a list of items that it recommends that we bring on an outdoor trip.
00:25So here it is, Comfortable hiking shoes, Hat, et cetera.
00:28I'm just going to take Sunglasses and Sunscreen and cut those and move them up
00:32underneath Hat, because those are pretty important items.
00:34So I'm going to put them near the top. Save our change, close it.
00:39Now of course, that changes in our working directory, not staged yet.
00:43So if we want to stage it we know that we do add and then resources.html. Now git status.
00:50We can see this that change has been staged there.
00:53What we want to do now is unstage that change. We don't want lose the change.
00:57We want this change to still be in our working directory.
01:00The time when you'll most often use this is if you're trying to put together a commit.
01:05Let's say you've got five or six different files of changes that have been made,
01:08and you're trying to assemble them into a commit in the staging area.
01:12But then there's that extra file that you accidentally add.
01:15So I need to unstage that one file, leave all the other ones in there, and then
01:19I'll be ready to make my commit.
01:21That's the real world application of how you would use this.
01:25How do we unstage it?
01:26Well, it gives us a little hint here in the status.
01:29It says (use "git reset HEAD <file >..." to unstage).
01:33So be sure enough, git reset and then HEAD followed by resources.html.
01:40What we're telling it is go look at the HEAD pointer.
01:44The HEAD pointer points to the last commit of the tip of the current
01:48branch, which is master. That's our current branch.
01:51Go look at that last commit and reset yourself to be the same as what that has.
01:56Very similar to what checkout did.
01:58Checkout went and checked out that file from the Repo.
02:00Here we're resetting the index to be the same as that. So we hit Return.
02:05It says Unstaged changes after the reset:
02:08is a modification--that's what the M is for--to resources.html.
02:13If we do git status, it tells us something similar.
02:16It says that now in our working directory change is not staged.
02:21We have a modified file resources.html.
02:24If we want to add it to our staging directory, we use git add to put it there. So it's that easy.
02:29If you put something into the staging area that you don't want there, you
02:33can take it out by using git reset HEAD, and the status message will help you remember that.
Collapse this transcript
Amending commits
00:00In the first movie of this chapter we saw how to undo changes to the working directory.
00:05In the second movie we saw how to undo changes that we've made to the staging index.
00:09Well, what about undoing changes that we've made to the repository itself,
00:13undoing commits that we've made? Well, that becomes a lot trickier.
00:18If you remember when we're talking about how Git refers to commits, and we talked
00:22about that it generates a hash value for all of the data that's put in there.
00:27The snapshot of all the changes as well as the information about it, the parent,
00:32the author, the message, et cetera. All that metadata all goes together into the
00:36algorithm to generate its hash.
00:40If we change any of that information, well then the hash changes.
00:43That's part of the built-in security and data integrity of Git is that nothing
00:48can change in the history.
00:49We are guaranteed that everything must be the same.
00:52Well, that makes it hard to go back and edit information in those commits,
00:57because what we're doing is messing with the data integrity of the Git
01:01repository, and Git doesn't want us to do that. Let me show an example of what I mean.
01:06Let's say that we wanted to do change something about the commit that's
01:09represented with snapshot B, the one right in the middle. So 38e73d6134...
01:15so on is the shot that it came up with when we first made that commit.
01:19So if we make a change to this, even if we just change the commit message, it's
01:24going to change that SHA to be something different, and if that SHA becomes
01:28something different, well, now the parent of snapshot C will need to be changed
01:34as well, because it needs to point to something different.
01:37And if we change the parent of snapshot C, well then when we run it through the
01:42algorithm it's going to come up with a different SHA as well.
01:46So all the way down the chain every single Git object will have to be changed
01:51just because we've made a change earlier down the line.
01:54Well, if completely broken the integrity of the data that's in Git.
01:58So Git doesn't want us to do that.
02:00However, it is possible for us just to change the last commit, because
02:06nothing depends on it yet.
02:08So the most recent commit the commit that HEAD points to we do have the ability to edit.
02:13Once we've tacked another on to the end of that we can't edit in anymore, but
02:17the one at the end is still editable, and we can do that using the amend option.
02:23So let's say that we have this change for resources that's sitting in our
02:27working directory, the change that we've made in the last movie.
02:29We're going to go ahead, and we're going to add that to the repository.
02:33So we'll git add resources.html that adds it to the staging area.
02:39Now we're going to go ahead and commit it, and we're going to say commit with
02:44the message "Rearrange the items to bring on a trip".
02:51So now we've now committed that. We do git log. We'll see that it's there. It's the top one.
02:58It's the commit that HEAD is pointing to right now.
03:00The most recent commit.
03:02What if we say, "Oh, that's not actually what we wanted to do.
03:05We wanted it to make a change."
03:07Now this change could be a change to the substance of the commit.
03:10Let's say that we want to go back in the resources, and we say, "Oh, you know what?
03:14Actually, I want to put Insect repellent.
03:16I want to move that up right below the Sunscreen."
03:19So we'll paste that in, we'll save it.
03:21Now if we do git status, you can see that we have a change to our resources
03:27again, but we didn't have that change in our previous commit.
03:31If what we wanted to do is add it to that commit, we can amend the
03:36commit by putting this change into our staging directory, add resources.html, there it is.
03:41Now it's in our staging directory, and let's amend our commit by making
03:46that change, git commit --amend, and then we're once again going to provide a message.
03:54Let's use that same message, "Rearrange the items to bring on a trip".
03:58I'll copy that and paste it, and now it amended it. Let's take a look.
04:02Git log, I just have one item which is here rearrange the items to bring on a trip.
04:08Now you can also use it if you just want to change the commit message.
04:12So we say that's a terrible message.
04:14I didn't stage anything into my index, but I want to change the message,
04:17rearrange the items to bring on a trip, to bring on an outdoor trip, change it again, git status.
04:26Nothing in my working directory, git log, and there's items to bring in on an outdoor trip.
04:32Now notice each one of these times that we do this that we make those edits, the SHA changes.
04:36You can see that every time.
04:37Even if we just change the message, the dates that we've made the
04:40commit, everything changes, and so the SHA changes as well.
04:44That's why we only have the ability to amend the most recent commit, the one that HEAD points to.
Collapse this transcript
Retrieving old versions
00:00In the previous movie we saw how we can use the amend option with commit in
00:04order to edit our very last commit, the commit that the HEAD still points to.
00:09We also saw how it's difficult to amend older commits, because that would
00:14violate the data integrity, which is an important feature of Git.
00:18Instead, if we need to make changes to those older commits, the best advice is
00:22to make new commits, commits that undo what was done in those older commits.
00:26Not only does it maintain the data integrity of Git, but then the log file also
00:32accurately reflects the changes that were made over time, and it shows that a
00:361.1 change was made and then several commits later another commit was made.
00:40That information might actually have some importance, especially if the commits
00:44in between played off of those changes in any way.
00:47Now, what it doesn't do is allow us to hide our mistakes.
00:50Instead, you'll just have to record the mistake you made and then record the
00:54fix that goes with it.
00:57In order to make new commits that undo changes, there's a number of different
01:00ways that we could do it, one would be we could simply manually make those
01:04changes just like we did the first time and then commit the result.
01:07But I want to show you another way that we can do it that's a little bit faster too.
01:11Let's take a look at our git log, and let's take a look at this last commit that we made.
01:16Now we could use amend to just edit this commit.
01:19But this is the one where we change our resources.html file.
01:24We rearrange the items that we're going to list there.
01:26Let's say we made two or three more commit since then and we wanted to go back
01:31and we wanted to rework this file and get it back to its old state.
01:34What we can do is we can check out this file, check out the old version of
01:39resources.html from before you made that change.
01:41So, if the change was made in this commit, then the commit that has the version
01:47previous to that is this version, and probably all the versions that are before.
01:51But we'll take the one that's immediately before.
01:54And what I'm going to do is I'm going to copy part of this S-H-A at the top.
01:58Now, you could take the whole thing, but it's not necessary, these numbers are
02:02unique enough that you can usually just grab the first 10 or so characters and
02:06copy those and use those for a reference.
02:08And then I'm going to say git checkout, I'm going to use that reference to
02:12the commit that I want followed by a dash, dash, that's that bare double dash
02:17that we used before with checkout to let it know that we're not talking about
02:20a branch, we mean the current branch, and then the file that I mean, resources.html.
02:27So now I've told it to check that out.
02:29Let's take a look at git status, and you'll see that it moved it into my index.
02:34So I've checked it out and here it is ready to be committed.
02:37Now, this behavior is slightly different. Before when I did a check out, it put
02:41up my working directory. Here it went ahead and put up my staging index.
02:45When you check it out from our particular revision, it puts it into your staging area.
02:50Now, if we do git diff --staged, we can see the comparison, and we can see that
02:58this is the old file, the old version, and if we were to commit it, it would revert those changes.
03:03It would change it so that sunglasses, sunscreen, insect repellent move from the
03:06top back down to the bottom where they were originally.
03:10So there it is ready to be committed, I can just do a regular commit now, and it
03:14will undo that change that I made previously.
03:17It's a good habit when you're reverting a particular commit to actually refer to
03:21the SHA for that commit.
03:23So, it would be a good idea to take part of the SHA and copy it and then say
03:28this commit reverts commit, and give that SHA, so it's a reference.
03:33So people can look it up and figure out what you were trying to revert.
03:36We could go ahead and commit that, but I'm going to instead bring up the status again.
03:41Let's do git reset HEAD on resources.html.
03:47That will put it back in our working directory, and then we'll do git check out --
03:52resources.html, and that now removes it from our working directory so that now
03:58our working directory is clean.
04:00And the reason I don't want to do it here is because in the next movie, I'm
04:03going to show you how we can use a command called git revert to do something very similar.
Collapse this transcript
Reverting a commit
00:00In the last movie, we saw how we could amend older commits by crafting a new
00:05commit that would undo the changes from the previous commit, and we talked about
00:10how we could do that manually by just making the changes to the files or by
00:14checking out a previous version of the file and then assembling that together
00:18so we can do a commit.
00:19But Git also gives us a helpful way when we really want to just undo the changes
00:23for a commit completely and totally, we can use the Revert command.
00:27So let's take a look with git log.
00:29Here is the commit that we're talking about, this first one, Rearrange the items
00:35to bring on an outdoor trip.
00:36What the Revert command will do is it will take all of the changes that were
00:41there, and it will flip them around. It will do the exact opposite of those changes.
00:46So, anything that was added will be deleted, anything that was deleted will be
00:49added back in again, and anything that was modified will be changed back to its previous state.
00:55It's going to be a complete mirror image of this commit.
00:58So, in order to use it, it's real simple.
01:01We just have to grab part of the reference to it. Remember, we don't need the
01:05whole thing. I'm just going to copy it, and let's use git revert, and then I'm
01:10going to put in that S-H-A.
01:12Now, this is going to do it all in one step for us.
01:15It's not going to assemble the commit and then wait for us, it's going to go
01:19ahead and make that commit.
01:20So, I'm going to hit Return, it's going to pop up with the chance for me to edit
01:25the commit message, and it's going to do that in TextMate for me.
01:28So it pops up, and it says, all right, if you want to edit this message before I
01:32commit it, go ahead and do it now.
01:34Now, I'm happy with the default that it gives me.
01:37Just lines 1, 2, and 3 are going to be part of commit, all that commented out
01:41stuff is going to get ignored, and not be part of my commit message.
01:45So, I'm just going to say Save and Close, and then Git will go ahead and do its thing.
01:49It went ahead and made the complete commit.
01:51So, if I do git status, you can see my working directory is still clean, but
01:55git log, and you can see that it did make this new commit here which reverts that old commit.
02:00And sure enough if we go and open up resources and take a peek at it, you'll see
02:04that down here it's now put insect repellent, sunglasses, and sunscreen back at the bottom of the list.
02:10Now, you can pass in the -in option with revert, and then it won't actually
02:16do the commit, it will just stage it and then wait for you to actually do the commit yourself.
02:20It will give you the chance to write your own message for it and also make any
02:24other modifications you might need to make.
02:26Now, git revert works really well when things are simple.
02:29We're just making a simple change from A to B, and then we're going to switch it
02:34back from B back to A.
02:35But what if the changes are really complicated? What if in the meantime other
02:39things have changed? What if files have moved perhaps, things have been renamed?
02:44It might get little harder to make an exact mirror image commit.
02:48Git is going to use a more complex set of rules for how to deal with those
02:53changes, and the set of rules it's going to use is what we use for merging.
02:57Merging is a more advanced technique that we'll talk about a little later on,
03:00but if you need to revert something complex, you're essentially going to find
03:03yourself doing a merge between the current branch and the new set of changes
03:09that you're trying to merge into it.
Collapse this transcript
Using reset to undo commits
00:00In this movie, we're going to learn about a very powerful tool in Git that
00:04allows us to undo multiple commits.
00:07And because it's powerful, it's also very dangerous, so I want to say right off
00:11the bat that you need to use this with extreme caution.
00:14The command that we're going to be using is git reset.
00:17What git reset does is it allows us to specify where the HEAD pointer should point to.
00:23Normally, we just let Git manage the HEAD pointer for us.
00:26We make a commit and Git moves the HEAD pointer to point to that commit, we make
00:30another commit, and it moves the HEAD pointer to point to that commit.
00:33Well, here, we're telling Git, "I want to be in control, I want to move the HEAD
00:38pointer over here, and that's where you're going to start recording from now on,
00:43that's where you're going to start making your commits."
00:45It's a lot like if you think back to the metaphor that I gave you early on about
00:50the cassette tape recorder.
00:51Remember that I said that the HEAD pointer is a lot like the playback and record
00:55head on the tape recorder.
00:56Let's imagine that we've recorded an hour's worth of audio.
00:59If we press Stop, now if we start recording again, of course it starts recording
01:03right there at the end of that hour's worth of audio.
01:05But what if we instead rewind back 10 minutes into the audio?
01:10Now, if we were to press Record, we would record over that last 10 minutes of audio.
01:15It would be very destructive. You can see why git reset is powerful.
01:19It does the exact same thing.
01:21It says let's rewind back to our previous commit, and that's where we're going
01:25to start recording from now on, and we're going to just overwrite whatever came after that.
01:30Git reset always moves the HEAD pointer. That's one thing that it does in every case.
01:35But there are three different options that I want us to look at that we can use
01:39to control some of the other behaviors that it has, and those options are going
01:43to be soft, mixed, and hard.
01:46Soft is going to move the HEAD pointer to the specified commit, and it's not
01:50going to change the staging index, or the working directory at the same time.
01:54It's just going to move the pointer.
01:56It's the safest of all these options, that's why it's called soft.
01:59Just a soft reset, move the pointer and do nothing else.
02:04The result of that, if we've rewound backwards is that our staging index and our
02:08working directory are going to contain the files in their later revised state.
02:13The repository is going to be set back to an earlier version.
02:16So, if we do a diff between the two, it's going to tell us about all those
02:21changes that have happened between the point where the HEAD is pointing, and all
02:25the files that are sitting in our staging index and working directory.
02:28So, that's a soft reset. That's the safest one we can do.
02:32The second one is a mixed reset.
02:34This is in between soft and hard which is why it's called mixed, and it is the default.
02:39What it does is it moves the HEAD pointer to the specified commit, and it also
02:44changes the staging index to match the repository.
02:47It does not change your working directory though.
02:50So, at this point, the staging index and the repository will be set in one
02:53place, our working directory, though, has all those changes that we've made.
02:58All the things that were in later versions of the repository are still in
03:02our working directory. We haven't lost any work.
03:05It's just waiting for us to stage it and then commit it.
03:08And then the last one is the most destructive of all, and that is hard.
03:13A hard reset will not only move the pointer of the repository, but it will make your
03:17staging index and your working directory match that as well.
03:21So that means any changes that came after that commit are completely obliterated.
03:27They don't exist in the repository, the staging index, or the working directory,
03:31they're completely gone. So use this one with caution.
03:34It really is for when things have gone completely wrong, and you really just
03:37want to reset everything back to a specific point in time, and you don't mind
03:42losing whatever came after it.
Collapse this transcript
Demonstrating a soft reset
00:00In this movie, I want to demonstrate a soft reset.
00:04So, here's the commit log. You can see that my most recent commit was reverting
00:08this commit that was right before it.
00:10What if we wanted to undo our version, that is we wanted to get rid of this?
00:14We could revert it and revert the reversion, or what we want to do here is
00:19we want to actually rewind back in time to before I made this reversion back
00:24to this point here. So, this is the reference we're going to use.
00:27We want to rewind the HEAD back to that point so that it records from
00:31there going forward. So, what would that look like?
00:34Well, the first thing is whenever I start working with moving the HEAD pointer
00:38around, I always think it's a good idea to open up a new text file, and let's
00:42just grab the most resent commits here, we can grab the first several, no big
00:46deal, and let's just take those and paste them in here.
00:49So now we always have these commits to refer to. If we need to get back here, we
00:53have that value recorded.
00:54Once we rewind, our log won't show it to us anymore.
00:58I'm just going to take that and put it out of the way for now.
01:02Let's first of all take a look at what the HEAD pointer points at now, git/HEAD.
01:06It points to refs/heads/master, and we saw before that, that's also a file,
01:10refs/heads/master, and it will always point to that file.
01:15So, if we ask for this, as long as we're on the master branch, it will tell us
01:20this answer, the real SHA that we're looking for is contained in this file.
01:23So, right now it points to that 5c86ebd.
01:27If we take a look here, you can see 5c86ebd is in fact the most recent commit.
01:33So now what we want to do is a soft reset, git reset --soft, and we want to
01:41use that second commit. Again, let's just pull it up.
01:44We're going to go back to this one here.
01:46I'm going to just copy that, and there we go, we'll paste it in here.
01:50Now, it's going to move the HEAD pointer back to that point in time.
01:54It didn't give me any kind of message there, but if I now do that same look at
02:00what it points to, refs/heads/ master, you can see it's changed.
02:05Now, it points to this other commit.
02:07And if I do git log, you'll see that the most recent commit looks like it's that one, the da3866.
02:16Now, here is what git soft does.
02:19If we do git status, you'll see that we have in our working directory and in our
02:25staging area, we have resources.html still in its most recent state, not the
02:32change that's in the Repo here, but the changes that we made since then.
02:36This is the reverted file.
02:38Let's take a look at the contents to see, git diff --staged, and you can see
02:44this is the change we made that reverted.
02:46So it took sunglasses, sunscreen, insect repellent and moved them back to the bottom.
02:51So, it did not destructively get rid of our changes.
02:54Our changes are still here in the staging index and in the working directory.
02:58We are now ready to record a new commit if we want to, and it would just record
03:02it over essentially where that other commit was before, a lot like if we had our
03:08tape recorder, and I was saying we recorded back, recorded over the last
03:1110 minutes of audio again.
03:12We are essentially forgetting about that old stuff that we were doing, and
03:16making new commits from here on out. Or what we can do is we can just go back to
03:21this most recent commit and change the HEAD pointer to point back to that, get
03:25reset --soft, and put the most recent one in there.
03:31Now, if we do git log, now our version has come back again, git status, there
03:37is nothing to commit. Our working directory is clean.
03:39So all we did was basically take the HEAD pointer from pointing at this one,
03:43moved it so it's pointing at this one, and then moved it back pointing to that one again.
03:47You can see why git reset with the soft option is the safest and least
03:51destructive, because it didn't actually remove anything at all.
03:55All it did was moved the HEAD pointer that other commit was still there, and
03:59all of our work was still maintained in the staging index and in our working directory.
04:03We didn't lose anything.
04:05In the next movie let's compare this to the mixed reset.
Collapse this transcript
Demonstrating a mixed reset
00:00In the last movie we saw that the soft reset moved the HEAD pointer but didn't
00:05do anything else. It left our staging index and our working directory alone.
00:09Now we're going to look at a mixed reset.
00:12Mixed reset works exactly the same as the soft reset with one additional
00:16thing, which is that it makes the staging index look the same as what's in the repository.
00:22So as I noted in the last movie, it's always a good idea when you're working
00:25with resets to just grab those last few commits, copy them, and paste them into
00:30a new document, so we have them to refer to if we need to get back here later.
00:36Let's make the same commit, let's go back to the same point in time, but this
00:40time let's use a mixed reset instead of the soft reset.
00:44We're not going to look at the actual file for refs/heads/master, we did that
00:48in the previous movie, we know that the HEAD pointer moves in each of these cases now.
00:53So let's copy this, and let's do git reset --mixed, and then our new SHA, that's going to reference it.
01:01Git reset -mixed, it comes up afterwards, and it says unstaged changes after
01:07reset, that's what it normally tells us when we unstage something.
01:12So let's take a look, git status, and you can see changes not staged for
01:17commit, meaning changes that are in my working directory includes modifications to resources.html.
01:25So if we do git diff, we can see what those changes are, and we can see that
01:29it is our reversion, where we moved sunglasses, sunscreen, insect repellent,
01:33back down to the bottom.
01:35So again, it did the exact same thing as git soft did, the only difference here
01:40is how our staging index looks.
01:43The changes that we had subsequently made are not gone, they're just only in our working directory.
01:48They're not in two places, they're just in one place.
01:50So it's almost as safe as the soft reset, because we do still have these changes here.
01:54They're ready for us to restage them and then recommit them.
01:58Now, we can also just take a look at the log real quick to see that in fact it
02:02did roll us back to this commit, and so that's where it will start recording new
02:07commits going forward. We've essentially just undone that commit.
02:11So if you find that you've made two or three commits, and then you think, you know what?
02:15I wish I could just go back and redo those commits again, this is
02:19what does it for you. It allows you to rewind back, let's say, three commits,
02:23all of those changes are still in your working directory, now you can go and
02:27make those commits over again.
02:28Now, the one thing that I did want to point out to you about reset is that if I
02:33do git add all, you can see that I've got the file in my staging directory.
02:38Notice that the command here is a reset command. That is what it's asking us to
02:43do if we want to unstage things.
02:45Git reset from the HEAD so that's the commit that it's using, wherever the
02:50HEAD is pointing now--instead of using the SHA, it's using HEAD--and then tell
02:56it which file, we're not telling it to move the pointer and then make our
03:01staging directory look the same, we're telling it just to go get the file that
03:05is where the HEAD is at.
03:06So the HEAD doesn't move, the HEAD stays in exactly the same place that it's in
03:10now, but it also then pulls down just this one file from the HEAD to make the
03:16staging directory match it.
03:18So that's another instance where we're using git reset that might not be
03:22immediately obvious that it's doing the exact same thing.
03:25So there it is, stage changes after reset, we've got it back in our working
03:31directory just like we did when we moved the HEAD pointer and made our staging
03:35directory look the same.
03:36So doing a git reset is the same thing as doing git reset mixed.
03:40Now just like before, because we haven't recorded anymore commits yet, that old
03:45commit is still there, and we can actually go back to it again.
03:49Let's just do that real quick, and let's do git reset, and we want to still make
03:53sure we do a mixed one so that we get our staging directory to look the same,
03:58git reset and mixed back to that future version, status no changes, and git log
04:04and our reversion is back again.
Collapse this transcript
Demonstrating a hard reset
00:00In the last two movies we've taken a look at a soft reset and a mixed reset.
00:04In this movie we're going to take a look at the hard reset, or a Git reset
00:09using the hard option.
00:10Now, of the three this is the most destructive, because all three of them rewind
00:15the HEAD pointer to point to another commit, but the other two leave the files
00:21either in our staging index or in our working directory so that we then have
00:25those changes still at hand ready to remake those commits.
00:29The hard reset doesn't do that.
00:30Hard reset makes our staging index and our working directory exactly match the repo.
00:36It throws out everything that happened after that.
00:39Those commits are not just sitting there waiting for us to recommit, we're now
00:43essentially rewound back to that previous commit.
00:47That makes it the easiest way for you to lose data.
00:50The main time that you want to use a git reset hard is when things have really
00:55just gotten out of hand in your working directory, they're just completely out
00:58of sync, that's what git reset hard is great at.
01:00It just says, you know what, I don't want everything that happened after that.
01:04I really wish I could go back and just do a hard reset to this point and then
01:08move forward from there. So let's try it.
01:11Again, just like on the other two, grab some of these commits and put those into
01:15a new text file, so then we'll have these references to these later commits if
01:20we decide that we want to go back to them.
01:22And the commit that we're going to roll back to is going to be the same one,
01:26we'll just go back to that right there.
01:28So it's git reset with the hard option to this SHA right here so that's going to
01:34rewind back and undo the revert commit that we made.
01:38So it tells us HEAD is now at this point, and it gives us the name of that.
01:44If we take a look at the log, we'll see that in fact that's what it points to,
01:48that's the most recent commit.
01:50And if we do git status, you'll see that it tells us our working directory is
01:54clean, there's no trace of that file.
01:57There is no trace of the changes that we made to resources.html.
02:02Now, we can at this point do our revert again if we wanted to, if we wanted to
02:06do it over, or if we just thought we wanted to do something different, we've now
02:10essentially rewound our project back to this previous point in time.
02:14I said that it throws everything away, that's not entirely true, it doesn't
02:18throw everything away, it's just not sitting here waiting for us to make those
02:21commits, it's not at hand.
02:23However, those old commits are still there, we can still move our HEAD back to
02:28this later point in time.
02:30So let's do that, git reset --hard, and we'll put in the later commit again, it
02:38now moved it up there, that git object was still there, it's still sitting there
02:42in the git folders, it had just moved the HEAD pointer away from it.
02:47At some point if we hadn't done anything with it, it would have gotten garbage
02:50collected and thrown away, that would have been a long ways down the line.
02:54It would have hung on to it for a while just to make sure that we didn't want to go back to it.
02:59But it wouldn't have been easy to go back to it if we didn't record this reference right here.
03:04We wouldn't have those changes in our working directory, and we wouldn't know
03:07the name of the commit that would take us back there to get to it.
03:11So unlike the other two examples that we did with reset, let's go ahead and take
03:15the additional step of making a new commit here.
03:17So let's do git log, and instead of just reverting this commit, let's rewind
03:21back here before we even rearrange the items the first time.
03:24So I'm going to use this 2907 as the SHA, let's do git reset --hard, and let's
03:30rewind back to that point. So now it's rewound us back to git log.
03:36You can see we're back to removed contractions from page text, git status, you
03:43can see that there's nothing in my staging index or working directory.
03:46And if we open up resources.html, and we scroll down to that list, you'll see
03:51that it's back in its original state.
03:54So it essentially did the reversion by allowing us to rewind.
03:58Let's say that we now want to make additional changes though and go forward.
04:01Let's say that we want to just move sunglasses up here after hat, put it right
04:07in front of hat, and then I'll save it, close it, git status. Let's do git
04:13commit, and we're going to use the -a option, which is going to commit all of my
04:17changes all at once with the message, and we're going to say "Moved sunglasses
04:24higher in list of suggested outdoor items".
04:30So now it's made my new commit. Nothing in my directory. Git log.
04:36Now I've put a new commit here.
04:38So now, after this one comes this one, I've essentially rewound in time and started recording.
04:44And now my HEAD pointer points to this new commit, and all my future commit will just come off of that.
04:50Those other commits that we made, they're now just lost, they're sitting there
04:53abandoned in the git folder and they will eventually get garbage collected.
04:57So that's how you use the three different forms of reset, soft, mix, and hard.
05:02Again, just be careful when you use them, because they do allow you to overwrite data.
Collapse this transcript
Removing untracked files
00:00To finish up our discussion of how we can undo changes that we've made, I want
00:04to look at a relatively simple one which is how we can remove untracked files
00:08from our working directory.
00:10The idea is that if we have a lot of files that have been added to our working
00:14directory that are not tracked that we don't want, we just want to get rid of
00:18them, is there an easy way that we can do that?
00:21We certainly could go through and just delete them one by one,
00:23but Git gives us a quick and easy way to just tell all those files that should be thrown away.
00:28So specially if you have things like log files, zipped directories, compiled
00:32code, things like that that you don't want in your Repo, and you'd like to get
00:35them out of your working directory too.
00:37We can get rid all of those by using the git clean command.
00:40Let's start by just creating some simple files.
00:42So we'll go into TextMate, and let's just make a new file, put Junk in it, and
00:47we'll save it, and we'll call it junk1, we'll put on the Desktop and then let's
00:51do a Save As, and we're going to call this one junk2, and then let's do Save As
00:57one more time, make this one junk3. So we'll close that up.
01:02We've now got these three junk files, we're going to add all of these to
01:05our working directory.
01:06So now when I do git status you'll see that they show up there as untracked files.
01:11What we want to do is get rid of them.
01:13And the way that we just say throw them away is with git clean, and git clean on
01:19its own won't actually do anything.
01:20They will come and say you know what I need either a -n or a -f option.
01:26- in is a test run, so let's try that first, git clean -n, and it comes up and it
01:32says would not remove the folder explorers.
01:34Don't worry about that, we'll talk more about directories later.
01:37It says that it would remove junk1.txt, junk2, and junk3.txt, so it tells us the
01:43files that it would remove. That's what the -n option does.
01:47git clean -f forces it to run, and essentially we have to add this extra flag to
01:53it because it is going to be destructive, it is going to throw away anything
01:57that is not in our repository.
01:59However, if we have something in our staging directory, junk1.txt like that,
02:08now if we run git clean -f, it did remove junk2 and junk3, but it did not remove junk1.
02:17Junk1 is in our staging index, not in our working directory, so it didn't get thrown out.
02:22git reset HEAD on junk1.txt, now if we do git clean with the -f option, it
02:31throws it away as well, git status is empty.
02:33And we take a look, and we can see that all three of those files have been thrown away.
02:38So git clean is pretty simple, especially compared with all the work that we were
02:41doing with different kinds of resets.
02:43It has one simple purpose, which is just to throw away the untracked files.
02:48Now be careful when using it, because of course it does destructively throw
02:52away these files. They're not stored in our Repo, they're not stored in our staging index.
02:56If we throw them out of the working directory, they're not stored there
02:59either, and they're not stored in your trashcan, they're just going to be permanently deleted.
Collapse this transcript
8. Ignoring Files
Using .gitignore files
00:00In the previous chapters we saw that git does a really good job of noticing new
00:04files as well as changes to existing files in our working directory.
00:08In fact, as soon as we added a new file to our working directory Git noticed and
00:12added it to the list of untracked files.
00:15So, for example, if I take this tempfile.txt and drop it into my
00:19project directory, I can say git status and right away git recognizes
00:24this is an untracked file.
00:25But what if this is in fact a temporary file that we don't care about or what if
00:30it's a log file that's constantly changing, git would constantly be prompting us
00:34to commit those changes to the repository. Instead, what we really want is a way
00:38to tell Git just ignore the files altogether, that's what we're going to learn
00:43how to do in this chapter.
00:45To tell Git which files it ought to ignore, we're going to create a special file in the root of
00:48our project, in the root of the working directory.
00:51And that file is going to be called .gitignore, so it's all run together, no
00:56spaces or punctuation except for the Period
00:57at the beginning, .gitignore this file is going to provide Git with a set
01:02of rules that it can use to know which files to use for commits and which
01:06ones should be ignored.
01:07Those rules can be very simple, just a list of files one for each line or we
01:12can get little fancier, and you some very basic regular expressions.
01:16We can use the Asterisk, the Question Mark, a bracket of characters, a
01:20character set, or a range like 0-9.
01:22So it's really pretty limited, we just have some basic wildcards that we can use.
01:28We can also negate expressions by putting an exclamation point in them.
01:33So, for example, we could say ignore any file that ends in .php. We're using the
01:38asterisk wildcard for one or more characters, so one or more characters
01:43ending in .php will get ignored but don't ignore index.php.
01:49Don't let it confuse you this sort of a double-negative, we're talking about not
01:53ignoring things, that means these would be tracked.
01:56So files ending in .php don't get tracked, but index.php does get tracked.
02:02And you can tell to ignore all files in a directory by just having a trailing
02:06slash at the end, and that will tell that all files in this directory should be ignored.
02:11If you want to add comments to the file, you can start those with the Pound or
02:16Hash sign at the beginning, and blank lines will just be basically skipped.
02:20Let's try creating a gitignore file.
02:21Now you can create the gitignore file a number of different ways. You can simply
02:26open up your Text Editor and create it that way.
02:28But I think because it has a dot
02:30in front of it which makes it hard to see anywhere except from command line,
02:34it's best to create the file from the command line.
02:37So I'm going to use a Unix command nano which will bring up a text editor that I
02:41can use to edit that.
02:42Now if you're doing this on Windows, even though you maybe using a Unix-like
02:46environment, you still may not have access to the nano program.
02:49You can try and see if it works.
02:51But if it doesn't work then you'll need to fallback using another Text Editor,
02:54and Notepad is probably the simplest one that you know you're going to have a
02:58Windows, this is the most basic Text Editor there is, and you can find that in
03:02your applications, and then you just save the file as .gitignore and make sure
03:06you have the Save As type field set to be All files, and then I'll make sure it
03:11doesn't put a file extension at the end or just be .gitignore with nothing after
03:15it, and you'll save that file in your Explore California directory.
03:17Now since I'm on Unix, and I do have access to nano, I'm going to type nano and
03:22then .gitignore. This is going to create a new file called gitignore in the
03:29directory that I'm in right now which you can see is my project directory, so
03:33let's create that new file there, and let's start by just putting in that we
03:37wanted to ignore tempfile.txt, and then you can see down here it says Exit is
03:44this character here followed by the X, that's the Ctrl key, so Ctlr+X, we'll
03:48exit out of there, save changes, and we'll type a Y for Yes, file name to write
03:53it to is gitignore, we'll hit Return to accept that.
03:56And now if we do ls -la, we see gitignore file has been added.
04:03So let's do a git status now, and now you can see that that temp file is no longer listed there.
04:09So we're not seeing the temp file as being a file that's not tracked.
04:13However, we have a new file there, which is gitignore.
04:17Don't ignore that file--or you don't want to tell Git to ignore that--we want to commit
04:21that file to our repository.
04:23We want that to be included with the project, this is the project's gitignore
04:27file, it's the files that may show up in the project that everyone is going to
04:32want to ignore, so we're just always going to include it with the project we
04:36will want to commit that.
04:37And before we actually commit it, though, let's just try a few more things, nano,
04:42let's open up gitignore again.
04:45And this time I'm going to change it to just use the Asterisk, so
04:50anything that is .txt.
04:52Now if I did this, it's going to ignore not just that one file but any other file
04:58in this directory that ends in .txt.
05:00All the .html files would still be tracked, so let's just do Ctrl+X to save the
05:05changes, type a Y and return, and that will save it, git status again, and you
05:11can see that it still is ignoring that temp file.
05:14If you want to do gitignore, we can put a Pound sign at the front that makes
05:20it a comment, right? Comments are done like that.
05:24Now I'll just save it again and git status. Now that rule is no longer in
05:29effect, now it says I see two files there, I see our gitignore file, and I see
05:33that temp file again. All right!
05:35So before we actually committed let's add a few more entries to it now that we
05:39kind of have a feel for how it works.
05:41Now the only file that we really want to ignore at the moment is that temp file,
05:45so let's do tempfile.txt, and let's add a few others in here.
05:50And in the next movie we'll talk about the different kinds of things that you
05:54should can ignore but I am going to give you some samples.
05:57We're going to list the .DS_Store file that's a file that shows up on Macintosh,
06:01that's something that the operating system uses.
06:03We're going to tell it to ignore all files that end in .zip and .gz.
06:08That's files that have been compressed into a single file, and let's say log files.
06:13Let's say we have a directory called log and anything in that directory that
06:17ends in .log we're going to ignore.
06:20In addition to that, if we use log rotate on our log files it's going to append
06:25a number at the end. So anything that is 0-9 at the end we also want to ignore.
06:32Let's imagine that we have in our assets directory some Photoshop files that we
06:36used to create the graphics. Well, we can tell to ignore all Photoshop files that are in there.
06:41Let's say we have some videos, we can tell it to ignore all the videos, but
06:46let's say there are some videos that we do want.
06:48Well, let's tell what videos do we want it to track. We'll tell it
06:51not to ignore videos/tour_*.mp4.
07:00So anything that starts with tour_ and ends in .mp4 in the videos directory is
07:06still going to be tracked.
07:08Okay, so that gives you some idea of some of the kinds of ways that we can use this file.
07:14Now here's my question for you, would log/archive/access.log be ignored?
07:21Look there at the entry for log right here and decide whether you think that it
07:27would be ignored or not.
07:28The answer is no, it would not. This is only going to apply to files.
07:33So this wild card is for characters that would be part of the file name, it would not
07:39include archive and the slash in front of it.
07:42So if you have folders nested inside of folders, you'll need to be careful about that.
07:47So now that we've finished working with our file, I'm going to use Ctrl+X to
07:51exit, Y to save my changes, and Return to save it to the same file name.
07:55Let's do git status again, I'll just clear my screen, so we see our gitignore
07:59file listed, let's now add that to our repository, git add .gitignore and then
08:10git commit -m "Add . gitignore file". So there it is.
08:14Now we do git status, and we don't see it, but as you can see our tempfile.txt
08:20is still in there. It's just being ignored.
Collapse this transcript
Understanding what to ignore
00:00In the last movie we saw how we could use the .gitignore file to provide rules
00:04to Git about what files ought to be ignored or not tracked.
00:09In this movie I want to talk about to the kinds of files that you might want to
00:13include in your .gitignore file. First, let's look at some general categories.
00:17Compiled source code, the idea here is that you would want to store the
00:22uncompiled code but at the compilation you would actually want to do after you pull down the repository.
00:28The compiled code might depend on things like the processor that you're running
00:32on your computer at the time, so you'd want to compile it fresh so that you would
00:36make sure that it was compatible.
00:37You would also want to ignore packages and compressed files, so that's files that
00:42end in .zip, .gz, for example, it's also disk image files, those are typically
00:48files that you're not using in the project itself.
00:50For example, a zipped files is usually on its way somewhere else.
00:54You're zipping it up so that you can download it or send it to someone, it's not
00:58usable in itself, it has to be uncompressed before it's usable.
01:01And you don't gain any advantage by having a compressed, Git does its own
01:04compression, so you're not helping Git out by compressing those files.
01:08The third one would be logs and databases.
01:11The idea here is files that change often. So while we're working on our
01:15project, it's logging information to a log file. We don't want every time you
01:18hit get status, we don't want it to come up and tell us about those changes to the log file.
01:22And then operating system generated files, these are files that have nothing
01:27to do with our project, they are files that the operating system is using to keep track of things.
01:31Maybe it's the window position on the desktop, or maybe it's things that are in the trashcan.
01:36We want to ignore those, we don't want to have those tracked in our repository
01:40because they are really not about the project.
01:42And the last general category would be user-uploaded assets.
01:46Now this really applies mostly if you're talking about working with web projects.
01:50Let's imagine for a moment that we have a PHP project, and we have a web form
01:54where a user can upload an image.
01:56Well, as we're developing and we're testing our code, we might try uploading
02:00images, and we would tell our PHP code, hey, once you receive an image you have
02:05to store it in this directory inside the project.
02:07So it stores in that directory and then Git comes up and says, "Hey, I noticed
02:11there is a new image file, do you want to add it to the repository?"
02:14We don't, we want to ignore all those files, all the tests that we do,
02:18everything is uploaded in those image directory's user-uploaded content, we
02:21just want it to ignore.
02:22That is dynamic and changing in the same way the log files and databases are changing.
02:26Now those are some general categories, but I'd like to give you some more
02:30specific ideas as well, and there are some great resources for this on GitHub.
02:34So if you go on GitHub there's two URLs that you want to take a look at.
02:38The first is a help article just about ignoring files that has some good tips in it.
02:42And then the second is there is actually a github repository called gitignore
02:47which has some great ideas in there as well.
02:48Let's take a look at both of these.
02:50So the first of these is the github help article about ignoring files, and it
02:55has also some information just about ignoring files generally, including the
02:58things that we just learned about gitignore.
02:59But right here is what I want you to see: "Some good rules to add to this file
03:04are:" and you can see they've broken out Compiled source, Packages, Logs and
03:08databases, OS generated files.
03:09So it gives you a list of some good and general ideas.
03:12Now this is probably overkill for most people because you probably aren't going
03:15to come across even half of these depending on what language you are using.
03:18This is really a very general list.
03:21To give more specific and look at your specific purposes, the gitignore
03:25repository is a great place to look.
03:26If we scan down here, you'll see that there is a list of all the different files
03:31that are in here, these are files in the repository, and each one is a gitignore
03:35file that's specific to a certain language.
03:37So, for example, if you are working with Django, you can click on that, and you
03:42can see here is the list of files that it thinks would be a good idea to ignore.
03:47If we come over here, let's scroll down to another one.
03:49Let's say that we're working Java, well here's a Java.gitignore file.
03:56If we scroll down a little further here's one for Perl, let's click on that, and
04:01now we see the list of files that typically would come up that you would want to
04:04ignore if you are working on a Perl project.
04:07Now it's not just the languages of the applications that you might be using,
04:10there is also a folder here called Global, that has a lot of stuff about
04:14operating systems or applications that you might be using.
04:16So for example, if you are on OS X, here's a list of the files that are good to ignore for OS X.
04:23If you're on Windows, then you can scroll down here, and here's a list of the ones
04:27that are good to ignore on Windows.
04:31So it's a great resource for you to comb through and figure out the components
04:35that you might want to put in your gitignore file.
04:37Of course, the other simpler way to do it is just to start creating your project,
04:41and as files pop up that you want to ignore you can just take a second and add
04:45those to the gitignore file.
Collapse this transcript
Ignoring files globally
00:00We've seen how we can tell Git which files that auto ignore inside of our
00:04working directory, and we did that by putting a gitignore file in the root of
00:08our working directory and even storing and committing that to our repository.
00:12But what if we find ourselves ignoring the same files over and over and all of
00:16our different projects in each of our different Git repositories?
00:20Or as we saw in the last movie some of the files that we want to ignore are
00:24operating specific files, we want to ignore them all the time, because they are
00:27just generally the kind of thing that we don't want to track.
00:30Well, to do this, we're going to configure Git to globally ignore some files.
00:35That means if we ignore those files in all repositories, not just in any one specific
00:40repository, and the settings for this global ignore are not going to be inside
00:45the repository, they're going to live outside of it, right?
00:48It's part of our git configuration, not our project configuration, but our git configuration.
00:53So what that means is it's not going to be stored in the repository. People who
00:58use our repositories, if someone downloads it and starts working with it, they're
01:01not going to get it, and so we've traded repository specific ignores for user
01:07specific ignores. They exist only on my machine. Now that's good because it
01:11means that I can configure exactly the way I like it, I can ignore the files
01:15that I want to ignore, and then we don't have to worry about what someone else
01:19wants to ignore, okay? I can just ignore my preferences.
01:21Now that can be good, for example, if I'm working on a Mac and someone
01:25else using their repository is working on Windows, then we can each have
01:28our own gitignore files that are specific to our operating system.
01:31We don't have to share those.
01:32But on the other hand, if I've told it to ignore all log files, files ending
01:37in .log, and that's in my global config but not the project config, and then
01:42someone else starts using the repository, then they're going to always be
01:46prompted by Git to try and track the log file, that is unless they also ignore the log file.
01:52You just want to keep in mind the difference and consider whether you want an
01:55ignored file to be listed in your user-specific ignores or your
01:59repository-specific ignores. Okay, so how to actually do the ignoring?
02:03Well, we do that using git config. We saw this back when we were setting up
02:07Git at the beginning.
02:08We do git config with the global option and then core.excludesfile, and we tell
02:14it where the file is.
02:16So the file can be named anything we want, we can locate it wherever we want, we
02:20just have to tell Git in its config file, hey, this is the file you should use
02:24for globally ignoring things. Let's try creating one.
02:29So right now I'm inside my explore_ california directory, where I'm going to put
02:33my global ignore is in my user directory, right here. That's where my git config
02:38was before, if you remember ls -la and inside Users/kevinskoglund, you'll see
02:45that's where I've got my global gitconfig file.
02:47So I'm going to put the gitignore file right alongside it.
02:50You can create a number of different ways, you can use a Text Editor.
02:54I'm going to use the nano Text Editor that's in Mac OS X and in Unix--it's just
02:58a real simple Text Editor--and tell it that it ought to go to Users/kevinskoglund
03:02and create a file called .gitignore_global.
03:07Now again, you can call it anything you want, so we'll be just call it gitignore.
03:11I'm going to call it gitignore_global, so it is very clear that it's a global file.
03:15So inside that file then we can put whatever things we want to ignore.
03:19Because I'm on a Mac, the things that I want to ignore most often are .DS_Store
03:24and .Trashes and .Spotlight-V100, those are just a couple of things that often
03:33pop up that need to get ignored, and there are files that the operating system is
03:37using to keep track of various things.
03:39So I'm just going to go ahead and close that now, say yes, and let's save it to
03:43that file name that I gave it.
03:45And now if we check again la / Users/kevinskoglund, there we are.
03:50Now you can see that that file is there, and then the last thing I need to do is
03:55tell git config about that file, so git config --global core.excludesfile and
04:04then the path to the file. Let me just clear the screen, so it's clear.
04:08The short version in Unix, it just uses this Tilde that represents your user
04:12directory so you could say ~/.gitignore _global, that's what I would probably
04:19do, but you can also do it with a full path, which is what you would do on
04:23Windows, and we'll put in the full thing, kevingskoglund, that's the full path to get there.
04:27So when we hit Return it'll add to our config file.
04:30If we take a look at that config file cat /Users/kevinskoglund/.gitconfig, we
04:39can say that it added that excludes file right here.
04:42So, now that's the file that we'll be using for global gitignores, so I'll
04:46ignore those files in every repository on my machine.
Collapse this transcript
Ignoring tracked files
00:00In this movie, we are going to learn how to tell Git to ignore tracked
00:04files, that is files that has already started tracking, we want to ignore
00:08them after the fact.
00:09When we were looking gitignore previously, we were looking mainly at ignoring new files.
00:15So a new file is out of the repo, we don't want to track it, so we tell Git that
00:20it ought to ignore it rather than continue to show it to us.
00:23But you should note that Git will not ignore a file that was already
00:26tracked before a rule was added to the gitignore file, telling it that it ought to ignore it.
00:32If that's the case Git will still try to keep track of the file and the file
00:36must first be untracked. Let me show you what I mean.
00:39Let's say that I have a new file here, tempfile2.txt, I'm going to drop this
00:44into my working directory. If I now do git status, you will see that it comes up
00:50and tells me that now this new file has been added.
00:53Now before we do a gitignore rule for it, what we want to do is commit it to our repository.
00:59So let's do git add tempfile2 and then git commit with the message, "Adding
01:08tempfile2.txt to repo before ignoring it".
01:13Okay, so it's now been added to our repository, git status, the working directory
01:19is clean, and we look and here is the file.
01:23So we've just committed a file. That's all we have done, just a basic commit.
01:26Now that Git is tracking the file, let's tell it that we wanted to ignore
01:30changes to this file in the future.
01:32So let's open up our gitignore, so if you remember that's right here in the root
01:35of the project directory.
01:37We can open this file up and edit in a number of ways, because it has the dot
01:40in front of it, it's not visible here from this window, which makes it a little bit tricky.
01:44So I am going to use the Command Line, and I am going to use nano which is a
01:49Unix program, that will let me edit, gitignore and just right here below
01:53tempfile.txt let's add a new line tempfile2.txt.
01:57Ctrl+X to Exit, Y for Yes to save changes and Return to keep the file name.
02:04So now it's been told that it ought to ignore it, and of course gitignore shows
02:09up now on our status list is something that has edits that needs to be
02:13committed to the repository. Let's not do that just yet.
02:15Instead let's go over here to tempfile2, and let's make an edit.
02:18This is the second temporary file.
02:22If we come here, say git status, notice that even though we told it to ignore
02:27it, it did not ignore our changes, it's still kept track of our changes, because
02:32it's a tracked file, so it still sees it.
02:35And it doesn't matter if we were to have committed gitignore to the repository
02:39first or not, that's not why it's doing this, it's because Git still keeps track
02:43of these tracked files.
02:45Instead, what we have to do is tell Git to stop tracking it.
02:49One way we could do that is just to remove it, right?
02:52Git remove that would do it, git remove tempfile2.txt.
02:56It would remove it from the repository, and it would remove our version, it would do both.
03:02What if we didn't want to remove our version? What if this was a log file?
03:06Of what if it's a set of images or something or Photoshop files that we want, and
03:10we want to keep on ours but we want to tell it, you know what, stop tracking it?
03:15We may even want to leave it in the repository so that it stays in the repository
03:20for other people to download.
03:21We just want to ignore changes that happened to it after that, right?
03:25That certainly might be the case with like a log file or something. We want to have a
03:29placeholder for the log file that everyone can have, but we don't necessarily
03:32want to have changes to that log file be tracked.
03:35Well, what we want to do here instead of just remove is a remove with the cached option.
03:42So --cached, that's going to tell it to remove this file from the staging index,
03:51not from the repository, just from the staging index.
03:55That will cause the file to stop being tracked.
03:57It will still leave the copy in the repo, it will still leave the copy in
04:01my working directory. It's just going to take it out of the index.
04:05So let's go ahead and hit Return, it will say that it removed it, I do git
04:10status now, you will see it comes up and says that it was deleted, that's the
04:14commit that it wants to make is to delete the file.
04:18However, if I come back over here, you will see that the file is still here,
04:21it has not deleted it.
04:23So let's go ahead and add our gitignore file, so now both of those are ready to
04:28go, here they are, ready to be committed.
04:30And let's git commit -m, and we are going to say, "Remove tempfile2.txt from
04:41staging index" and then hit Return.
04:46Now if we do git status, we will see that the working directory is clean, but it
04:52is still listed here in my directory. It did not get rid of it.
04:55We make more changes to it, let's open it up, let's say These changes will
05:02not be tracked anymore.
05:06Save it, close it up, git status, and now it's not being tracked anymore.
05:13So if you want Git to ignore files that are already being tracked, but you
05:16don't want to remove them completely, then what you need to do is not only
05:20ignore it, but tell Git that it ought to also remove them from the staging index or the cache.
Collapse this transcript
Tracking empty directories
00:00So far in this chapter, we have been talking about how we can give instructions
00:03to Git, to tell it which files it ought to ignore instead of tracking.
00:08In this movie, we were actually going to do the opposite.
00:10One of the things that always surprises people who are new to Git is the fact
00:14that Git does not track empty directories, and that's because Git is designed to
00:19be a file-tracking system.
00:20Its purpose is to track files and the content in those files.
00:24So it tracks files, and it tracks the directories it takes to get to those
00:28files, but it ignores directories that have no files at all.
00:32Let me demonstrate. Here I am in my project folder.
00:36I have got an empty folder here on my Desktop called pdfs, you can create a
00:40new folder or pull this one out of the exercise files, and I am just going to drag this into assets.
00:45Let's open up assets, and you can see that pdfs is empty.
00:49All right, there is nothing inside of there, and I can confirm that from the
00:52Command Line ls -la assets/pdfs/. Now these are not things in there.
00:59There is not a file called dot and dot dot.
01:01In Unix, this is a reference to the current directory and reference to the parent directory.
01:05So those were not files, it means the directory is in fact completely empty.
01:09I had already done a git status here, and it said working directory is clean.
01:12Let's try it again, git status, working directory is still clean, it didn't list it.
01:17Now the moment that there is a file in there, then it will suddenly keep track of it.
01:22So the trick that we use in order to keep track of empty directories is to put a file in them.
01:28Now if you already had planned on putting some PDF files in there, well, no problem.
01:32Just put the PDF files in, add the PDF files to the repo, and
01:36that directory will get put in there at the same time, it will all get added together.
01:40But if you want to have it track an empty directory, it can't be truly empty.
01:44It has to have some kind of file in there.
01:47So the cheat that everyone uses is that you just put a little tiny file in there
01:53so that it can track it, and by convention people either name that file
01:56.gitignore to match the gitignore file or more often now but use .gitkeep, the
02:04opposite, basically telling it, it should keep this directory.
02:06So we just need to put a little file inside pdfs called .gitkeep, and you can do
02:12that using just any text editor. You don't have to actually put any content on
02:16it, it can have zero content in it, drop it in there or it can have a comment
02:20saying I want to keep this file, something like that.
02:23It doesn't really matter. That file will never get used for anything except for Git.
02:27One of the ways that we can do that from Unix is we can use the touch command.
02:31So touch is a way to just create a file that doesn't exist.
02:35If we say assets/pdfs/.gitkeep, this will create the file .gitkeep with no
02:42content in it whatsoever. This is a little Unix trick.
02:45We will do that, and now if I go back here and do ls -la assets/pdfs/, you can
02:52see that .gitkeep file is there. It's 0 length, there is nothing inside of it.
02:57But the file is there.
02:58Now we can't see it, right here from the desktop, it still looks empty, but when
03:03we go to Git and ask about it, Git says, "Ah!
03:06I see this directory," and if we say git add assests/pdfs, git status, now
03:15here it is it says, "Ah! I found a file." Assets/pdfs/.getkeep.
03:21That's the file that it wants to add.
03:23So let's go ahead and commit it, so git commit and "Add 'empty' directory with .gitkeep file in it".
03:36So there it is now it's added to our repo, git status, and it's been tracked.
03:40So even though it's a little bit surprising at first, it's a pretty easy fact to remember.
03:44Git keeps track of files, not directories.
03:47The directories are just incidental as the path to get to those files.
03:51If we want to keep track of a directory, it has to have a file in it, no matter
03:55how small, but there has to be a file.
Collapse this transcript
9. Navigating the Commit Tree
Referencing commits
00:00In this chapter, we are going to learn how to navigate the repositories commit tree.
00:04In order to do that, we need to start off by talking about the ways that we can
00:07reference commits in Git.
00:08We have covered a few basic ways already, but there are others that are going to
00:11be really useful to know.
00:12We will start off by introducing a new concept in Git called tree-ish.
00:16It's kind of a funny word, we've already talked about what a tree is in Git.
00:19It's the structure of files in the Git repository.
00:21It's similar to a directory in your file system.
00:24In Git, tree-ish means something that references part of the tree.
00:28It's ish because what that something is can vary widely.
00:32The suffix ish indicates that it's like something but maybe in a vague way.
00:36Tree-ish is an important term to know, because it does show up in the Git documentation.
00:40You will be looking up how to use a command, and it will tell you that you can
00:43pass in a tree-ish as an argument to that command.
00:46Now in its simplest terms, a tree-ish is a reference to a commit because that
00:51commit then in turn references the tree, the Git repository and all the files
00:56that are in there at that point.
00:57So if you have a hard time thinking about all the things that a tree-ish can be,
01:01the simplest version is that it's just something that points out a commit.
01:05So how can you reference a commit?
01:07The easiest way to do it is to use the SHA-1 hash, to use the entire 40
01:12character string in order to reference the commit.
01:14Git will always know which commit we mean because each one of those 40
01:18character strings is unique, and as a side note, if you were wondering, how Git
01:23make sure that all those are unique, it doesn't, but the odds of it not being
01:26unique are astronomical.
01:27We are talking you would need billions and billions of objects in order to have
01:32a chance of having two objects that have the same SHA-1 hash.
01:35It so highly unlikely that, for practical day-to-day purposes we assume
01:39that they are unique.
01:41The other way we have seen that we can refer to a commit is using a shortened
01:43version of that hash.
01:44We don't have to have the whole thing, we can just use a portion of it, and
01:47because those numbers are so unique, Git can use that small portion and still
01:51find the object that we were looking for.
01:53We do have to provide at least four characters, and we have to provide enough,
01:56that it is unambiguous.
01:58Now being unambiguous depends on the size of our project.
02:00If we have a project that only has five commits, well then 4 characters is
02:04enough for it to know which one of those 5 commits that we're talking about.
02:07If we are working on a mid-size project, you typically want to have something
02:11like 8-10 characters, and if you are working on a really large project, one that
02:14had millions of objects committed into it, something like the Linux Kernel, well
02:18at that point you want to have 12, 13, maybe even 15 characters to make sure
02:23that Git can find the object that you are looking for.
02:25My advice is to stick to about 8- 10 characters unless you need more.
02:29And we have also seen that we can reference a commit by using the HEAD pointer.
02:33The HEAD pointer remember always points to the commit that's at the tip of the
02:37currently checked out branch.
02:39So that's going to be a tree-ish that points to part of the tree.
02:43We can also use a branch reference. If we use a branch reference, then we are
02:45referring to the tip of the branch.
02:48Now it doesn't have to be the currently checked out branch, it can be a branch
02:51that's not checked out.
02:52We will talk a lot more about working with branches in the next chapter.
02:55We also can use a tag reference.
02:57We are not going to cover tagging in this tutorial, other than just to mention
03:00that it is another way that you can refer to commits.
03:02And the last way that we can refer to commits is by using any one of these
03:06methods and then referring to that object's ancestry.
03:09Let me show you how we do that.
03:11So if we want to refer to the parent commit of something, we first provide the
03:16reference for what we want to focus on, and then we say, find its parent by
03:21using the caret. So that caret character comes right after it, you can think
03:25of it is pointing up, pointing up to the parent on the tree.
03:28If you think of like a genealogy chart where the grandparents at the top and the
03:32children come down, we are moving up.
03:34So we are moving up to the parent, and that's what the up arrow nature of the
03:37caret suggest to us.
03:39We can also use a tilde notation, that is to have a reference to the commit
03:43and then a tilde followed by the number of generations we want to go up.
03:48So HEAD going back one, we can also leave off the one, and it's just assumed.
03:52Most people tend to use the caret in this case instead of the tilde, but
03:55they do the same thing.
03:57If our HEAD commit is acf87504 then all five of these, all refer to the same thing.
04:04They all refer to the parent commit of acf87504.
04:08Now in addition to the parent commit, we can refer to the grandparent commit.
04:12Of course, if we want the parent of the parent, well then we just provide two up arrows.
04:17We say start at the HEAD and go up twice, that will give us the grandparent.
04:22This is where the tilde notation becomes a lot more useful because now we can
04:25say HEAD~2, and it's especially apparent when we have the great grandparent
04:30commit because then we start having a whole lot of caret characters coming after
04:34our commits, whereas the tilde notation is much more compact and clear as to
04:38exactly what we were doing.
04:40We are going from the HEAD, we are moving back three commits to the great grandparent.
04:43So these are some useful ways that we can refer to commits that are in the commit tree.
04:48In the next movie, let's put these into practice and actually try using them.
Collapse this transcript
Exploring tree listings
00:00In this movie, we are going to apply what we just learned in the last movie about how
00:03to refer to commits, and we are going to use it to be able to look at the tree listings.
00:09Remember that I told you that a tree is a lot like a directory on your file system.
00:13If I am in Unix, and I want to get a list of the current files that are in the directory
00:17I am in right now, I use the ls command for list, ls -la is a set of options that formats
00:24it so that it runs in a nice vertical list with all of the file names, including file
00:29names that start with a dot over on the right side.
00:32Now in Windows, you can do something similar with the dir command,
00:34but I want to stick with the ls of Unix for a second, because in Git, it's something very similar.
00:40To list out a tree, we use git ls-tree, listing the tree, and then what we pass in after
00:47that is a tree-ish.
00:48In fact, before we do it, let's take a look at the Help documentation, and notice right
00:53where it talks about how to use it, it says, get ls-tree, there is a whole bunch of options
00:57we can pass in and then after that it won't say tree-ish.
01:01So there it is. I am not making it up. That's the word for it, and it's a reference to the tree.
01:06So let's try that, git ls-tree, and now we need a tree-ish.
01:10Well, one of the one is we can refer to the tree, is to use the HEAD that will point to
01:15the tip of the currently checked out branch, and it will return the list of files at that point.
01:22That's what's in the HEAD.
01:23Those are the files that are in the repository at that point, so that's what the repository
01:28thinks is the current set of files.
01:30If I were to check this out, brand new, from the repository, these are the files it would give me.
01:35Now those don't exactly match what I had in working directory because my working directory
01:40has some files that I have used gitignore on.
01:41So you can play around and try out some different tree-ishes, so let's do git ls-tree master.
01:48That points to the exact same thing because we have the master branch checked out right
01:51now, so HEAD points to the tip of that, we are getting the exact same results.
01:55Let's take a look inside a directory there, we can pass in a file path after that, so
02:01git ls-tree master, and let's ask it for assets with the slash after it. So the contents of
02:07the assets directory, and it comes up and tells us the files that are inside that directory.
02:13Now let's try going back one commit.
02:15I don't know if you remember, but one commit back is when we actually created this pdfs folder,
02:20that's when we added it.
02:22So unless you made other commits, in which case you may need to go back further, but
02:25one commit back will now show us that directory in its previous state. So in the commit before
02:31that, there was no pdfs folder, in the commit after it, now there is a pdfs folder.
02:36One more thing I want to show you, notice that each of these entries over here on the
02:40left, it tells you that everything is either a tree or a blob. A blob is a file. It can
02:46be any kind of file that's stored there.
02:47It can be text file, an image, anything, they are all stored as a blob.
02:51If it's not a blob, then it's a tree and guess what a tree is? A tree is a directory.
02:57So we are inside a tree because we had a tree- ish that pointed us to a tree and then inside
03:01that tree are other trees.
03:03Well, that three has an object number, it goes with it.
03:07So we can grab the first part of that, copy it, and then we can say, well git ls-tree
03:13and pass in that SHA, that's a tree-ish that points to it and look what it gives us.
03:17It gives us back the exact same thing that we had here, the only difference is that it
03:21doesn't prefix it with the assets directory because we have already told it it's the tree.
03:26This was telling us we were starting with master and then looking inside assets, so
03:30it listed assets for us.
03:32Here were starting at assets so it doesn't give us the prefix there.
03:35So try it out, play around little bit and get comfortable with it and make sure that
03:39you understand the things that we learned in the last movie about the different tree-ishes
03:42and the way that we can reference different trees this way.
Collapse this transcript
Getting more from the commit log
00:00In this movie, we're going to talk about how to get more from your commit log. We've already
00:04seen the basics, and we want to see what's in our log for our repository, we can say git log.
00:08That returns a paginated list of everything that's in our git log, and if we hit space it
00:12will just keep going until it gets to the end, and Q will quit of it. So that's the basics
00:17of git log, but there is a lot more we can do with it.
00:19In fact, I really encourage you to go look at the Git help pages for log, because there
00:24are so many options there. You can really fine-tune exactly what you are looking for
00:28and tease out the information about the commits using all of these configuration options, but
00:33I'm going to highlight some of the most important ones.
00:36The first I think is just git log --oneline.
00:40I think it's probably the single most useful option, because it just gives us a oneline
00:43list of what's in our log file, instead of having that long scrolling list, it just compresses
00:48it for us. It still gives us part of the SHA here that we can use to reference each one
00:52those commits if we want to work with it.
00:54We can also use a number of commits to limit the number of commits that it goes backwards,
00:58so, for example, -3 will show us just three commits, -5 will show us five commits. We
01:06can also filter the log by time period.
01:08So for example, git log, and then we can use the since option, since equals and then in
01:14quotes, and we can put a lot of things in here for the time.
01:16For example, 2012-06-20, and it understands that as being 2012 June 20th.
01:25Hit Return, and that's what it gives us, just the entries that are since then.
01:28We can always use after instead of since, those are synonymous.
01:32We can do the same thing, but use until so that's all the commits that are until that
01:39date, and we can use before as well. So before and until both work the same way, and we can
01:43of course combine both of those. We can pass in the time period in other formats as well.
01:48So for example, 2 weeks ago, just as a string, and it's able to figure this out.
01:55Say 3 days ago, so there's everything from 2 weeks ago until 3 days ago, again paginated,
02:02hit Return at the end, and you can even do it just by saying 3.days and 2.weeks, and
02:13it's able to understand that as well.
02:14So any of those formats will all do the same thing. You have a lot of flexibility in the
02:17way that you specify the time period that you want to use.
02:21We can also search by author, so author this is the person making the commits,
02:26I can say I'm looking for everyone with Kevin and the author, so if there were multiple
02:30Kevins, it would show all of them. Instead if I wanted just Kevin Skoglund then of course,
02:35I would write in my name there, and now it shows me just author Kevin Skoglund.
02:39We're the only one making commits at this point, but if we are collaborating with other
02:43people, it's nice to be able to filter out and see, what are the commits that John made?
02:47I want to see John's commits only and see what he was up to last week.
02:51We can also GREP the commit messages. GREP is a global regular expression search, so
02:56we can do git log --grep equals and then whatever regular expression we want to search for we
03:01can put here in quotes. So I'm going to search for temp, and that'll return the two things
03:06that had a message that were about the temp file, and see both of those.
03:10This is really nice if you want to see everything that was committed about a certain topic.
03:13You can see now why having good commit messages is really, really helpful, because it allows
03:18us to be to search for things in the commit message that apply to the particular section
03:22of our code that we might be working on.
03:24We can also specify a range of time period, let's do just a regular git log, oneline, so
03:32here we are, and let's say we want to see all the commits from this commit, do git log,
03:39and then put that SHA in dot, dot. That's how we indicate a range, all the way up to let's
03:44say this one. So this will show me just those commits, and I'll go ahead and do it as one line
03:49again, so it's really clear what it's doing.
03:51So now it's showing me just those from that commit up to that commit, so that's how we use
03:55a range. We will be using those again a little later on. We can also ask it for information
03:59about what happens to a particular file.
04:02For example, I could say, tell me everything that has happened since the initial commit,
04:08git log from initial commit going forward to, and I could put in a commit or I can
04:13just leave it blank, nothing at the end of the range will say all the way up to the end,
04:17what has happened to the index.html file.
04:20Give me the logs that affect that file, let's try that.
04:24There is one commit that's relevant to it, it's this commit right here, and this is what
04:28changed to that file.
04:30So if you're working on a particular file, and you want to go back in history, and see
04:34what's happened to that file previously, the log will let you do that.
04:38We can find out more details about the commits by using git log -p, this is the patch option,
04:43and it shows us a diff of what actually changed in each one of these.
04:48So here's the additions and here's the subtractions. So we can really see what's different about each one.
04:53That's really nice, especially when we're working with this, find out what happened to
04:56each one of these files, because we can jump back here and right after log we'll put it in
05:00the -p option, and now not only does it tell me what commits apply to this, it actually
05:06shows me the changes as well. So I can do both, all right here, every single change listed
05:11out that happened to the index.html file.
05:14We can do something similar also with git log --stat and --summary, and you can use
05:21those separately or together.
05:23What they'll do is they'll tell you statistics about what changed in each one, so you see
05:28here this, the git ignore file added whole bunch of things.
05:31Here in resources, something was added and something was taken away, and it goes
05:35ahead and gives you a little summary here as well, that's what that summary is.
05:38That's nice if you're not as concerned with the actual details of what happened, you are
05:41just wanting to get an idea of the quantity of things that changed and where.
05:45So as far the log format goes, we saw the most useful one, already which was the oneline,
05:50and git log --oneline is one way to do it, git log format equals oneline is another way to do it.
05:58Now this returns a slightly different thing, because it returns the full SHA instead of
06:02just a partial SHA, so you can compare the two, oneline, oops, I misspelled it. There
06:10it is, so you can see the difference between the two of those.
06:13We can also specify other formats though which is why it's nice to know about the format
06:16version, because in addition to saying oneline, we can also use short or we can use medium
06:24which is the default one that we already seeing, we can see full, that gives us a little more
06:29information, like the commit author, and there's fuller which gives us even more information.
06:34There is email, which generates it in a format useful for mailing an email, and then there's raw.
06:41It's really showing us the raw information that's stored in Git.
06:44The last one I'm going to leave you with is one that I think is pretty cool, git log --graph.
06:51So this shows us a graph of each one of our commits.
06:54Now right now our graph is pretty straightforward and linear, but if we start having branches,
06:59and we start branching thing off and then merging things back in, then this really shows
07:03us those branches are merged, so we'll come back and try that a little later.
07:06A nice combination of them is git log --oneline --graph --all --decorate, so let's put all
07:17those together, and you'll see that it gives us a nice compact list. It'll show all the
07:21branches that take place and even tells us right now that this is where the HEAD is pointing,
07:25and this is the tip of the master branch.
07:28So this is a nice combination of options that's worth remembering. Please experiment, find
07:32more, dig through the log files and find formats that are useful for you in the way that you
07:36like to work.
Collapse this transcript
Viewing commits
00:00In the last movie, we saw how to get more out of the commit log, so any time we're looking at the
00:04commit log, we're looking at a list of commits.
00:07What if we want to look at a specific commit though? We want to see what changed. What
00:11was this commit all about? I want to examine it and see what was committed.
00:15Well we do that with git show, so git show followed by a SHA, so let's take a look here
00:22at git log --oneline, and get a list of our commits, and then let's show one of them, git
00:29show, and let's take a look at this one here, moved sunglasses higher in list of suggested outdoor items.
00:35So I just paste the SHA right there and then hit Return.
00:38It shows me the full SHA for the commit, it shows me the author of the date, the commit
00:41message and then gives me a diff of the commit.
00:45Remember we saw diffs before when we were trying to see what had changed before we decided
00:49what content we wanted to commit. We could diff the two to see what changed.
00:53Well, here it's showing us what was committed, the diff between what was there before and
00:57what was there after.
00:59So sunglasses was added in this spot, and it was removed in this spot. That's what the
01:05change was, and it gives me the plus and the minus as well as some coloring to indicate the changes.
01:09I can hit space to make sure that there is nothing else after it, and then Q to quit out of it.
01:13So that's it, that's what a show looks like.
01:15Let's take a look again in our log, let's take a look at different one, let's say this
01:19one where we add a file. Let's see what that looks like, git show, and that SHA, and there
01:25it is. It's adding a file, so diff is /dev/null which is computer speak for empty, so it didn't
01:32exist before, and now here it is. So compared to nothing, it's all added, all these items
01:38are added here, all new.
01:40Same thing if we delete something, it'll of course all be removed, it'll show them all
01:44as being minuses.
01:45Now that you can also pass in formats here, mainly it has to do with what the format looks
01:50like at the top, so let's say format=, and we can have oneline and then let's give it
01:56our SHA, I'll just say HEAD, so there is what our HEAD looks like.
02:00Let's take a look at HEAD back one, there is the one that's before that, and let's do
02:05HEAD back two, or HEAD~3, that shows us the commit that was before that, so we can surf
02:15around and go back and look at these commits.
02:17There are some other options you can pass in. You can look through the help documents to find those.
02:21Now what we're passing into it is a tree-ish object like before, but git show actually
02:26does handle them all a little differently. If we do the help docs git help show, you'll
02:31see it takes blobs, trees, tags and commits, so we're mostly working with commits here.
02:37If we passed in a tree, it would show the names of what was in the tree, it's equivalent to
02:42doing git ls-tree with the name-only option, so it's the exact same thing.
02:48For plain blobs, that's files, it shows the contents.
02:51Let me just demonstrate both of those real quick.
02:54So let's do git ls-tree master, so there is our list.
02:59Here is the one for assets, so I'm just going to grab the first part of that and tell it
03:03git show that tree. That's the tree that we want to focus on, that's the tree-ish object
03:08we're passing in, it comes up and gives me a list of what's inside there.
03:13Again this is same as git ls- tree with the name-only option.
03:17Let's do the same thing for our file.
03:19We have our index file here, again, we pass in the tree-ish object, git show, and then
03:24we pass in that SHA, and there it is, there's the content.
03:28Now I just want to point out that that's not the same thing as saying git show index.html.
03:33That's not a tree-ish. We can't pass that in. That is not a reference that it understands
03:39as a tree-ish object, so it comes up and it says I don't know what that is.
03:43We have to pass in the SHA or some other reference to the file that it can understand a tree-ish.
03:49So I think between viewing the tree, viewing a log file, and viewing the commits, you'll
03:54be able to navigate around and really see what's been committed to the repository before.
03:59The last thing that's super useful is being able to compare commits, and that's what we'll
04:02do in the next movie.
Collapse this transcript
Comparing commits
00:00In this movie we're going to learn how to compare two different commits.
00:04Now when I say compare commits, we're not actually comparing the commit snapshot, just
00:08those changes that were made that are stored with that commit. We're comparing the directory
00:13that that commit references; the actual state of all the files in the repository at that point in time.
00:19And that makes sense because a commit is not just a snapshot of those changes, but it includes
00:24all of the ancestors all the way back to the beginning of the repository as well.
00:29And the sum total of all those ancestors is the directory, or tree, at that point in time
00:34where the commit is.
00:35So when we compare commits what we're actually doing is comparing two directories and seeing
00:40what has changed between those two directories.
00:42Now it might be comparing what's changed over time.
00:45For example, I might be comparing a commit that I made on Monday morning with a commit
00:49that I made on Friday afternoon, and comparing those two directories will show me all of
00:53the changes that have been made during that one week.
00:56Or once we learn about branches, which we'll do in the next chapter, we can compare two
01:00different branches to see how they differ.
01:02What's changed in each of these branches? In order to make these comparisons we're going
01:06to use a tool that's already familiar to us, and that is diff.
01:10When we used it the first time, we just used it simply by saying git diff.
01:14And what that did was it returned the changes that were made between our working directory
01:19and the staging index.
01:21So it's all the things that could be put into our staging area, changes that we had made
01:25recently that were not yet staged.
01:28Once we put them into the staging area, they didn't show up in git diff anymore, you'll
01:31remember we had to add another option to it, which was staged or cached, and those are synonymous.
01:37And what those do is they show us the difference between the staging index and the repository
01:42or HEAD, where the HEAD pointer is pointing.
01:44Well, the diff tool is very flexible and allows us to pass in other things as well so that
01:49we can compare more than just our working directory, staging index, and repository.
01:54If we pass in a SHA that references a commit, it will show us the difference between our
01:58working directory and the directory at the point in time that that commit was made.
02:03So for example, let's do git log --oneline, and let's get a list here, and I'm going to
02:09use this one right here, cdae0ed.
02:14If we say git diff, and then we just pass in that SHA, that reference to the commit,
02:20Moved sunglasses higher in list of suggested outdoor items, now it returns to me all the
02:25differences between the directory at that point in time and my current working directory.
02:30Let's take a look at another one.
02:32Let's go up here, let's pick out one further back, this has lots of changes.
02:36Let's clear our screen, git diff, and in that one, 1506576, hit Return.
02:43And now you see I get lots of changes.
02:45It's showing me all the different things that have changed, including renaming files and
02:50things like that.
02:51I'll hit Q to quit.
02:52Okay, that's nice, because then what we can do is we can compare where we are now against
02:57a previous point in time, basically just looking back. What's changed since this point in time?
03:02And we can be more specific by passing in a specific file.
03:06For example, if we wanted to use that same commit and find out what's different about
03:09the tours.html file only, look it up and tell us.
03:13This is a comparison between this previous point in time and your working directory now.
03:18It's a very handy tool.
03:20Now we don't just have to use our working directory, we can actually compare any two commits at all.
03:24We can just pass in two different tree-ishes using a range.
03:29We saw the range before when we were working with the log file, so it's just between two arbitrary commits.
03:34Let's do git log --oneline again, so we can see a list of those commits.
03:39Let's compare these two commits right here, the two that start with c.
03:42What changed between these two? Let's do git diff and the first one, followed by dot dot
03:48and then the second one, and that's it.
03:51The snapshot at this point in time versus the snapshot at another point in time, show
03:55me what changed between them, and this will give us a summary of all the things that have changed.
04:00Now if we're only interested in what changed in the tours file, same thing html, look them up
04:06and tell us nothing actually changed between those two points in time.
04:09Now again, you can pass in any tree-ish here, so if you wanted to say git log --oneline,
04:15and we want to compare this versus HEAD, git diff ..HEAD, we can compare that.
04:25If we want to say git diff ..HEAD parent-parent, we can do that, all those tricks that we learned
04:32about how to reference commits, we can use here.
04:35You can look through the help documentation, and there are lots of modifiers and options
04:38that you can use with diff.
04:39However, I just want to show you a couple that I think are especially useful.
04:44Let's just get our git log --oneline again, and let's just go ahead and start from almost
04:50the beginning, git diff, and then we'll just go from there to HEAD.
04:56The first options that I think are useful is that we can do stat and summary, and you
05:01can use either one of these or both together, and they'll show you summary of what's changed,
05:05a list of the files with an idea of how many things changed in there, things that were
05:09added, things that were removed.
05:10And then the other two that I think are especially useful are the b and w options.
05:16Let's take this out.
05:17And you won't actually see any difference here, because I don't have any, but the -b
05:21option is the same thing as the longer ignore-space-change.
05:28So it changes to white space.
05:30So it will ignore whether or not someone changed one space to two spaces, four spaces to five
05:36spaces, it ignores that, that's the b option.
05:38The other one that you can use is the w option, which is ignore-all-space. It ignores every
05:46single change that could be made to space, it just says forget about it.
05:49Now that's a long thing to type, so the shorter one for each one is just to type b and w.
05:55So b is for ignore-space-changes, w is to ignore-all-spaces, everything having to do
06:01with space whatsoever completely forgotten about.
06:03This can be helpful, because most of the time simple space changes are not something that
06:07you really care about that much when you're looking at your code. You really care more
06:10about the characters that have changed, spacing is often insignificant.
06:14So we now have some powerful tools at our disposal for navigating the commit tree.
06:19We can take a look at the directory structure, we can look through the logs, we can view
06:22commits, and we can compare two different commits at to two different points in time.
06:26These are powerful tools and learning how to use them well is going to help you get
06:29the most out of Git.
Collapse this transcript
10. Branching
Branching overview
00:00In this chapter we're going to be talking about branches in Git.
00:04Branches are one of the most powerful features in Git, in large part because of how easy they are to use.
00:08It's as if Git wants you to branch, and getting the most out of Git will mean using branches
00:13often and effectively.
00:15In Git, branches are cheap, and what we mean by that is that they don't cause a lot of headaches.
00:20They don't take a lot of processor power.
00:22They don't take up a lot of storage space.
00:23They are easy to create.
00:24They are easy to delete.
00:26They are easy to work with.
00:27And they allow you to then try new ideas.
00:30Let's imagine that you have your master branch that you are working on and suddenly you get
00:33an idea for something, but you are not sure if it's going to work out or not, instead
00:36of making lots of commits to your master branch and then trying to undo those if it doesn't
00:41work out, instead you just create a new branch, try your new ideas there.
00:45If those ideas don't work out, you just throw away the branch, and you haven't tainted your
00:48master timeline with those mistakes at all.
00:51If it does work out, then you can fold those changes back into the master branch through
00:55a process we call merging.
00:57Branches also allow you to isolate features or sections of work.
00:59This can be especially useful when you're collaborating with others.
01:02Let's imagine that we have a web site, and we want to revise the user sign up section,
01:06we can create a branch for that separate from our master branch, work on that feature, collaborate
01:11with others on that feature, meanwhile other people can still be working on the master branch.
01:15When we finally have our feature all ready to go, and when everyone is happy with it,
01:19then we can merge it back into the master branch.
01:21This is a very, very common practice when working with Git, you do it all the time.
01:25When we create branches we're still going to have just one working directory.
01:29All the files that we're working with will still be in that same project folder that
01:32we've been in before.
01:33But when we switch branches, Git is going to do fast context switching.
01:37It's going to take all of the files and folders that are in our working directory and make
01:41them match what's in the branch.
01:43It will swap out the two sets of changes.
01:46So if we're working on our master branch, and then we switch to our user sign up feature,
01:50now our working directory will have all of those user sign up changes in it.
01:54We switch back to our master branch, all those changes will go away, and we'll be back to
01:58the master branch.
01:59Git will handle swapping out all of those files for us, making all those changes, and
02:03it does it very fast.
02:04Let's take a look at an illustration of what branching looks like just to make sure it's clear.
02:09So we have our master branch, that's our default branch that everyone gets to start with, and
02:13we start making commits to it.
02:15And then after we make four commits, we decide that we want to try revising the navigation,
02:18but we're not sure if it's going to work out or not.
02:20So we create a new branch, and then when we finally have all of our changes in our working
02:24directory, like we want, we commit those to the new branch.
02:28So the commit is now on a new branch, it's not on the master branch.
02:31If someone has the master branch checked out, they won't see our changes.
02:35We can then switch back to the master branch, and we can switch back to the revise_navigation
02:38branch, and each time Git will swap out the files and folders in our working directory to match.
02:44So let's say we switch back to our master branch, and we make some more commits there,
02:47our revise_navigation branch still is in its other state.
02:50We can switch back and forth between master and revise_navigation, and we'll still get
02:55each of those sets of changes.
02:56When we're finally ready, and we say, all right, you know what, now I'm ready to merge
03:00in the changes from revise_navigation.
03:02Let's say it took a week to get approval on my revise_navigation from someone else, but
03:06they finally have approved it, a couple of commits have happened in the meantime, but
03:10that's okay, we're going to merge it back in, and it will create a new commit, and that
03:14new commit will merge in those changes from the revise_navigation branch.
03:18So now my master branch contains the changes that we've made in the revise_navigation branch.
03:23Now we can go back to revise_navigation branch and make more changes and merge those back in again.
03:28And we don't have to always merge things to the master branch, we could have many branches,
03:32and we can merge changes between those branches.
03:34Before we dive into actually creating branches, I just want to revisit this illustration again,
03:39but I want to talk about where the HEAD pointer is at each point, because I think that's an
03:42important thing for you to know right off the bat.
03:45So we have our master branch, and we know that the HEAD pointer always points to the
03:48last commit in the master branch, the tip of the current branch.
03:52Once we create a new branch though, that changes.
03:55We create the new branch, at that point HEAD still points to commit 534de, both the master
04:02and revise_navigation at this point are exactly the same.
04:04There have been no additional commits made, so HEAD points to the same commit.
04:09It's only once we make new commits to the revise_navigation branch that then HEAD moves
04:14to a new commit, a commit that's not on the master branch anymore.
04:18Now we can switch back and forth.
04:20If we switch back to master branch, well then, the HEAD points to the tip of the current
04:24branch, that's the master branch.
04:25If we switch back to revise_navigation, it will switch back to point to the tip of the
04:30revise_navigation branch.
04:31Again, it's like that playhead that's always saying where we're going to start making new commits.
04:36So let's say I've got my master branch that I'm working on, that's where HEAD is pointing.
04:39I make more commits there.
04:42Then when I'm finally ready to merge back in to revise_navigation branch, it creates
04:46that merge commit and the HEAD moves to that merge commit.
04:49Okay, keep this in mind, because in the next movie we're going to learn how to create a
04:53branch, and we'll also take a peek to see where the HEAD pointer is pointing.
Collapse this transcript
Viewing and creating branches
00:00In this movie, we're going to learn how to create a branch.
00:03To begin with, let's start by looking at our current branch.
00:06The way you can see all the branches in our local repository is git branch.
00:10And it's just by itself git branch will show us a list of the branches that we have on
00:14our local machine.
00:16I only have one, and it is master, the default branch.
00:18And you can see there is an asterisk next to it. That lets you know that that's the branch
00:22that we're on now.
00:23We refer to that as the current branch or the currently checked out branch.
00:27You may remember from our discussion about the HEAD pointer that the reference for the
00:31HEAD pointer is stored in the .git folder.
00:34So cat .git/HEAD, and inside there what that file contains is a reference to one of the
00:43branches, because HEAD always points to the tip of a branch.
00:46So the HEAD says all right, here is the branch that I'm on now, and then we can go in that
00:51folder to find out what the actual tip is.
00:54I can do ls -la .git/refs/HEADs, let's just do that, let's not do master, and we'll see
01:02a directory listing of all the branches that are listed there.
01:05When we add new branches this is where they show up, it adds a new reference in the HEADs folder.
01:11And if we take a look at what's in that, .git/refs/heads /master, you can see that that contains the SHA that
01:19points to a commit, that is the tip of the current branch --oneline, so there it is.
01:25So you can see that it points to this one right here.
01:28So now that we have a good foundation for what's going on with our existing branch,
01:32let's try creating a new branch.
01:33We do that with the git branch command again, but this time, we just provide the name of the new branch.
01:39I'm going to call mine new feature, you can call it anything you want.
01:42There can't be any spaces in there, and you will want to stay away from punctuation.
01:45You want to keep it simple with basic letters, numbers, and underscores.
01:49So git branch new_feature, I hit Return, and it created the branch for me.
01:53How do I know that it did that? Well, git branch, there it is.
01:57I'm still on the master branch. That's still the one that's checked out, the one that I'm working on.
02:02HEAD still points to master right now.
02:04We're going to talk about switching branches in the next movie.
02:08Before we do though, let's just go and take a look at what was created in our git folder;
02:11ls -la .git/refs/heads, and there we see it.
02:17Now there's a new reference for it in the refs/heads for new feature.
02:21What do you think that points to? .git/refs/heads/new_ feature, it points to the exact same commit right now,
02:31because I haven't made any other changes. It still points to the same commit.
02:36They now have two branches pointing at the same commit.
02:39Once we start making changes to each of those and making new commits, well then those values will change.
02:44Let's take a look at .git/HEAD, and we'll see that it points to master still, that's
02:51still the branch that we've checked out.
02:53In the next movie, we'll talk about how we switch to the new branch.
Collapse this transcript
Switching branches
00:00In the last movie, we created a new branch called new feature,
00:04but we haven't switched to it yet.
00:06The currently checked out branch is still master, and we know that because we can say
00:10git branch, and it gives us a list of the branches and puts some asterisks next to master
00:15to let us know that that's still the currently checked out branch, that's what's in our working directory.
00:20We saw that we can also take a look at the .git file to see where the HEAD points, and
00:26we can see that it also points to the master branch as well right now.
00:30So let's see how we check out the new branch.
00:32We do that by checking out the branch, so git checkout is the command that we're going
00:37to want, git checkout followed by the name of the branch, git checkout new_feature.
00:42And we hit Return, it comes up and tells us that it switched to the branch new feature.
00:48Git branch now confirms that we've made the switch, and if we take a look at cat .git/HEAD,
00:54we'll see that it also now points to the new_feature branch instead.
00:57Now at this point, they both point to the same commit.
01:01We haven't made any new changes to master, we haven't made any new changes to new feature,
01:05so the tips of those still are absolutely identical.
01:08If we switch between them, no files change in our working directory.
01:12Let's add a commit to new feature.
01:13Let's just open up index.html, and where it says Welcome to Explore California in the
01:18title, let's just add Affordable Outdoor Tours, Save that, git status.
01:27We can see that it's here and our changes are not staged for commit.
01:30I'm going to commit it, and I am going to use the -a option, which will take all of
01:34the changes that are in my not staged for commit, and commit them all at once, and automatically
01:38add them as well as commit them, and let's call this modified title of index.html.
01:47So now we have that commit made.
01:49Let's take a look, git log --oneline.
01:53We can see it, Modified title of index.html,
01:55here is the commit number, dc9c83c, so now let's do git checkout of master.
02:03Switch back to the branch master, we can confirm that with the git branch.
02:07Now let's do git log --oneline, oop, typo there.
02:15Now you can see that it's not there anymore.
02:17380f is the last one, which was the second to last one here.
02:21So we have a new commit that's on one and not the other.
02:23And now that we're on master, let's go back and take a look at index.html.
02:28Welcome to Explore California, let's close that file up.
02:31Let's switch our branch again, git checkout new_ feature, switch back to the branch new_feature.
02:38Let's open up index.html again.
02:40Notice that it changes back again, this is the fast context switching that I was talking about.
02:44It's that easy to just swap out all the files and folders in your working directory just
02:49by typing checkout a different branch.
02:52In the next movie, we're going to see how we can both create a branch and check it out
02:56at the same time.
Collapse this transcript
Creating and switching branches
00:00So far we've seen how to create new branches, and we've seen how to switch between branches.
00:05In this movie we're going to take a look at how we can both create and switch branches
00:08at the same time so that we don't have to type both commands.
00:11Let's just review, we do git branch, we're on the new_feature branch that we created,
00:17and if I do git log --oneline you'll remember that this is the new commit that I made right here.
00:23I modified the title of index.html.
00:26I can also take a look at that commit with git show, and I can either copy and paste
00:31the SHA that references it, or the HEAD pointer points at that commit right now.
00:36So git show HEAD will show me that change, it'll show me that commit and what I changed.
00:41So let's say that the change we want to make now is we want to make a new branch where
00:44we want to try out shortening the title, the title now has gotten to be very long, and
00:50we're going to try to shorten it.
00:51So what we're going to do is create a new branch and check it out at the same time.
00:54What we're going to do is use the checkout command with the -b option;
00:59-b means both created and switch at the same time.
01:03You can think of it as check this out as a new branch, it's a little bit counterintuitive,
01:08you might be thinking well the branch is the thing that creates the new one.
01:11Why am I not using the branch command? It's not that way, it's the checkout command.
01:15Put this stuff in my working directory as a new branch, that's what it's telling it.
01:20Now we need to give our branch a name.
01:22The first branch we created we just called new_ feature which is pretty generic and not very useful.
01:26You want to try and give your branches useful, meaningful names so that when you look at
01:29them in your branch list you'll know what they refer to.
01:32So we're going to call this one shorten_title, that should be pretty clear what we were trying to do.
01:38So switch to new branch shorten_title, it created it and checked it out and switched
01:42to it all at same time, and we can see that with git branch.
01:46So now we are on our shorten_title branch.
01:48Let's do git log --oneline, and notice that it includes the commit that we made to the
01:55new_feature branch.
01:56What we did was we didn't make a branch off of master, we made a branch off of new_feature.
02:01So we were on new_feature, and if that's the branch that we were on at the time, if that's
02:05where the HEAD is then that's where the branch will be created off of.
02:08I could've switched back to master and then created the branch from there, and it would
02:12not include that commit, the dc9ca3c commit.
02:17But I wanted that commit in there, I wanted the long title because now I am going to try
02:20and shorten that title.
02:22So let's do that, let's open this up and inside index.html you can see that the change is
02:28there, and I am just going to take out the Welcome to.
02:30We're just going to make this Explore California - Affordable Outdoor Tours, that's a shorter
02:35title, and that works for us.
02:36So let's save it, close it.
02:38Now we know how to make basic commits, git status.
02:42Before we add this and make the commit I just want you to notice here that checkout was
02:46the command that we used earlier when we wanted to discard changes in the working directory.
02:50And remember at the time I told you that we use the dash dash to make it unambiguous that we are
02:56not trying to check out a branch, we're trying to check out just the file.
03:01So dash dash says from the current branch, that's what it's telling us, don't change branches, that's
03:06not what I am trying to do here to check out. I'm trying to just check out the file.
03:09So checkout essentially does double-duty for us. It'll checkout branches, but it'll
03:13also go to the repository and checkout files for us.
03:16Essentially checkout is saying, put this stuff in my working directory.
03:20So now let's add it, so git add index.html,
03:24git commit, and we're going to give it a message "Shorten the title of index.html."
03:32That describes what my commit does.
03:36Now if we say git log --oneline, you can see here it is. I have my dc9 commit followed by
03:42the 6a2a3f5 commit.
03:46If we now git checkout our new_feature branch, and we do our git log --oneline, you'll see
03:54that it's not there.
03:56If we do git checkout of master, and then we output our log file, you'll see that neither
04:04one of those is there.
04:05So you can switch back and forth to these, and each time go check and see, take a look
04:09at what's inside index.html and see the difference between them.
04:12You also can check out the shorten_title branch and use that git log with some of those
04:19options that I gave you like --graph, --oneline, --decorate, --all.
04:27And notice now it gives me the different commits, and you can see that it shows me the tip of
04:32each one of those branches; master has this tip, new_feature ends with this one.
04:37Right now, HEAD is on the shorten_title one, and so both of those point to this last commit.
04:43Feel free to switch between branches, make more commits until you get comfortable, and
04:46you really understand how the switching works because it's something that you're going to
04:49be doing all the time in git, and you really should feel comfortable with it.
Collapse this transcript
Switching branches with uncommitted changes
00:00We now know how to switch between branches in Git, and we also know that the process
00:05of doing that is to use the checkout command, and what the checkout command does is it tells
00:09Git to go and get the latest version of the branch and to make our working directory look exactly like it.
00:16There is one thing that you need to be cautious about with that, which is that your working
00:19directory must be clean in order to switch. Actually, mostly clean. We'll talk about that later,
00:25but if it's not clean, then Git won't let you do the switch.
00:28Let's take a look.
00:30Right now, I'm on my shorten title branch, I do git status, you will see that right now
00:35my working directory is clean.
00:37Let's make a change.
00:37So I'm going to make a change to index.html,
00:40open it up, and in the same line that I changed before, I'm going to change the
00:44hyphen to be a colon.
00:46I am going to save my changes and close it.
00:49So now we have an unsaved change, not stage for commit or anything, just sitting in our
00:55working directory.
00:56Let's try switching to our master branch, git checkout master, just clear my screen so it's at the top.
01:03Now it pops up, and it gives us an error, it says, your local changes to the following
01:07files would be overwritten by checkout: index.html. Please, commit your changes or stash them
01:13before you can switch branches. Aborting.
01:16Git is telling you, sorry, I can't do this, because if I do, if I make your working directory
01:19look exactly like master, you're going to lose the changes that you just made.
01:25So rather than destructively just blow out your changes, which you might want to keep,
01:29you might not have realized that this was going to a problem, Git stops and does the
01:33safe thing, and it says you need to deal with this problem first.
01:36You have three options at this point.
01:38One, you can scrap the changes by checking out the file again.
01:42That's git status git checkout -- and the file name.
01:46The second thing you can do is you can commit the changes to the current branch. Once they're
01:51committed, they won't get lost anymore.
01:53They're stored in Git, we can just switch back and forth between the branches, and it
01:56will just switch back and forth between the HEAD of each one of those branches.
02:00The third possibility is that we can stash the changes, and we'll talk about the stash
02:04a little later on.
02:05Basically it's a little pocket that we can put things in and save them until later.
02:09We can put them away to a little area that we can pull them back when we're ready.
02:13So for now, let's go ahead and just commit this, git commit, and we'll use the -a option
02:19to both add it and commit it at the same time, and then give it a message, we'll say, Swap
02:25Out - for : in index.html title.
02:32So now, we've made our change, we can now checkout master, no problem.
02:38We can checkout our shorten title, and it switches back and forth between those just fine.
02:44Now I said it has to be mostly clean, because it doesn't have to be completely clean. It
02:48just has to be clean enough that there are no conflicts.
02:51So for example, let's say that I put a new file in here, tempfile3.txt, just any file will do.
02:58Now if I say git status, we see that we are on our shorten title branch, and you can see
03:04that here's the file, tempfile3.txt that's untracked.
03:08If we say git checkout master, it said no problem, I have no problem switching for you.
03:16git status, now we're on branch master, still have this untracked file.
03:19So that's what I mean when I say mostly clean, we can't have anything that would cause us
03:23to lose data if we made the switch.
Collapse this transcript
Comparing branches
00:00In this movie, we're going to talk about how we can compare branches.
00:03Now we saw in the last chapter, we talked about navigating the commit tree, so we could
00:07use the git diff command in order to compare two different tree-ish objects.
00:12And at the time, I told you that a branch was one of the tree-ish's that we can pass
00:16in, but we didn't have any branches back then.
00:19Now we have some branches so let's try comparing them.
00:21Use git diff, and then we just pass in the names of the branches.
00:24Let's remind ourselves that those branches are real quick.
00:27There is a list of our branches, and I'm on the shorten title branch, let's say git diff
00:31master..new_feature.
00:34So I'm going to compare master with new feature by using that range operator in between, dot dot.
00:40So master compared to new_feature, and it comes up and tells me what are the differences
00:44between the tip of master and the tip of new_feature, the most recent commits there. That snapshot.
00:50So I now can very easily see what changed between the two versions.
00:54Try it again with master and shorten_title.
00:57So there is what changed there.
01:00That includes those changes that were made in the new feature branch, remember because
01:05shorten title is a branch off of new_features, so it has all of those changes as well.
01:09And of course, we can do the intermediary step git new_feature compared to shorten title.
01:15The order of these doesn't really matter.
01:16Let me just show you, let's do that one again, and now let's just flip them around, let's
01:20do git diff shorten_title..new_feature.
01:25It'll show us the exact same diff, it just flipped them around.
01:28It changed which one was the a or minus and which one is the b or plus.
01:33So that's all it did.
01:34Typically the one that's further back in time, you would make the one that comes first, and
01:39the one that comes later would be the one that made second.
01:41But time can be kind of tricky when you start working with branches and different commits
01:45are being made at different places.
01:47So it really is just about which one you want to be the old state, and which one you want
01:51to be the new state.
01:53Another nice feature that we can use with diff is colorwords option.
01:57So let's go with this one, the new_ feature..shorten_ title, and let's add in --color-words, with a space.
02:06Now it comes up and shows with the same diff, but it shows it to us all on oneline.
02:10So that might be a little clear for you as to what changed, instead of having the two
02:13lines, one above each other.
02:15It's really matter of personal preference for which one you like better.
02:18Now of course, what we are passing in here is not just a branch, we are passing in a tree-ish.
02:24We talked about tree-ishs.
02:25A tree-ish can be a lot of things, it can even include the ancestors.
02:29So for example, I can compare new_ feature with the previous commit to the HEAD of shorten_title.
02:36So go to shorten_title, and it's not the last the commit, it's the commit right before that,
02:40that I want to compare it to.
02:42And we can see that what changed was I took out the words, welcome to.
02:45There is one more important way that we can compare branches, and that's that we can find
02:49out, whether one branch completely contains another branch or not.
02:54That is whether or not everything in it has been merged into the current branch.
02:59We do that by not using the diff tool but using git branch with the dash dash merged option after it.
03:06That will show us all branches that are completely included in this branch.
03:11So in this case we're on the shorten_title branch, all of the commits that are in new_feature
03:16are also in shorten_title, all of the commits that are in master are also in shorten_title.
03:21What that lets us know is that we can actually delete new feature if we wanted to and shorten_title
03:25wouldn't be affected.
03:27Shorten_title has all of those commits in it.
03:29Let's try switching to different branch,
03:31git checkout new_feature, surround it again, git branch merged.
03:37Now it says, all right, new feature doesn't have all of the commits that are in shorten_title.
03:41Shorten_title has some things that are not merged into here yet, we would need to do
03:45a merge to get those changes into new feature first.
03:49What it actually does is it goes back up the ancestor chain of the new_feature branch to
03:54see does it have the tip of master in it.
03:57If it has that final commit of master, then it has all of the ancestors as well.
04:02It does not have the final commit of shorten_title so it doesn't list it here.
04:05And just for good measure, let's do checkout master, and we will do the same thing there,
04:10and you see that master doesn't contain those changes that are in new_feature and shorten_title.
04:15So well, it's not strictly speaking comparing branches, the same way that diff does, I think
04:19it's important way to get some information about the comparison of the content of what
04:23is in each of the branches.
04:24Those come in very handy soon, when we start trying to delete branches.
04:28
Collapse this transcript
Renaming branches
00:00In this movie, we're going to learn how to rename branches.
00:04We saw how to create branches already, and we created a few.
00:07Git branch will show us the list, you can see I've got master currently checked out, and
00:10I have also got the new_feature branch and the shorten_title branch.
00:14Now shorten_title is pretty descriptive, you can kind of guess what that's about, especially,
00:18if there's 10 different branches, you can kind of pick out which one it is.
00:22But new_feature that's really vague and not at all descriptive.
00:26So it's much a better idea to give these a very descriptive name letting us know what they do.
00:31So what does the new_feature branch do? Well, I made it off of master.
00:35So let's take a look, let's see what it does.
00:37Let's do git diff master..new_feature.
00:43So that shows us what it does.
00:45What it does is it adds that chunk of text right after Welcome to Explore California.
00:50We were just sort of adding text at that time but in the real world, we have to ask ourselves,
00:54well, why were we hitting this text? What were we trying to do by adding it.
00:57Were we trying to be more descriptive? Were we trying to improve our search engine results?
01:01Let's says that it's the second one.
01:03Let's say that we're trying to improve our search engine results.
01:06That's a process called search engine optimization, or SEO for short.
01:10So what I am going to name this new branch that's more descriptive is going it be SEO title.
01:15I am going to give it SEO title to let me know that that's what I was up to.
01:19So the way that we're going to rename the branch is we will say, get branch -m for
01:25move, or we can also use the full word with two dashes, --move like that.
01:29Usually, you just use the one.
01:30So get branch move, and I'm going to move the new_feature branch to a new SEO title.
01:39Now it's not actually moving it, it's renaming it.
01:41As we saw earlier when we were working with files in Git, they are really the same thing.
01:45Git considers a re-name to be a move, the same way that UNIX does.
01:50So if we say git new_feature seo title, and we do git branch, we see our list, now we see
01:56our seo_title branch. So that's it.
01:59That's all there is to renaming branches.
02:01Just be sure that you do give your branches good names.
02:04Names that help you to distinguish what they're all about.
02:06Now if are working in a large organization, and you're doing, let's say, trouble tickets
02:11where you are fixing bugs and things like that, there might be some kind of a support
02:14ticket attached to it.
02:15In that case, maybe you want to name your branch with the ticket name, maybe it's ticket
02:20375 something like that,
02:22but you want some way that you can look through at a glance and pick out the branch that you're
02:26looking for.
Collapse this transcript
Deleting branches
00:00We've learned how to create branches, now we're going to learn how to delete them.
00:04I've already created several branches, git branch will show that list.
00:08Now regardless of whether you've the same ones as me or not, make sure that you switch
00:12to the master branch, so that's git checkout master.
00:15That will put you on a master branch with me.
00:16Once you are there, we're going to create a new branch, git branch, and then we just
00:20provide the name of the new branch that we wanted to create.
00:23We're going to call is one branch_to_delete.
00:26That will make it nice and clear.
00:29So git branch will now show that in the list.
00:31Notice that I'm still on the master branch.
00:33I did not create it and switch to it, I just created it, that's important.
00:38So now we want to delete it.
00:39It's really simple; git branch with the lowercase d option.
00:43So -d or you can use --delete if you'd rather. Most people just use the lower case
00:49d, and then the name of the branch that we want to delete.
00:52So git branch with the delete option, the branch to delete.
00:56We hit it, deleted branch, branch_to_delete, git branch, now that branch is gone.
01:02And you may be saying wow, that's a pretty powerful thing! Obviously we would want to
01:06be careful and not accidentally delete something that we don't want to.
01:09That's certainly the case, anytime you are deleting anything, but git does have a few
01:13checks in place to make sure that you don't do something stupid.
01:17The first of those is let's create a new branch again, we will call it branch_to_delete a second time.
01:24So there it is, this time though, let's checkout that branch, get checkout branch to delete.
01:31So now I'm on that branch, now lets try delete it, git branch -d branch_to_delete, cannot
01:38delete it the branch that you are currently on.
01:40So if we are there, we can't delete it. We have to get off of this branch first, before it'll
01:46lets us delete it.
01:46So make sure that it's not deleting everything that's in our working directory and somehow
01:51leaving us stranded not on a branch.
01:53We have to get on another branch, and then we can delete the old one.
01:56You can think of it a little bit like if you are in the tree with actual tree branches,
02:00you wouldn't want to cut off the branch that you were on, you want to switch to another
02:03branch before you sawed off the other tree branch.
02:06So that's the first check that it makes.
02:08Let me show you the next check that it makes.
02:09Let's say that we make a commit to this new branch.
02:12So let's just do something real simple here, let's open up the index.html file, and let's
02:18change Welcome to Explore California to be Explore California: Tours and More.
02:26It's kind of silly but we have just been changing the title before, so we'll stick with that for now.
02:29It's a simple change we can make.
02:31We'll go ahead and commit that change.
02:33We'll use the dash -a option so that we don't have to add it in a separate step, and we'll
02:38just say changed title for now.
02:40We're going to delete this branch anyway, so it's not a big deal.
02:43So git log --oneline, now you can see that commit the we've made.
02:48So I am on now my branch_to_delete. It won't let me delete it while I am on it, lets get off of it;
02:54git checkout, and let's do master.
02:58So now I am switched to master, git branch will show me that I am on my master branch.
03:03Now let's try and delete that other branch,
03:05git branch -d branch_to_delete, it comes up and says, woah, woah, woah, hold on.
03:13There are some things in there that are not in the branch that you're on now.
03:18So I'm not comfortable just throwing away those commits.
03:21That might not be a smart thing to do.
03:23So you tell me if you really mean it, and you really want to do it, use capital D. Capital
03:29D will tell me that it's okay to throw away all those changes that are in that branch,
03:33but with lowercase D, it's sort of like we have a safety on it.
03:36It's going to check and make sure that we're not losing something.
03:39So the -D option, the branch must be fully merged into this branch with the -D
03:45option, then it'll delete the branch irrespective of its merged status.
03:50So now let's use the -D option to tell it we really mean it.
03:56Now it's deleted, git branch, and you can see that it's gone.
04:00So it's pretty easy to delete branches but luckily git does give you a couple of checks
04:04to make sure that you don't do something dumb.
04:06So always use the lowercase -d option first and then let git tell you, hey, I want to
04:11warn you about something before I actually do this.
04:14And then you can change it for the capital D option, if that's what you really need.
Collapse this transcript
Configuring the command prompt to show the branch
00:00Now that we understand the basics of working with branches, I want us to pause and add
00:05a little something extra to our configuration, and that is I want us to configure a command
00:10prompt to show us the branch.
00:11This is not strictly necessary, but I think at some point, most Git developers choose
00:16to do this, so it's worth us doing here.
00:19Now the command prompt is this bit that's right here at the beginning.
00:22So every time I hit a Return it prompts me with a bit of text.
00:26Yours almost certainly looks different than mine, because I have already configured mine just to say
00:29Kevin with the dollar sign after it.
00:32What we're going to do is have that include our branch name as well.
00:36So that way it will always tell us which branch we are on.
00:39Every time we enter a command the current branch is sitting right there at the beginning
00:42of the line, and that will help to make sure that we don't end up in a feature branch when
00:47we actually meant to be on our master branch.
00:49We will take a look at this in two parts.
00:52First we will look at the Unix side of things, that's for Mac OS X and Linux, and then we
00:55will look at Windows.
00:56The first thing you want to do if you are on Mac or Linux is to make sure that you install
01:00that Git Completion Script that we had at the configuration.
01:03You remember we put that into our root directory here, .git-completion.bash, and then we also
01:10made an entry to load it in either our bash_ profile or a bashrc file, so one of those should be
01:16loading in git-completion.
01:18And the reason why we want that file is because that file declares a function that we are
01:22going to want to use.
01:24That function is __git_ps1.
01:28You can just type it from the command line, and it will then return to us the name of
01:32the branch that we are on.
01:33If we swap branches, well then that would change to show us the current branch.
01:37So this is the function that we are going to use, and we're going to use that inside our prompt.
01:42If you are not in the Git directory, let me just go backwards into my Documents folder,
01:46it's where I am now, see I'm just in Documents, now if I do, __git_ps1, it doesn't put anything there at all.
01:52So it's only when we are in a Git directory that it does that.
01:55So let's go back into cd explore_ california/, and we can configure our prompt.
01:59And let me stop to give you a quick tutorial about prompts in Unix, if you don't already know.
02:04The prompt is stored in a variable called PS1, that's for Prompt String 1, and we can
02:09see our current value of Prompt String 1 with echo and then a $PS1.
02:15That comes back and tells me what it is mine is the literal characters kevin$.
02:18Yours will likely include some letters and symbols that represent dynamic data, and you
02:23can have all sorts of things in your command prompt, you can have it show the current time,
02:27the date, you can have it show the current directory you are in, all kinds of things.
02:31You can Google for information about all things that you can do with it.
02:34If you want to set your prompt to something else, the way you want to do that is with
02:37export PS1, no dollar sign in front of it this time, equals, and then inside single quotes
02:44we can put whatever we want the prompt to be.
02:45But let's just make it a bunch of arrows.
02:48So now that's our prompt, or we can make it some dashes with an arrow, that's our prompt.
02:54It can be absolutely anything we want.
02:57So mine was the literal characters, kevin$ with the space after it.
03:03The space is important because it's going to determine where we place the cursor.
03:06So that's the basics.
03:07So now let's actually use that function and set it to what we want.
03:10So I am going to just erase all of this, and we are going to put inside these single quotes
03:15is we want to do a command substitution.
03:17So we do that with $(__git_ps1) and to that we are going to pass a format string, for
03:27how it auto format things.
03:28So we will put that inside double quotes and then the important part is that you have %s,
03:34that's where the branch name is going to go.
03:37Around that %s I am going to put parenthesis so that's what I want to have around mine
03:41is just some parenthesis.
03:43You can do something different.
03:43If you want square brackets or curly braces, anything you want, this is how it's going
03:48to format that output.
03:49And at the end, after that command styling, I am going to have it put a space and then
03:53arrow and a space.
03:54Let's go ahead and just hit Return, and you will see that's what it gives me now.
03:58For every one it just tells me what branch I am on.
04:01In addition to that, you can put other things in here, you can look up how to configure
04:05your prompt and customize it to your heart's desire.
04:08The way that I do it, and what I am going to have you do and recommend for you, is to use
04:12\W, and that's going to be your current working directory, not your working directory in Git
04:19but the working directory that you are in Unix.
04:22So when we hit Return, you will see it tells me that I am in the explore_california directory.
04:25If I go backwards one, it tells me I am in Documents with no branch after it.
04:30So that's kind of nice.
04:31So suddenly you go into a Git repository and the branch just appears appended at the end.
04:38So it tells me I'm in explore_ california, and I have the master branch.
04:43This works great except as soon as I close this window that's going to go away, that
04:47export command that I did right here is only active as long as this window is still active.
04:54In order to keep it around I need to copy this, and then I need to edit my bash_profile
05:01or my bashrc file.
05:04So here we are, I have bash_profile as what I am using, if you are using a bashrc file
05:09instead, that's fine.
05:10The way I am going to edit that is just with nano, nano .bash_profile, and you can see
05:16that I already have a declaration here that I was using before, I am going to take that
05:20out, I am just going to put in our new one, but I need to put it after I've loaded in
05:25the source code for git-completion.bash.
05:28You can load it inside the if statement if you want or you can load it outside, either one.
05:33This will just make sure that it is declared first, so it's not a bad idea.
05:37And then Ctrl+X, Yes to save changes, Return to keep the file name, and now it will be
05:43there every time I load up a new window.
05:45Let's just test it to see.
05:46I will close that window and open a new one, and there I am, cd into Documents/explore_california,
05:52and it tells me which branch I'm on.
05:55Git branch, see the list of branches, git checkout and then let's do a seo_title, and
06:02now switch to seo_title, and that's what it tells me each and every time.
06:07Now I want to show you how to get set up on Windows.
06:08Now it may be super simple for you to set up on Windows, because you may already have it installed.
06:14When I installed my version of Git, it went ahead and installed the git-completion script,
06:19and that Git Command Line prompt, and went ahead and set my prompt for me so that it shows it.
06:24You can see here explore_california, and it tells me that I am inside my master branch.
06:28So you may have already been seeing this all along.
06:31Now if you aren't for some reason though, we can still set it up.
06:34It's the exact same thing, let's take a look, echo $PS1 will show what it's using currently,
06:40and you can see that there is some additional stuff here, there is / with some numbers after
06:44it, that does the code coloring. That's what it allows it to be green and yellow and things like that.
06:49We can leave those in or take them out, it's also got my username and @ sign and the host
06:54name, that's the screen part here, followed by the part that we were installing here on Mac.
06:59Now if we want to do it ourselves we can do __git ps1 to see that it returns the same
07:08thing to us, and if we want to set our command prompt, the PS1, if we want to make it permanently
07:13be something different we can also do it that with our bash_profile.
07:17Now you probably don't have a bash_profile here unless you have created it for some other
07:21reason, but we can create it.
07:23On Unix we would use the nano command in order to have a simple text editor, here we are
07:28going to need to use Notepad, we can just find Notepad here from our Program menu, it
07:34will open up, and we can type our command right here.
07:36So export PS1= and then inside single quotes, we are going to type \W$ and then inside parenthesis
07:47I will put our Git command, __git_ps1, space, quotes, parenthesis, and make sure I got that
08:00right, and then I also want to have a caret at the end.
08:04So there is the same command that we had before, and then when I am done with that, I need
08:08to save it as, and I want to save it in my Kevin Skoglund directory, that's my user directory,
08:13and I want to call it .bash_profile, and I want to make sure that Save as type is set
08:20to be All Files, so it won't put any kind of extra file extension at the end.
08:24It will just be called bash_profile.
08:26So let's save that, and we can come back over here.
08:29If we do ls -la on our user directory, which is the tilde, we can scroll up here, and we
08:37can see that bash_profile is right there.
08:40Now in order to run that bash_profile script, we could either close this window and start
08:44a new one, or I can actually just type source ~/.bash_profile, and now it runs that command
08:53and sets my prompt to be what I want it to be, which is just to have explore_california
08:58and then the branch name after it.
09:00So now it looks exactly like the Unix version.
09:02This one was all colored, it broke to a new line afterwards, you can keep that one if
09:06you like but my version now is going to be exactly like the Unix one.
09:11
Collapse this transcript
11. Merging Branches
Merging code
00:00In the last movie we got the basics of working with branches, and by now you should be able
00:05to create a new branch off of your master branch and use it to try out new ideas or
00:11implement new features.
00:12What about when you done with it? What about when your idea turns out to be successful
00:15or the future is finished, and you now want to bring those changes back into the master
00:19branch so that they're part of the main project? Well, in order to do that we need to merge
00:24them back in, and that's what we're going to learn how to do in this movie, how to bring
00:27those changes back in by merging one branch into another.
00:31So at the moment, I'm on my seo_title branch, and we know that because in the last chapter
00:36I installed this command prompt that will show me what branch I'm on.
00:39So I'm on seo_title, let's remind ourselves what the other branches are, we have the master
00:44branch and the shorten_title branch.
00:46What I want to do is I want to merge the changes that we made from SEO title into the master branch.
00:52Now if you don't member with those changes were, we know how to do that, diff master..seo_title,
00:59and there's the changes.
01:00We just added this bit of text here at the end.
01:04So what we are going to do is bring that change back into master so that it exists there as well.
01:08The first step is that we want to make sure that we checkout the branch that things are
01:12being merged into, the receiver.
01:15So let's do that.
01:16Let's do git checkout master.
01:19So I am in the master branch now.
01:21So the master is going to receive the changes that are in seo_title.
01:25So from the master branch I now tell it, git merge seo _title. It is that easy, just git merge seo_title.
01:33And it says, updating fast-forward, tells me summary of the changes that were made, and that's it.
01:39Let's take a look now, let's say git log, this is the master branch log, and look here,
01:44the top commit here is modified title of index.html, and sure enough, if we now go here, and we
01:50open the index.html, we will see that our changes are in fact there.
01:54So it took the commit that was an seo title, but it did not have that snapshot of changes,
01:59and it brought that change into the master branch.
02:01So in the simplest of cases that's all there is to merging.
02:04You check out the receiving branch, then you say git merge and then the target branch or
02:09the sending branch where you're going to be getting those changes from, and that's it.
02:13So one last step that I want us to do is let's just clear our screen, and let's do our git
02:17diff again, this time between master and seo_ title, and it comes back and tells us that there
02:24is no difference between them.
02:25If we were to use git branch --merged, which we also learned when you are comparing
02:31different branches, it'll tell us that seo_ title is fully incorporated into master.
02:37If we wanted to, now we can completely delete seo_title.
02:40We can do with the lowercase d option, and it would be deleted.
02:43Now there is a one good tip, merges can be complicated, merges can get hairy, and we're
02:48going to talk about what to do in those cases in the upcoming movies.
02:52Because of that, you always want to run git merge with a clean working directory. You
02:57don't have any uncommitted changes, you want to go ahead and get all of those out of there.
03:01You can stash them, which we will learn how to do later, you can go and turn them into commits,
03:04but have a clean working directory, and that will give you a good clean workspace where
03:09you can sort out problems with your merges.
Collapse this transcript
Using fast-forward merge vs. true merge
00:00In this movie I want us to understand the difference between fast-forward merges and real merges.
00:05When I first gave you an example of what a merge looks like,
00:08I said that it looked something like this, and then we made a merge commit that brought
00:11those two branches back together and did it with a new commit.
00:16But that's not what actually happened in the last movie when we did our first merge, and
00:19the reason why is because this isn't really representative of the state of our two branches at that time.
00:25We hadn't made additional changes to master yet.
00:27It actually looks something more like this.
00:30So we had made our branch, we'd made another commit on that branch, but we had not make
00:35any changes to master, as a result, it did a fast-forward merge.
00:39You may or may not have noticed, but it actually came up and told us that when we did the merge.
00:44What happens is when git goes to do a merge, it takes the thing that you're merging in,
00:48and it starts at the end of it, and it looks back at all of the ancestors, all the way
00:52back up to the beginning.
00:53So in our example here, it starts with ba8ce and then goes to 534de, all the back to get
00:59to 84c46a, all the way down the chain.
01:03And along the way, it looks to see whether it has the HEAD pointer of the current master branch.
01:09In our case, the HEAD pointer was pointing at the commit where the branch was made, no
01:13movement had been made.
01:15If it does that, if in the chain of ancestors it sees the HEAD, it says oh, I'm safe to
01:19do a fast-forward merge.
01:21I don't need to do that fancy merging and make a new commit, instead what I can actually
01:26do is I can just move that commit up into my timeline and move the HEAD along to it.
01:32Now revise_navigation also points to the same thing, they both point to ba8ce.
01:37There was no need to make a new commit. You could just fast-forward along the chain and merge that way.
01:44So we know that that's true, because we can do git log seo_title --oneline, and then let's
01:50just look at 3 of those lines.
01:53Now notice that the top commit here dc9c83c, that's the thing that had changed before in
01:59seo_title, that's what we merged in to master.
02:02So let's take a look now at master.
02:07See the same commits here, it's got the same SHA, it's the exact same object stored in Git.
02:12It did not make a new commit in order to merge these two together, it did a fast-forward.
02:17Now there are a couple of options with merge that are related to the fast-forward.
02:20The first is the no-ff option so that would be git merge --no-ff and then whatever branch
02:28you were trying to merge.
02:29The no-ff option forces Git to create a merge commit anyway.
02:34It says, don't do a fast-forward, make a new commit with the commit message anyway.
02:38And the main reason you'd want to do this is if you wanted some kind of documentation
02:41of the fact that you did do this merge.
02:44You didn't want it to just quietly do it, you wanted it to sort of make some noise in your git log.
02:49The other option you should know about is the ff-only option.
02:52Don't get those confused, no-ff says don't do a fast-forward, ff-only says do the merge
02:58only if you can do a fast-forward.
03:01If you can't do a fast- forward merge, then just abort.
03:04Don't try and do it at all just exit.
03:06So we won't do either one of those now, but those are useful options to know.
03:08All right, so now as a contrast, let's try an example of a true merge or a non-fast-forward merge.
03:15Let's take a look at our branches, so we've already merged in our seo_title branch.
03:20What I want to do is I want to merge in our shorten_title branch and make those changes.
03:24Now if we were just to merge it in the way that we did before, git merge shorten_title,
03:28it would do a fast-forward merge.
03:31Why is that? Well, it's because the only object that's different between them is the one commit
03:35now that master doesn't have.
03:37There were two commits; the master was missing before, now it's only missing one, and it
03:40would just fast-forward one more time.
03:43Instead, we need to make it so that it's non-fast- forward, and the way that we do that is we need another
03:47commit on master.
03:49If there's another commit on master, then it'll no longer be able to just fast-forward,
03:54because now HEAD will have moved to a new commit that is not in the shorten_title branch.
04:00So let's try that.
04:00You want to make sure you're on your master branch and then let's edit our contact.html,
04:04and you see it says Export California: Contact Us, let's take out the us, so it's just Contact.
04:11Close it up, clear it, git status, so we have our contact file there, git add contact.html,
04:19git commit -m and "Edit contact.html title".
04:27Okay, so now we've made our commit, git log --oneline, and let's just look at 3, so there it is.
04:33Now we have a new commit that comes after this dc9 commit, so git log for the shorten_title
04:38branch, so let's just take a look that one real quick.
04:42Notice now it has that commit here, but then there are two commits that come after it.
04:47So we've got a common ancestor, but right now HEAD is pointing here, and it's not one
04:52of the ancestors of the shorten_title branch.
04:55So it won't be a fast-forward merge, it'll be a true merge.
04:57The process is the same though.
04:59We just say git merge shorten_title.
05:03Now Git popped up, and it asks me to provide a commit message here, that's because I had
05:07configured it to have TextMate as my default editor. It may have popped you into a different
05:11editor, or it can be configured so that it doesn't give you the opportunity to edit it, that
05:16it just goes ahead and makes this commit with this commit message, Merge branch shorten_title.
05:21All of these lines are going to get ignored and left out of the commit message.
05:24So I'm going to go ahead and accept this, so I'm just going to hit Save and close it,
05:29and it says, Merge made by the recursive strategy.
05:33So merge has different strategies for merging, recursive is typically the one that you're
05:37going to see there, and it figured out how to make a merge between the two.
05:40If you take look at the log for the master branch now, you'll see that we've a have a
05:44new commit, Merge branch shorten_title that comes after that one, and that is the
05:49commit that ties these two items back in together.
05:52And sure enough, if we take a look over here, our contact.html page is what we would expect.
05:58And if we take a look at our index.html page, it is our shorter title here as well.
06:02Now may be wondering, what about the fact that the index.html was different in the master branch?
06:08Well, that might at first seem like it's a conflict between the two, but it's not, because
06:13the change to shorten_title branch was made after that. It has that as an ancestor, so
06:19it was able to resolve it, it was able to say, oh I see, later that thing was changed. There's
06:23a snapshot that addresses that change.
06:26So it wasn't any kind of conflict, the same way that it wasn't a conflict when we did
06:29our fast-forward merge.
06:30So hopefully that it gives you a better idea of the two ways that Git can handle merges, either
06:34by fast-forward or by doing a real merge, and it's pretty good at figuring out how to merge things in.
06:40However, sometimes there are merge conflicts. Sometimes there are problems that Git can't
06:44solve on its own, and it needs you to resolve them, and that's what we're going to look
06:47at in the next couple of movies.
Collapse this transcript
Merging conflicts
00:00We now know how to merge one branch into another and Git does a really good job at figuring
00:06out how to merge those together.
00:08For example, let's say that we've our index.html file and in the master branch we make a change
00:13to the top of the index.html file, somewhere near the top of html we make an edit.
00:17Then we have another branch that we're merging in, and we made a change near the bottom of
00:21the index.html file.
00:23That's not a problem for Git. Git sees those, it recognizes the line numbers and realizes
00:27that those are not next to each other, and it takes both of those changes and incorporates
00:31them into one composite document.
00:33Having two versions of a single document is not a problem, most of the time.
00:38However, a conflict occurs when there're two changes to the same line or set of lines in
00:43two different commits, because then Git can't decide which one to use or how to merge them
00:47together and so we get a merge conflict.
00:50And this is the one headache about working with branches is resolving merge conflicts.
00:55So let's first talk about what it is, and then we can talk about how to solve them.
00:58So just a quick example, let's say that we have our master branch, and we have a line somewhere
01:02in one of our HTML files this says Git is great, and it has <span> tags around it.
01:06From my master branch we create a new branch, we'll call it the new_styles branch.
01:10And we start making edits over there.
01:12We got all sorts of commits going on, at the same time we're switching back to master,
01:15and we're making edits back there as well.
01:18One of the edits that we commit to master is that we change the <span> tags into <strong>
01:23tags, and then we keep making more commits, we switch back to new_styles, we're making
01:26more commits over there.
01:28At some point, we make an edit in the new_styles branch so that we change the <span> tags into <em> tags.
01:35So now we've two different versions of this line. In the master branch it has <strong> tags
01:40around it, in the new_styles branch it's got <em> or emphasis tags around it.
01:44So when we go to merge new_styles back into master, Git doesn't know which one of these we prefer.
01:50Git says I can't choose between these. I don't have any idea what's your intention
01:54was, so I need you to tell me.
01:56So git will mark the conflict and wait for you to fix the problem.
01:59Let's try this in our explore_california project.
02:02The page I'm going to use to generate a conflict is going to be this mission.html page so just
02:06open that up real quick so you can see it.
02:09And what I want to do is I'm going to create a merge conflict in this text down here.
02:13So in order to that, we have to create the conditions that will make that happen.
02:16The first thing is let's make a new branch, so git checkout -b text_edits.
02:22Now remember, checkout -b is checkout as a new branch, or create a branch, and then switch to it.
02:29Now in my new branch let's open up mission.html, and this is just a text_edit branch, the idea
02:35here is it's a branch dedicated to making edits to the text.
02:37So I'm going to scroll down to that block of text, and let's make some edits here.
02:41We are passionate about Californian preserving the abundant resources that make it so unique.
02:45Our goal at Export California is transform your vacation into adventure that will educate,
02:48inspire, and energize you unlike any other.
02:50Let's take away unlike any other, it'll just energize you.
02:54Okay, that's good so that's an edit to line 65 right here.
02:57All right, now let's see line 66.
02:59Our tours are crafted around our central mission, and are deigned to engage you in a unique
03:02and fulfilling way.
03:03All our tours are sensitive to the environment, and will provide you will the opportunity
03:07to explore California in your own way.
03:08Let's say, they're, cut this, and we will say they're environmentally sensitive, instead.
03:14Okay, so environmentally sensitive, so we made edit to line 66, and then let's comedown here to
03:19line 67, let's change this quote here into being have.
03:23It's simply really, we'll leave that, and let's see, we ask ourselves one question, we'll
03:28say we ask ourselves a question.
03:31And I think that's good.
03:31Okay, so we have made an edit to line 67.
03:33So 65, 66, and 67 have all had edits.
03:36Let's make one to line 68, we have worked for a tour company.
03:40Okay, so now each one of those lines has some edits in it.
03:43So we could go on and you keep editing as much as you like.
03:46Let's now save that document and close, now we're on our text_edits branch, we know that
03:51we've made changes, we can see that with git status.
03:54So now we can do a commit, and we'll do that with git commit, and I will use the -am
03:59option, and then my message will be "Text edits on mission page."
04:06Okay, so now I've made that commit to my text_edits branch.
04:10So now let's go back and let's check out our master branch.
04:13All right, so now we're back in the master branch, this does not have that edit in there,
04:18let's go in to mission.html, and let's scroll down to that big block of text.
04:23You'll see that those changes that I made, like we've, right, those are all gone.
04:27We have the old version and the change that I'm going to make here is that I'm going to
04:30change the quotes here.
04:33See if we still have this up, these are straight double quotes.
04:35You can see those here.
04:37What I want to do is turn those into curly quotes.
04:40So let's go back here, and we'll make this one left double quote, and this one is right double quote.
04:45Okay, and let's while we are at it, let's go ahead and make this one &rsquo, and that will take
04:51care of that, let's copy that, let's paste that in here for the tours, we are basically
04:55just making all of these curly.
04:57Okay, so all of those have now been turned into curly ones. I may have missed some, in
05:01fact, here is one right here, and right single quote.
05:04Okay, so let's close that document now, and let's make this commit, git commit and
05:10"Replaces double quotes with curly quotes," actually I can do it with single quotes too,
05:18not just the double quotes, let's say, Replace straight quotes.
05:23Okay, so now let's remind ourselves what we have, git log --oneline, this is in the master
05:30branch, oops, some typo there.
05:33Replaces straight quotes with curly quotes is the merge that comes right after the merge
05:37with this shorten_title branch.
05:39If we check the same thing, put in our text_edits branch, you'll see that we have our shorten_title
05:46merge here, and then we have our new commit here.
05:49But those two commits change some of the same conflict.
05:53So let's try and merge now, so just to remind you, here are our branches.
05:56We're going to do git merge, and then we can say, text_edits.
06:02Says auto-merging CONFLICT, merge conflict in, and it gives us a list of all the things
06:08that have conflicts, mission.html.
06:10Automatic merge failed, fix conflicts and then commit the result.
06:14Okay, so now notice that my branch now says master and MERGING, right? I'm not fully on
06:20my master branch, I'm in the middle of a merge, it's letting me know that.
06:25Let's take a look, if we do git status, look what it comes up and tells me, unmerged paths
06:30right here, it tells me to use add and remove on them, to mark the resolution, tells me both have
06:35been modified, both versions of mission.html, and so nothing is ready to commit yet.
06:40I need to fix these problems.
06:42Let's open up mission.html, and let's scroll down to see how Git marked those problems, here it is.
06:50This is what is in the HEAD, which is remember, the master branch, the current branch that I'm on.
06:55And it tells me those lines, and then it's got a bunch of equal signs, and then it's
07:00got another block here, and it tells me that that's what's in the text_edits branch.
07:04So now it's up to me to go through and decide which one of these I want.
07:09But there are three lines that were different in each one, and each one had some conflicts in it.
07:13Now that we see how merge conflicts occur, and we see that Git marks them using symbols
07:18like this, we're ready to talk about how to resolve these merge conflicts, and we'll do
07:22that in the next movie.
07:26
Collapse this transcript
Resolving merge conflicts
00:00In the last movie we learned about merge conflicts, and we actually created one in our
00:04Explore California site.
00:06That's where we left things off. We left things in the middle of a merge, the merge has not
00:10yet been completed, and Git wants us to resolve these conflicts before it will go ahead and
00:15complete the merge.
00:16What I want us to look at in this movie is how we go about resolving these conflicts.
00:19You've three choices as to what to do to resolve these conflicts.
00:23First, you can simply abort the merge.
00:26You can say oops! That was not what I wanted to do, I was not anticipating all of these
00:30problems, get me out of here.
00:31We'll see how to do that.
00:32The second is that we can resolve the conflicts manually.
00:36Most of the time this is what you're going to do, and I think especially while you're
00:39learning how to resolve these conflicts, I think this is the one that you want to do.
00:43And then the third one is that you can use a merge tool.
00:46There're number of tools out there that will help you to resolve these kinds of conflicts.
00:50Now I'm not going to teach you any specific one of those, because there are so many, and
00:54my advice would not be go to a Merge tool until you've spent some time resolving them manually.
00:59So that you have an idea what the tools are doing for you, and you won't be entirely dependent
01:03on them in order to resolve merges.
01:06So let's look at the first one of these, aborting the merge.
01:08To abort the merge, while we're in this state, all we have to do is say, git merge --abort. That's it.
01:15Now notice I'm no longer in my MERGING state, git status, everything is clean, and if I
01:20do git log --oneline on my master branch, you can see that it did not bring anything
01:26else. This is the state of things right before the merge. So nothing got merged, I simply aborted it.
01:32Now let's do our merge again, git merge text_ edits, once again it did the same thing, created
01:37the same conflicts for us.
01:39This time we're going to soldier on, and we're going to resolve the conflicts manually, so
01:43the problem was in mission.html.
01:46So we can see that again, git status shows us that.
01:48What we need to do is we need to resolve the conflicts by hand in mission.html, and then
01:55add and commit the result.
01:57So that's what we're going to do. Let's open up mission.html.
02:00Now we saw before that the markers here, this arrows pointing to the left, going down to
02:05the equal sign all way down here to the arrows pointing to the right, is how we know where
02:11the conflicts are.
02:11If there had been several of these conflicts it would've marked each one of them.
02:14Maybe there's one at the top of the document, one in the middle, one at the bottom, and each
02:18one would be a section.
02:19So every time there's a problem, you want to just search your document looking to see
02:22where the first one of these is.
02:24So the best thing to do is here at the top of your document, you do a find and find three of those.
02:30So there we go.
02:30Now I know I'm right here at the first commit.
02:32Now you can go through these line by line and try and sort it all out.
02:36You also could do some research here. You can say, all right, let's go back, and let's
02:39remind ourselves if we do git log --oneline, let's just do 3 of those.
02:46All right, here's that commit. What was that commit all about? Let's see, git show, let's
02:51take a look at that commit.
02:52Okay, and you can look through there, and you can see oh, all right, I was doing the curly
02:55quotes here, that's really what changed was the curly quotes.
02:58So I know that what I need to do is I need to take the version that is in text_edits,
03:03this version, there're lot of text_edits in there.
03:06So I'm just going to take that and assume that that's the right one, so what I'm going
03:10to do is I'm going to go through and make sure that I get all of the curly quotes in there.
03:14So let's do--we'll take our single quotes, and let's come down here and look for single
03:17quotes that need to be changed, and here's another one, and I am not sure if I've got
03:24them all or not, but then I know I need to change this one, this is left double quote, this one is right double quote.
03:31Okay, so that looks pretty good, oh, here's another one, California's people.
03:36Okay, so now I have all of the changes in the text_edits version, this is the one I want
03:42to keep, so I need to actually remove this from the document.
03:47I'm now going to also remove the lines with the equal signs, come down here and remove
03:52the ending arrows as well.
03:54So now, the document is a regular HTML document, it has all of the changes in there.
04:00Let's save it, and let's go ahead and just open up Firefox and then reload the page.
04:04All right, so you'll want to inspect it and make sure that it all looks good, make sure that
04:08you're completely happy with the results, that the merge conflict has been resolved
04:12to your satisfaction.
04:13And once you're completely happy with it and all of the changes have been made, save it and close it.
04:18We'll come back over here, and we need to tell it that it needs to add mission, git
04:23add mission.html.
04:26Now git status, shows that it is ready to be committed, we're ready to do the commit.
04:30Now we know how to do a commit, git commit.
04:33Normally we'd put a message after it.
04:35You can put a message if you want to provide the commit message, but you don't have to.
04:39When you're in the middle of a merge, it has a standard default message that it would use.
04:44So just git commit by itself, and it'll use that default message.
04:48So git commit, hit Return, it in this case popped up and asked me, I'm going to remove
04:52this list of conflicts here because those are gone now, and then I'll just save that,
04:56close it, and it says, all right, Merge branch 'text_edits'.
05:00Now if we do git status, we don't have anything in there.
05:03Let's do git log --oneline.
05:05Let's look at just the last 3, or I'll do the last 4.
05:09Now we see we have our merge in there, it has that merge commit, and if we ask it git branch
05:14--merged, it does list text_edits as being fully merged into the master branch.
05:20So that's it, that's the steps.
05:22You open up the files that have a conflict, find the spot where there are problems, manually
05:27fix them, do that for all the files that had a conflict.
05:29If there were 20 files that had conflicts, you'll do it for all 20 of them.
05:33Then add those files to the staging index, and when you're ready git commit will complete
05:38the merge and all those merge conflicts will be resolved.
05:43One last thing I want to show you, if you remember I told you that there was this nice
05:45future in git log where we could use --graph, git log --graph, and we'll use a couple of
05:50other options; --oneline, --all, -decorate, here we are.
05:53So if we use all of these together, look what we get. We get a nice showing of the different
05:59branches and what happened.
06:00Here's the shorten_title branch.
06:02You can see where it got folded back in.
06:03Here's our merge commit right here that does that.
06:05You see, this was a fast-forward one for the seo_title, so it doesn't branch out, it doesn't
06:10need this merge commit here.
06:12And then we've merged this one back in here, so you can see text_edits is still at this
06:16point in time and the HEAD and master have this merge commit in them as well.
06:20So it's nice because it gives you a graphical representation of what you've been doing with
06:24all of your branching and merging.
06:26Now of course, I mentioned there was a third option which is that you could use a merge
06:29tool when you're in that state where you're in between merges, and it hasn't been resolved,
06:34you could type git mergetool and then --tool= and then the name of the tool that you want.
06:41And the Help will show you all of the different tools that you can use, just typing it by itself
06:45will show you all of the different candidates that you could use there.
06:48So you could go and look up how these work, see if there's one that you like or feel comfortable
06:51with it, and you can also add that to your git config file if you want to always use a certain tool.
06:56Again, I'm not going to show you any specific one of these, I want you to really stick with
07:00the basics of resolving them manually first.
07:02It's a more advanced thing to start using these merge tools.
Collapse this transcript
Exploring strategies to reduce merge conflicts
00:00I want to conclude our discussion of merging by giving you some strategies that you can
00:04use to try to take some of the pain out of merge conflicts, to reduce them and to make
00:09them easier to deal with.
00:10I think this is important, because handling merge conflicts is really the only part of
00:14working with branches that can be at all painful.
00:16The first tip is to keep lines short.
00:19In the example that we just did, we had three large paragraphs of text, so we've got our
00:23merge conflict, we didn't know for sure where the conflict was in those three blocks of text.
00:28But by keeping the line short will make it much easier to spot where the problems were,
00:32because Git would then be able to show us, ah, the error was actually in the first part
00:36of this very long paragraph, not just somewhere inside of this paragraph, so it makes them
00:40easier to deal with.
00:41And in some cases, it might allow Git to resolve some of those conflicts for you automatically
00:46and have less work for you to do.
00:48The second tip is to keep your commits small and focused.
00:51If you open up a document to make a change, just make that change and then commit it,
00:55don't go in there and let yourself start wandering around, making lots of other changes, sort
01:00of, while I'm in here changes. I might as well do these things while I'm in here, and
01:04then you commit it all together.
01:06You're more likely to create merge conflicts for yourself by doing that.
01:09Especially, be careful about stray edits to whitespace, that is spaces, tabs, and line returns.
01:15Now sometimes you're going to want to make edits to those, I'm not saying that, what
01:18I'm saying is don't make unnecessary edits to those, or unintentional edits.
01:23You will get a merge conflict if you change four spaces into eight spaces, and you'll
01:28have to stop and resolve it, but if you don't unnecessarily change whitespace, then those
01:33conflicts won't come up.
01:34The next one may or may not be practical, which is to merge often.
01:38If you can, if you're not waiting until you finish a feature, get to some future point
01:43in a project, if you can merge in often back to your master branch, then you should do it.
01:49Because then each time you do it these merges are going to be smaller and the conflicts
01:52will be smaller and more isolated.
01:54The longer you wait, the bigger the merge conflicts are going to be. Instead of having
01:58a conflict in three files, suddenly you're going to have a conflict in 50 files.
02:02And you're going to spend a lot of time resolving it, and it's going to be much more painful
02:05experience than if you break that up and resolve those conflicts as you go.
02:09Now I don't want it to be a surprise to you that you can't merge more than once, we've
02:13only merged one time.
02:14Let's just take a quick look to make sure that that's clear.
02:17If you have your master branch, let's say, and we've our text_edits branch.
02:19So we're making commits to both of those, we're merging back in.
02:24Now we don't have to throw away our text_edits branch at this point.
02:27We can still continue to make new commits into the text_edits branch, and new commits
02:31to the master branch and then merge those commits back in.
02:34We can make more edits in to our text_edits branch, more commits in the master branch
02:38and then merge those back in, so this is what I mean by merging often.
02:43The last strategy is perhaps the most important one of all, which is that you can track changes
02:48to master as you go.
02:50What do I mean by track changes? I mean as changes continue to happen in master, keep
02:54bringing those changes into your branch so that your branch stays mostly in sync with
02:59master, it doesn't get far out of sync.
03:01Let me give in illustration of this.
03:03So again, we have our master branch, we have our text_ edits branch, we're making commits to both of those.
03:08So at a certain point though we say you know what, master has had some critical changes
03:12in it that I'd really like to have in my text_edits branch.
03:15I can merge those into the text_edits branch.
03:18Now my text_edits branch is mostly in sync with master again, and then I'll have more
03:22changes to master, more changes to text_edits, and then I can merge those changes back in
03:28again, tracking what's going on in master all along so that I don't get too far out of sync.
03:32And then that way when I finally decide that I want to merge text_edits back into master,
03:36it's not that far away anymore.
03:38It has most of the changes incorporated in master already, and we'll reduce the number
03:42of conflicts that you get when you merge back in.
03:44We call this process tracking, and it is an important strategy to use.
03:48By now you should have a good sense of how to work with branches.
03:51How to create them, how to add commits to them, how to switch between different branches,
03:56and how to merge them back in. It's a very powerful feature of Git, and you're going
03:59to find that you use it a lot.
Collapse this transcript
12. Stashing Changes
Saving changes in the stash
00:00In this chapter we're going to learn about a future of Git called the stash.
00:05The stash is a place where we can store changes temporarily without having to commit them
00:09to the repository.
00:10It's a lot like putting something into a drawer to save it for later.
00:14The stash is not part of the repository, the staging index or the working directory, it's
00:18a special fourth area in Git, separate from the others.
00:23And the things that we put into it aren't commits, but they're a lot like commits, they
00:27work in a very similar way.
00:28They're still a snapshot of the changes that we were in the process of making, just like a commit is.
00:34But they dont have a SHA associated with them.
00:37Let's try making a change, and then we can store it in the stash.
00:40Let's start by checking out one of our other branches. Let's check out this shorten_title
00:45branch, so git checkout shorten_title.
00:50Now the shorten_title branch does not include the changes that we've made to our text_edits branch.
00:54So git branch --merged, you'll see that it includes all the changes that are in seo_title, but
01:01not the changes that are in either master or in text_edits.
01:05So if you remember back we've made some changes before to the mission file.
01:11Let's open up that file again, and let's make another edit to this file.
01:14I'm just going to say Explore California: Our Mission, change the title of it.
01:18So I'll save that, close it up, git status, we see the change.
01:23While we've got that change there, let's now try to switch branches back to our master
01:28branch, checkout master, it says nope, you can't do that, because if you did it would
01:34overwrite the changes that you just made because master has something different for mission.html.
01:40So please commit your changes or stash them before you can switch branches.
01:47This is a classic case of when we want to use stash.
01:49It's not the only time you can use it, you can use it any time you want to just take
01:53some stuff and shove it in a drawer.
01:55But this is the time that you'll probably use it most often when you need to switch
01:58branches, you have some changes, you're not quite ready to turn them into a commit yet,
02:03so we've got stash them instead.
02:05The way that we do it is we simply say, git stash save, so we're telling to git stash
02:12that we want it to save our changes, and then we're going to provide a message.
02:16Now there's no -m option this time, we just provide the message inside quotes.
02:21So I'm going to say that the changes "changed mission page title."
02:27Now this can be anything. This is for your benefit. This is not a commit that anyone else is going to see,
02:32so it can be a little bit sloppier perhaps. It doesn't have to have a good message the
02:36way that you should do with the commit, but it should be something descriptive that's
02:39going to be meaningful to you when you come back and look at it later and try and remember
02:43what was it that you put into the stash.
02:45So we'll hit Return, save the working directory and index state on shorten_title, changed mission
02:52page title, HEAD is now at here, swap out - for : in index.html title.
02:58So that's the name of the commit that I'm on now, git status, and you'll see that this
03:04is clean, git log --oneline, and I'll just do a couple of lines here, and you'll see
03:12this is the commit that it's on now.
03:14So it stashes the changes and says, now you're back here at that commit.
03:18So what it actually did, after I put those changes into the stash, was it ran git reset
03:24hard HEAD, so if you remember what we talked about with git reset hard, that takes whatever
03:29is in the Repo, and puts thats into both our index and our working directory, so they're
03:35exactly the same as the commit where HEAD is pointing right now.
03:39One note, if you did have untracked files, you can include those too, you use these include,
03:45untracked option.
03:46You can look that up in the help file if you need to.
03:48But normally this would just include things that are in your working directory, which
03:51are tracked files, because those are the things that would conflict, it would keep us from
03:55being able to switch.
03:56So that's it. That's all there is to be able to put things into the stash.
04:00Now we are going to see how we can take a look at things that are in the stash, and
04:03that's what we'll do in the next movie.
Collapse this transcript
Viewing stashed changes
00:00In last movie, we saw how to make an edit and then to put it into the stash.
00:05In this movie, we're going to see how we can view those changes in the stash.
00:08Once again, we're going to use the git stash command, that's going to be true for all of
00:13the things that have to do with the stash, git stash followed by something else.
00:17Before we did git stash save, this time we're going to do git stash list, and that's going
00:23to show us a list of the things that are in the stash.
00:26So here, there's one item in the stash, it's this line right here, stash @ sign, curly braces, 0.
00:34This is the way to refer to this item in the stash.
00:37Let's remember that, that's the syntax, stash @ sign, curly braces followed by a number.
00:44The number here is going to be 0,
00:45next one will be 1, then 2, then 3, then 4 and so on, so there're all going to be numbered.
00:50Next it tells us on shorten_title, that's the branch that I was on, when I put it in the
00:56stash because the stash is going to be accessible even when I switch branches.
01:01So if I switch to my master branch, let's try that real quick, git checkout master, and
01:06then I do git stash list.
01:08It's still there.
01:09The stash is available all the time.
01:10I can always pull from it.
01:12That makes it really handy, especially if you start to make a change on one branch,
01:16and then you realize this isn't the branch that you wanted to commit those changes to,
01:20you can put them in the stash, change your branches and then pull them back out of the stash again.
01:26Back to the listing, it tells us what branch we were on, when we first made the stash,
01:31and then it gives the description that we gave to it, so we'd know what where we stashing.
01:36Now we can see more information about each of those stashes by saying, git stash show,
01:42and then this name right here.
01:44Now it's a bit awkward to type the name, I know it is. It's stash, @ sign, curly braces, zero,
01:50curly braces. That's how we refer to it.
01:53And it comes up and by default it shows us what's called diff stat.
01:57This is a stat about what changed in this file.
02:00So that's by default.
02:01If we want to see more information, we really want to use the -p option, which is show it
02:06to us as a patch.
02:07A patch is a section of code that you can apply to different things to modify them and change them.
02:13So this is basically saying, show us the edits.
02:17The -p option, I'm going to clear the screen before I do it,
02:20and what we see is the typical diff that we're used to showing us the sets of changes.
02:25This is very similar to showing a commit.
02:28So now that we know how to put things into the stash, we know how to look at the stash
02:32and see what's in there.
02:34Next thing is to be able to pull items out of the stash, and we'll do that in the next movie.
02:39
Collapse this transcript
Retrieving stashed changes
00:00We've been taking a look at how we can use git stash to save our changes temporarily.
00:06We saw we could put changes in there, and we saw how we could list them, and we saw
00:10how we could use show in order to inspect them.
00:12Now what we want to do is be able to retrieve those stash changes out of there, essentially
00:17do the opposite of git stash save.
00:20If we put them in the drawer before, now we want to get them back out of the drawer, and
00:24when we do that it's going to bring those changes back into our working directory,
00:28whatever that working directory is, whichever branch we're on. And now just as a refresher,
00:32remember when I did the stash before I was on the shorten_title branch, now I'm on the master branch.
00:41Git doesn't care. For all it knows this is absolutely what you intended, which is stash
00:45the changes, switch branches and then bring them out again.
00:48So it doesn't matter which branch you're on, it's going to try to bring them into your
00:51working directory and apply those changes.
00:54Like with merges, there's the possibility that there may be conflicts that those changes
00:58don't apply cleanly, and in that case it works like merge does.
01:02It does its best to try and figure out how to merge the changes, but if not, then there
01:07will be conflicts, and it'll be up to you to resolve those conflicts.
01:11Now there are two commands that we can use to pull items out of the stash.
01:16The first is going to be git stash pop and the other one is git stash apply, both of
01:23them will pull what's in the stash out, and put it in the working directory.
01:28The difference is that stash pop also removes it from the stash as well.
01:34Git stash apply leaves a copy there, so pop is going to pop it out so that it's no longer in there at all.
01:41We'd just popped it out of the drawer and back into our working directory.
01:46It is exactly the opposite of git stash save.
01:49Git stash apply pulls it from the stash into the working directory but leaves a copy in the stash.
01:54The idea here is that it might be some change that we want to apply to where we are now,
02:00then we might want to switch to a different branch and apply it there, switch to another
02:04branch and apply it there as well.
02:05So we want to keep it in the stash as we move between each of those branches.
02:10Or it might be something that we want to apply then make a few more commits and then apply
02:13it again, and so on.
02:15Most of the time, pop is what you're going to want to use, and that's what we're going to use here.
02:20After pop, I need to specify which stash item I want it to pull out.
02:26If we don't say then by default, it's going to pull the first one, which is this one.
02:30I'll just go ahead and write that in there.
02:32So if we don't say, it will pull the same thing.
02:34It'd be exactly the same as if we did stash @ sign, curly braces around a zero.
02:39If we had three of them, and we wanted to pop up the third one, well then we'd do git
02:44stash and then 2, 2 because the third one is actually number 2 because they start numbering
02:49at 0; 0, 1 and 2.
02:53But in this case, I want to pop out that first one.
02:55So I'll pop it out, auto-merging mission.html, changes not staged for commit, that means
03:02it's in my working directory, and it dropped the stash right here.
03:06So now if we say git stash list, you'll see that it's not in there anymore.
03:11And if we go and look at that file, mission, you'll see that it has the Our Mission in
03:18it, which is the change that we made.
03:20Now we can re-stash this change if we want.
03:23If we say, oops, wait!
03:24I didn't want to be on the mission branch, we can say git stash save, and then we can
03:30store "change to mission page title."
03:35Now it's saved again, git checkout, and we'll check out our shorten_title branch, okay.
03:43Git status, nothing in there, git stash, and this time just for the experience of it, let's
03:50do apply, and we won't specify which one, that will pull the top one out of there.
03:56Just take a list just so you see it, there it is.
03:58And let's this time do apply, now it still does the auto-merge but this time when we
04:04look at our stash, you can see that it's still there. It did not take it out of there.
04:09For now, you can just leave the changes we made to mission.html in your working directory.
04:15We're not going to commit it or worry about right now.
04:16What we want to focus on next is how we can delete items that are in the stash. In particular,
04:21I want to see how we can delete this item that we left in there.
Collapse this transcript
Deleting stashed changes
00:00We've seen how we can add items to the stash, take a look at them while they are in the
00:04stash, and retrieve them from the stash.
00:06The last step is to be able to delete items that are in the stash without applying them.
00:12Now we made some changes to mission.html, we stash those, and then we used git stash
00:18apply, so they actually stayed in the stash while they pull them out. So if we do git
00:23stash list, you'll see there is still this change to the mission page title in the stash.
00:29What we want to do now is delete the stash set of changes.
00:33The way we do that is pretty simple, we just like everything else say git stash followed
00:37by the command that we want to do to the stash, git stash drop, and then you want to provide
00:43the reference for what you want to drop.
00:46So git stash drop that item stash@, then the curly braces with the 0 in the middle.
00:53That will just simply drop that one item, comes up and tells us I dropped it.
00:57Git stash list now, and it's gone, it's that easy.
01:01Let me also show you another way to delete, let's make another change first.
01:05Let's open up our tours.html file, at the top instead of just tours, we can say our
01:12tours. That's a very simple change, very similar to what we did in mission, we do git status,
01:18we now see we have changes both of those files.
01:21Let's stash those changes, stash save "Changed mission & tours page title," can be absolutely
01:30anything you want.
01:32Now if we say git stash list, we can see that we have that item saved there, git status
01:39shows that our working directory is clean.
01:41All right, let's just make another one. Let's go into explorers, and let's scroll down here
01:47in the explorer section and here is the word that's misspelled, enthusiasts.
01:53So enthusiasts has an extra S in it, you want to take that S out, let's save the file close
01:59it up, git status, we can see that the changes there in our working directory, let's stash
02:04it, git stash save "Fixed typo in explorers page." Now if you say git stash list, we can
02:16see that we have two items in there.
02:19Now we certainly could work with each one of those too. I'll just show you again.
02:23We could work with each of those, we could pop them or apply them, we know how to do that.
02:29If we want to drop them, we could drop each of them just by using the reference.
02:33What I want to show you now is how we can delete everything that's in the stash all at once.
02:38Sometime it happens for me when I'm developing that I take ideas that I had or something
02:42that I was working on, and I stash them, and then later, either I apply those changes,
02:48or I just end up going in a different direction. Maybe someone else does the work for me, so
02:53I don't end up having to do it, things like that.
02:55I then may end up with three or four items in my stash that I don't actually need, so
03:00it's very helpful to be able to delete them all just saying git stash clear.
03:05Now be careful because it is very destructive get stash clear, boom just like that, clears
03:11out your whole stash, but if you want to just get rid of everything and start with a clean
03:14slate before you start making some stashes that's a good way to do it, git stash clear.
03:20So you now know how to drop a particular stash or how to clear all of the stashes.
Collapse this transcript
13. Remotes
Using local and remote repositories
00:00In this chapter, we're going to be looking at remote repositories, or as we call them
00:04in Git, simply remotes.
00:06In everything we've done up until now, we've been able to do just on our own computer.
00:11We don't even need a network connection. We can do version control just on our local files
00:16and not share them with anyone else, and that's very effective and Git allow us to do that.
00:20But Git becomes even more powerful when we're able to collaborate with others, and that's
00:25what remotes allow us to do.
00:26The concept is that there is a remote server, and we'll take our changes that we've made
00:31and put them on that remote server so that other people can then see them. They can then
00:35download the changes that we've made to their repositories, they can make changes of their
00:40own, upload those back to the remote server, and we can pull those back down into our repository
00:46to get their changes.
00:47It makes this remote repository sort of a central clearing house for all of these different
00:53changes that are going on, and that remote server is just simply a Git repository.
00:58Remember that Git is distributed version control. There's no real difference between the different
01:03repositories, so there's not a big difference between the server and our computer or the client.
01:08The only difference really is that the server is running some Git software that allows it
01:12to communicate with lots of different Git clients at the same time, but the actual repository
01:17where those changes are being stored, is just simply a Git repository; it has commits, it
01:21has branches, it has a HEAD pointer. It works exactly the same, and the fact that that Git
01:26repository is the central clearing house is really just a matter of convention.
01:31We've all just agreed that we're going to use this one repository as the place where
01:35we all sync up our changes, but it doesn't have to be, it's still just a Git repository.
01:40Let's take a look at the big picture.
01:42So we know that we have our computer, and we know how to have just a simple branch called
01:46master with commits in it.
01:48Now we're going to introduce a remote server.
01:50What we want to do is take our commits and put them on the remote server, so other people can see them.
01:55The process that we used to do that is called a push. So we push our changes to the remote
02:00server, or you can say you pushed them up to the remote server.
02:03At that point, the remote server creates the same branch with the same commits with the
02:08exact same commit IDs referring to all of them, at that point our collaborators have
02:13the ability to see our commits.
02:16At the same time, Git also makes another branch on our local computer that is typically called
02:22origin slash and then whatever the branch name is.
02:24Now that's by convention, we'll talk about how we can change that name, it doesn't have
02:28to be origins, but in this case we'll stick with the default.
02:31So origin/master is a branch on our local machine that references the remote server
02:37branch, and it always tries to stay and sync with that. Right now it looks like all three
02:42of them are in sync, but it doesn't always have to be that way.
02:45We continue developing, we makes some more commits on our master branch when we're ready
02:49to share those commits, again, we do a push, so we push that code up to the remote server,
02:54and it makes note of the change also in our origin/master branch, the one that tries to
02:59stay in sync with the remote one.
03:01When other people make changes to the remote server and contribute them there, we need to
03:05pull those changes down so that we know about them, and the way that we do that is with
03:09what's called a fetch.
03:11So we fetch the changes, at that point they come into our origin master branch, because
03:16what we're doing is keeping those in sync. Fetch is essentially saying sync up my origin
03:20master with the remote server version, but it does not bring it into our master branch.
03:26Now our computer knows about the change, we have it locally, if we get on an airplanes
03:31and fly somewhere while we're on the airplane, we'll have a copy of that commit that 923ea,
03:35but it won't be in our master branch until we do a merge, and at that point then it'll
03:41be brought in to our master branch, and we'll be back in sync.
03:43Now this is an over simplified example, because you might notice that on my computer I have
03:47lots of duplicates.
03:49You can see that I have those same Git objects listed twice on my own computer.
03:53In realty, it doesn't store them twice. Git is smart about reusing these objects, because
03:57they're exactly the same.
03:59So Git uses pointers instead, to point to that, and we know about the HEAD pointer.
04:03So let's take a quick look at how that works just to make sure that that's clear.
04:06I think for illustrative purposes, it was good to see it as two separate branches with
04:11two sets of commits.
04:12But in reality, we have a HEAD pointer for master that points to the third commit, when
04:18we do a push and push it through remote server, it creates the commits there, and moves the
04:22HEAD pointer for master to the third commit, and then also adds another pointer that points
04:28to the same commit on our local computer. It doesn't actually duplicate those three objects.
04:33When we then make a new commit, it moves our master pointer to the commit, when we do a
04:38push it creates that new object on the remote server and moves the pointer, and also increments origin/master.
04:44Then when new changes come into the remote server from someone else, of course, it moves
04:49the master pointer to point to that latest commit.
04:52When we do a fetch, it brings that new Git object down onto our computer and moves the
04:58origin pointer to point to it, but our master ones still doesn't. We have to first do a
05:03merge, and we know that would be a fast- forward merge, that's what we would call that, in
05:07this case where it just moves all the way to point to the same commit.
05:10So as you can probably see, origin/master really is just a branch, it's just like the
05:15other branches that we're working with.
05:16The only difference is that it tries to stay in sync with what's on the remote server.
05:21The reason that matters is because it is possible for someone to make a commit on the remote
05:26server while we're in the process of making a commit on our local machine.
05:30All right, it happens all the time. I'm making changes to one part of the project, my collaborator
05:35is making changes to their part of the project, they put theirs up on the remote server, my
05:40origin master, once I do a fetch, the state of our two servers would look something like this.
05:45You'll see that origin/master does still include those objects that are in the remote branch,
05:50it did stay in sync with that, but in the meantime I've got a new commit called ba8ce.
05:56So now that our two branches have diverged, we need to do a merge to bring them back together
06:01again, and that process works exactly the same way as we saw when we were working with
06:05emerging branches. Origin/master is just a branch, so we can merge them together and
06:09then the next time we do a push, our master changes will be merged in and sent off to
06:14the remote server.
06:15So generally speaking, the process that you go through when you're working with a remote,
06:20is that you'll do your commits locally, then you'll fetch the latest from the remote server,
06:24get your origin branch in sync, then merge any of the new work you did into what just
06:29came down from the server and then push the result back up to the remote server.
06:33If the process seems at all unclear now, it'll become second nature soon enough.
Collapse this transcript
Setting up a GitHub account
00:00We're going to start out by setting up a remote repository, and the way we're going to do
00:04that is by signing up for an account at GitHub, that's http://github.com.
00:11GitHub is the most popular Git host.
00:14There are other ones out there, but they're a great one, and I think you should start
00:17with them first before you started exploring other options.
00:20They offer free and inexpensive hosting plans.
00:23Free is going to be great for our purposes when we're just getting started, but then we can also
00:26upgrade to very inexpensive plans later on as our needs grow.
00:30And one of the things that I love about GitHub is that not only do they provide reliable
00:34hosting for our Git repository, but they also offer many other great features.
00:38For example, charts and graphs that show the state of all the different branches and the
00:43commits that have been made, or graphs showing the activity on a project over time.
00:48Those kinds of bells and whistles make it a really nice choice.
00:51Now here I'm on the GitHub site.
00:52The design of the page may change over time, they certainly may update their web site after I record this.
00:57The thing I want to look for is the Signup and Pricing button, there's one there, and
01:00there is a big one down here.
01:01They have a lot of different plans.
01:03The one we're going to be picking is the Free for open source plan, which is $0 a month.
01:09It's unlimited public repositories and unlimited public collaborators.
01:13That means that once we push our code up there to the repository, everyone can see it.
01:18People may not be looking at our repository, but if they wanted to, they can. It is browsable.
01:23For open source projects that's ideal,
01:25but if you want to have a private repository where you can put code that people can't see,
01:30let's say you're building a project for a client, it might not be something that you
01:33want everyone to be able to see the commits that you're making on behalf of that client.
01:37In that case you would need a private repository, and that's what these other plans offer is
01:41different levels of private repositories for you to use.
01:45For now we can start with a free account unless you already know that you want to go with
01:48one of those others.
01:49So create a free account, and then we just have to enter some basic information.
01:54Username that we want to use, the Email Address, our Password, and then our Password a second
01:58time, and then Create an account.
02:01That's really all there is to it.
02:02Now it may send you an email and want you to confirm that you are who you say you are
02:06and things like that.
02:06Go ahead and follow all of those steps, and then sign in when you're finally all set up.
02:11Now do give some thought to your username, because this username is the name the collaborators
02:16on projects are going to see as well.
02:18Once you've gotten your account created, and you've signed into it, the next thing we want
02:22to do is we want to create a new repository.
02:25In order to connect to the repository we have to create it first.
02:29So on the GitHub site, create the new remote repository.
02:33Create a New Repo is right here.
02:34If I click that, it will come up and say, what do you want to call this repository?
02:39Now you can call it anything you like, it should probably match your project name.
02:43I'm going to call it explore_california.
02:45A description here, so we can provide a description, it's completely optional.
02:50Let's say Website for Explore California.
02:57And then we have a choice, do we want to make it Public so that anyone can see what's in
03:00it? We can still choose who can commit to it.
03:02They can't necessarily have access to it but they can see it.
03:06Or we can choose Private, which means that only we can do it.
03:09If I choose Private, then I have to upgrade my account, because I have to go from a free
03:12account to a Micro account, if I don't already have that.
03:15If I choose Public, then you don't have to so that's what I'm going to pick.
03:19Now the next option we have to decide is do we want to initialize this repository with a README.
03:24If you remember back to when we first created our very first repository, the very first
03:29step we did was we initialized the repository, and then we made our first commit.
03:35So then at that first point we have our first commit in the repository, it's sort of the
03:39very basic first step, and it's very common to create that first step by putting a README
03:44file in there just to get things started.
03:46So they're offering to do this for you automatically, so you can check that if you want.
03:49I'm going to leave it unchecked.
03:50It will also add a gitignore file for us if we want.
03:54So we can add a gitignore file to the repository, and we can pick, and you can pick based on
03:58what kind of project you're going to be doing.
04:00It will pull from the repository of gitignore files that we looked at earlier and put those
04:05in there for you.
04:06So those are two examples of the kinds of nice features that GitHub gives you.
04:10I'm not going to do either one of those though, I'm just going to click Create repository.
04:14So GitHub created the remote repository on their servers, and then they provide us with
04:18some helpful setup instructions.
04:21So we've got Quick setup here, if you've done this kind of thing before, or the steps that
04:25we want are down here, they give us two choices.
04:28Either create a new repository on the command line or push an existing repository from the command line.
04:33Since we have an existing repository, that's the step that we want to follow.
04:38Now you'll notice here these steps are basically the steps that we followed early on in order
04:42to create the basic first commit of our repository, and the last two steps are basically the same
04:48thing once we have an existing repository.
04:51It's also the same thing here, creating the init step that they offered to do for us on the last step.
04:57So we've already done it, we could do it ourselves from the command line again, or we can have GitHub do it.
05:03But the end result is that we have a repository and what we need to do then is git remote
05:08add origin and then this address right here.
05:12This address is also up here.
05:15If you click HTTP, you'll see the exact one, HTTP, https, that's the one that you want
05:21to make sure that you get, not the git@ github one, make sure that you get the HTTP one.
05:26The other one would be if you were logging in via SSH instead of via HTTP.
05:30Now don't worry about the exact syntax of this git remote add and git push, because
05:36we're going to be talking about those in the next movies.
05:39
Collapse this transcript
Adding a remote repository
00:00In the last movie we created a GitHub account and created an initial GitHub repository,
00:05and that's on the remote server that we can then connect to.
00:09We now need to tell our local repository information about where it can find the remote.
00:14When we set up the remote repository, GitHub came up and offered us some helpful information.
00:19Go ahead and leave that page up, because we're going to want to come back to that.
00:22But first I want to switch over to your command line and make sure that you're inside the
00:26root of your project already.
00:27If not, you'll want to navigate into it, and from there let's type our first command which is git remote.
00:34So git remote will come up and give us a list of all the remotes that it knows about.
00:38It doesn't know about any right now about.
00:39So it doesn't return anything.
00:41The git remote works a lot like git branch does.
00:43We use git branch to see all the branches, git remote shows us all the remotes that we know about.
00:49Now the next command we want to do is git remote add.
00:53So git remote add will add a remote and then what we want to put in.
00:57Don't type this part.
00:59Just wait for second.
01:01Git remote add and then the alias for what we want to name our remote followed by the
01:05URL of where it can find it.
01:07Let's go back and look at that and GitHub page again, because it tells you the name,
01:12the URL, where you can find it.
01:14That's what this is right here.
01:15So you can just copy and paste that, and it suggests the default name of origin.
01:21Now this is an alias.
01:22You can call it whatever you want.
01:24Let's say origin and then that whole long string pasted in.
01:28This will create a new remote called origin that points to that remote server at that URL.
01:34Now we don't have to call it origin.
01:35By convention, typically, you call your primary one origin, that's what most people do.
01:40But if you want you can call it GitHub let's say.
01:42I'm going to go head and call mine origin just so we can stick with that default convention.
01:47Now I do want to make sure that I call attention to the fact that I'm using a URL which has
01:51my name in it, because that's for my GitHub account.
01:53Of course, for you, you will want to make sure that you are using the one that has your
01:57GitHub account, and from now on if you're using the exercise files where we have a remote
02:03defined, you will want to make sure that you take a second to change that remote to point
02:07to your GitHub account, not to mine.
02:10So that's very important.
02:11You want to make sure that you customize it so that it's looking at your remote repository,
02:16and not trying to find the one that I created.
02:18Now it's worth noting that you can have more than one remote for your project.
02:22We don't have to just have this one remote server out there that we are connecting to.
02:26You can have several different ones and in that case you would definitely want to give
02:29them each a different name.
02:31So now lets try out git remote command again.
02:34Git remote, and this says ah, here is origin.
02:36Let's do git remote with the -v option after it, that will give us a little more information.
02:42Now it shows us the URL that it's going to use for fetching and the one that it's going
02:46to use for pushing.
02:47Now typically those are going to be the same ones, but they don't have to be.
02:50It could be different ones.
02:51We could have a read-only remote that we're fetching from, but we're pushing to one that lets us write.
02:56And if you're wondering how Git now knows about these remotes, it stores those in the
03:00.git folder of course, in config.
03:03Let's take a look that file, and you can see that now it says, okay, I have a remote called
03:07origin and here's the URL for it, and these are instructions that Git will use to tell
03:12it what information it's going to pull down from the remote repository when it does a fetch.
03:17The last thing I want to show you is just that if you want to remove a remote is just
03:21simply git remote rm followed by the alias.
03:25So that would remove the origin remote that we just created.
03:29So I've removed that.
03:29If we now take a look, you will see it's not in our config file, and of course, I can add
03:34it again just like that, and now git remote shows me it in the list again.
03:40So now our local repository knows about the GitHub repository that we've created.
03:45We haven't shared any data yet.
03:46None of our branches or commits or anything like that are on the remote repository yet.
03:50At this point, we've just simply created the mechanism by which they can establish a connection
03:54so that we can begin pushing our code up to the remote repository, and that's what we
03:58will start doing in the next movie.
Collapse this transcript
Creating a remote branch
00:00So far we've created a GitHub account, we've created a remote repository on that account,
00:04and we've told our local repository how to find that remote repository.
00:08Now we are ready to start putting our commits up on the remote repository for other people to see.
00:13If you remember from the introduction, I told you that process is called pushing, and push
00:17is the verb that we're going to use.
00:19So what we want to do is push our code to the remote branch, and when we do pushes what
00:23we are pushing is a branch.
00:25So we are on a branch, and we're telling GitHub push this branch up to the corresponding branch
00:30on the remote server.
00:32The syntax that we're going to use for that, GitHub actually gave us in their helpful hints here;
00:37git push -u origin master, so that's git push, we're going to use the -u option.
00:43You are pretty much always going to want to use that, we're going talk about what it is
00:47in just a little while.
00:48But for now, go ahead and do it;
00:49git push -u followed by the alias for the remote repository.
00:54Remember, we called it origin.
00:56So push to origin, that's the GitHub remote, push to that a branch.
01:01And which branch do we want to push? We can take a look real quick and see which branches
01:04we have, but I'm going to go ahead and do get push -u origin master.
01:11So I'm going to push up the master branch up there to GitHub.
01:14It wants my username for GitHub, and it wants my password.
01:20Now you can see that it counts up the objects that we have, it compresses them so that it
01:25can send a small data packet to GitHub, and then it writes those objects on the other side.
01:31Once it's done with all of those, then it creates this new branch for us.
01:35So that new branch gets created, and then it notes at the end, branch master set up
01:39to track remote branch master from origin.
01:42That's what the -u option does for us.
01:44We will talk about branch tracking a little later.
01:46Now let's go back to GitHub real quick.
01:48It says when you're done doing these steps then click Continue.
01:51So we're going to click Continue here.
01:53And now it takes us show page for our project, Explore California, and you can see here's
01:59the latest commit that we made and here's a view of the entire project.
02:02So we can go through, and we can actually surf those files and see everything that's in there.
02:08There's also lots of other things you can do like viewing the commits, viewing a chart
02:12of the different commits over time, looking at graphs. Feel free to explore,
02:17but at this point now we've pushed our project up on to GitHub.
02:21It now exists there.
02:22Let's go back and just look at the command line real quick just to see what it actually
02:25did. As with a lot of things,
02:27it stored that in the git folder.
02:30So git config, you can see now there is a branch definition here and the branch has
02:35a remote which is origin, but what is origin? Origin is right up here so that's how master
02:41knows where it's going to commit to.
02:43It references origin, origin references this URL, and then merge is giving it a reference
02:48for what it's going to use, when it's doing merges.
02:50We don't need to worry about that at this point.
02:52Now I just want us to also take a look at where it stores these, ls -la .git,
02:59in the refs folder, there's a folder called remotes, and inside remotes we now see a file
03:04called origin. Actually it's a directory called origin.
03:07And inside that directory, you'll see there is our branch master, and if we take a look
03:13at that, .git/refs/remotes/origin/master, it's a reference to a shot just like our regular
03:21tip of our branch pointed to a shot.
03:23It works exactly like a branch, it just stores them in this different folder called remotes.
03:28Now you can see your branches normally would git branch, right?
03:31Git branch -r will show you the remote branches, and git branch -a will show you both.
03:39It will show you both the local ones and the remote ones.
03:42So at this point, we have successfully completed the steps in order to get all of our local
03:46code online on the remote repository where other people can see it and start working with it.
03:51Before we dive into seeing how we can push and fetch from that repository, I want us
03:56to stop and take a look at how we can clone a remote repository.
03:59Because that's the way you will work with an existing repository that someone else has.
Collapse this transcript
Cloning a remote repository
00:00We were able to successfully create a remote GitHub repository and to configure our local
00:05repository so that we can push all of our local commits up to the remote.
00:10Now I want to switch gears for a second, and I want us to do the opposite.
00:13And that is instead of taking a repository that's local and pushing it to the remote,
00:18I want to see how we can do the reverse.
00:20How we can go with a remote repository and pull it down to have a local copy of it to work with.
00:25This is assuming that we don't have a local copy to start with.
00:29This kind of circumstance would come up, if someone said, hey come and collaborate on
00:32a project with me.
00:33I have put my code on GitHub, now why don't you go get it, pull down a copy, and then
00:38we could start collaborating. Or if you wanted to work on open-source project, the same kind of thing.
00:43You'd go out, find the open-source project, get a copy of it to bring on to your local
00:47machine, and then you could start contributing.
00:49The way we will simulate this on our single machine is that we will back out of our Explore
00:54California directory.
00:55So I'm going to cd.., go backwards a directory, and in that directory you can see
01:00I have got my explore_california.
01:01I'm just going to ignore that.
01:02Let's pretend it doesn't even exist for a moment.
01:05Let's say that I'm a brand new user, I've got Git installed, but I don't have a Git
01:09project yet on my machine.
01:11What I want to do is go to GitHub and figure out what project I want.
01:16Now you can search around, and you click the Explore link, and you can look for different
01:19open-source projects, or we can stumble upon this Explore California web site and say,
01:23all right, I'm going to collaborate on that one.
01:26Regardless of how you get to the project, what you need to know is, how do you locate
01:30it? And GitHub tells you that information right here.
01:33This is what you need to know.
01:34So you want to copy this so that we can paste it.
01:36This is the path to the repository.
01:39It's also the same path that got configured in our Explore California folder, when we
01:44set up the remote branch.
01:45It's the way that we refer to this repository.
01:48So let's take that over here, and now from the command line, notice I'm not in any kind
01:52of Git project at the moment, I'm just in a plain old folder.
01:55I'm going to say git clone, and then I'm going to paste in that path.
02:00So I'm going to clone that remote repository which basically it's going to say, make me
02:04a local copy of it, clone it on my machine.
02:06And what it does, it's going to create a new directory, and that directory by default will
02:10be the name here, explore_california, not the .git.
02:14So explore_california is the default.
02:17Now of course, I already have an Explore California folder, so when I try it, it says sorry that already exists.
02:22But that's no big deal.
02:23We can call the folder that exists in, anything we want.
02:26The name of the directory has nothing to do with the name of the repository.
02:30So let's give it a different name.
02:31I'm going to say that I'm going to be collaborating with Lynda, so I'm going to call
02:37this lynda_version.
02:38So this is Lynda's version of the repository.
02:41So you can see when I do that, it counts the objects, and it compresses them, and it receives
02:46them on to my local machine.
02:48Now I do ls -la, you will see I have got this new folder, lynda_version.
02:52Let's go inside that folder, take a look, and there's my whole project.
02:57It downloaded the files and folders around GitHub to my local repository.
03:01Now we do git branch, you'll see that we don't have all of the branches that we had in our
03:06own version, in the explore_california version, instead we just have the master branch because
03:11that's all that exists on the remote branch.
03:13Those other ones that have never been pushed up there, they remain private until we push
03:17them up there and make them public.
03:19Now if there had been more than one branch up there, it still would have brought down
03:22the master branch by default.
03:23You can specify the -b option and tell it which branch you want, if you want a different
03:28one, but by default it's going to take whatever GitHub has as its default branch, and by the
03:32way, you can also configure which branch is the default in GitHub, in the GitHub admin controls.
03:38So now we successfully cloned this project on to our machine.
03:42Our machine happens to have two repositories on it.
03:45And what I'm thinking is that we're going to able to switch back and forth between those,
03:48as if we were actually jumping from one computer to another computer.
03:51They just happen to exist on the same computer, but it's two different git repos.
03:55We're going to call one of them our version and the other one will be Lynda's version,
03:59and Lynda is going to be a collaborator that we are going to work with on this project.
04:03So we will make commits, we will push them up to the remote, and then we can switchover
04:07to Lynda's repo and see how it looks to her.
04:10Then she can make changes, push those up to the repo, and we can switch back to our version,
04:14we will be able to see things from our side and how they would look.
04:17So don't let it throw you that it's not actually two different people on two different
04:20computers, it's still two different Git repositories each that contain their own unique sets of information.
Collapse this transcript
Tracking remote branches
00:00Back in the chapter on branches, we talked about how you could have one local branch
00:04that stays rather closely in sync with the progress of another branch, and this process
00:09is called tracking.
00:10And as an example, I showed you how to text_edits could track master.
00:13The idea here is that we want to keep the two pretty closely in sync.
00:17So we're regularly going to pull updates from master and merge them into text edits.
00:22That way it never gets too far out of touch and even though it happens less frequently,
00:26whenever we are done with our work in text_edits, and we are ready to merge it back in, master
00:30is probably the branch that we want to merge it back into.
00:33Now tracking is really common with remote branches, and it works in a similar way, plus
00:39with a little bit of configuration, we get to save ourselves some typing by letting the master
00:43branch know what remote branch should it be using when it's doing its fetch, and when
00:47it's doing it's push.
00:49We won't have to specify it each and every time. It will have a default setting by knowing
00:53its tracking branch.
00:54Now when we did our first Git push, we did it with the -u option, and I told you
00:59at that time, that that was about creating the tracking branch, and then we'd talk about it later.
01:03Well, that time is now.
01:04If we don't do git push with the -u option, it does not track any remote branch. All it
01:10does is push our code up there, and that's it.
01:13It doesn't keep any kind of reference that this is the branch there we're going to be
01:16working with in the future.
01:18The -u option says push it up there, and also make a note of the fact because we're
01:22going to be coming back and working with this branch frequently.
01:26When we did a git clone to create our lynda_ version, it does track the remote branch, and we can
01:32see that tracking here, git/config. You can see that our branch master is set up to track
01:38the refs/heads/master that's on origin.
01:41That's what it's going to track.
01:42That's how you know that it's a tracking branch.
01:44By contrast, let's switch back over. We'll go backwards a directory and then let's go into
01:49our explore_california folder, we can see the same thing is true here.
01:53If we do cat .git/config, but let's create one that doesn't track.
01:57Let's create one that doesn't have the -u option to see the difference.
02:01Let's create a branch off of master that we can then use.
02:04Let's do git branch, and let's call this branch non _tracking, that will make it clear what's up.
02:12And then now, we know how to push that to origin, and we're going to push non_tracking.
02:20Wait one minute, it wants my credentials, okay, pushes it up there, and now let's take
02:29a look again at that git/config, and you will see that it does not have a listing here,
02:34right, push it up there but it said, all right!
02:35Here you go remote repository, I am done with you.
02:38There is not sort of connection in the future between our non_tracking branch and what's
02:42going on at GitHub.
02:43The -u option or cloning it, created that tracking branch.
02:47Now I'm going to leave this non_tracking branch but I just want to let you know that
02:50if you ever end up with a branch that's not tracking, and you want to make it tracking,
02:54then you have three choices.
02:56Either you can come in and add these, so they are similar, or you can use the git config commands.
03:03It's git config branch and then whatever the branch name is.
03:07In this case, it would be non_tracking remote and then the name of the remote, origin, and
03:15then you would do the same thing for the option for merge refs/heads/master.
03:22So that would give you those same configurations in the dot config file, or if you're using
03:27Git 1.7, which most of you should be unless you got an old version of Git for some reason,
03:32you could use git branch --set-upstream, which is also what the u option is, that -u
03:39that was used, when we did a push.
03:41That's the shortcut for set-upstream, and then we can say non_tracking origin, non-tracking,
03:50and that will tell it what its up-stream server is.
03:52It will tell it what the remote is that it ought to track.
03:56So again, I'm going to do any of those. I am just going to leave it so that our non_tracking
03:59branch stays non_tracking, so that if we ever want to see the difference, we can switch
04:03over there and try it out.
Collapse this transcript
Pushing changes to a remote repository
00:00In the last movie we got an idea of how tracking branches work.
00:03In this movie, we will apply that while we also push some more changes up to the remote repository that we created.
00:09Notice that I'm inside my explore_ california directory, and I'm on the master branch.
00:14Before we can push some changes we need to make some changes.
00:17The change that I have in mind is going to be into the tours page.
00:20So let's open up tours.html, and if you notice over here I've got Backpack Cal, and I've
00:27got a link here that takes me to the Backpack Cal page, that page does exist.
00:33Notice that the link that will take me to for that is tour_detail_backpack_cal.html,
00:41that's the format of the file name.
00:44Now California Calm does not exist yet, I don't have that page created.
00:49But notice that the page at once that take me to is tourDetail_calm.html, so the change
00:55that I want to make is for each one of these to put them in the same format as the one that does exist.
01:00So even though these don't go to files that are actually there yet, we're going to go
01:03and change the link so that if that file existed, and had the same format as Backpack Cal, it would go there.
01:09All right, so let's make that change.
01:12So inside tours.html I'll open that up, and I'm just going to do a quick search for Detail,
01:18and I'm not going to Ignore case, and there it is, there is the first one, Detail_calm.
01:24So we'll make it _detail, do a search for the next one _detail, and the next one _detail,
01:32_detail, _detail, so a whole bunch of these.
01:41Okay, so I've got all of those now. So I'm going to save this document and close it up,
01:47git status, we see the changes there.
01:50Let's go ahead and do git commit, and I'll do it with the -am option, so it'll do it all
01:54at once, and we'll say, "Change file/link format on tours.html."
02:03Okay, so now I've committed that change.
02:08Now just to be clear this is just a local operation.
02:11This is the same kind of stuff we were doing at the very beginning, has nothing to do with
02:14the remotes whatsoever.
02:16We're just making a basic commit to our own master branch, our own local repository.
02:21Now at this point that's the only place that that change exists.
02:25So git log --oneline, there is the change right there, f3a370e.
02:31If we do git log --oneline origin/ master, that's the remote branch.
02:39Actually it's my copy of the remote branch, and you can see that it's not there right
02:43now, and we can actually compare the two by saying git diff master with origin/master,
02:50and actually probably you should swap those around because origin/master is behind master,
02:59and there's the changes. So that's all the changes that I just made between the two.
03:03So what I want to do now is push my changes.
03:06All right, remember that we're pushing the changes just like we push the initial code
03:09we're going to push to origin master.
03:11So we can do git push origin master, and that's the exact same command that we used before
03:18to push up our changes, but because this is a tracking branch, remember we set it to be
03:23a tracking branch, we can just say git push. Much, much shorter.
03:28Git push wants to know my username, and there it is, it pushed. It knew where to push to because
03:38we're tracking that branch.
03:40So whenever we do fetches and whenever we do pushes, it will assume that we want to go
03:45to that tracking branch. Very convenient. Saves you a lot of typing and having to think about
03:50what you're doing.
03:51You can just say git push, and it will push all the changes up to the remote branch.
03:56We can now see that that change is there, git log --oneline, and let's do origin/master,
04:03and let's just do the first three, and there it is.
04:06You'll see that it now shows up there.
04:08And sure enough, if you go back now to GitHub, and you take a look at GitHub, you'll see that
04:13the master branch now has that commit.
04:16In fact, here it is latest commit to the master branch, Change file/link format on tours.html
04:21authored three minutes ago, and here's the commit number.
04:23If we click on that, it comes up and it shows us that same diff that we were looking at.
04:28So that we can see what the commit was.
04:31Now let's go back to our command line, and let's switch to our other project,
04:35the lynda_version.
04:37So this is as if we're looking at it from Lynda's point of view, from her repository.
04:41So we'll go backwards and into Lynda's version, and from here we'll say git log --oneline,
04:47and you can see that Lynda does not have that change yet.
04:52It's in the explore_california repository, it's up on the remote repository, but lynda hasn't seen it.
04:58And that's because Lynda still needs to do a fetch in order to retrieve whatever changes
05:02have been pushed up the remote repository.
05:05Let's see how to do that in the next movie.
Collapse this transcript
Fetching changes from a remote repository
00:00In this movie we're going to learn how to fetch changes from a remote repository.
00:04In the last movie we made some new changes in our explore_california repository, and
00:08we pushed those changes up to GitHub,
00:11but when we switched over to the Lynda repository to take a look at what Lynda would see, we
00:16don't see those changes there; git log --oneline, let's just do -5.
00:22Oops! --oneline needs an e in it, and you can see that it's not there, and it doesn't
00:28matter if we're on master or if we ask it for origin/master.
00:35Same thing, it doesn't exist in master, and it doesn't exist in origin/master.
00:39Also let's notice that if we ask for git branch, we only have our master branch.
00:44If we ask it for a list of the remote branches it comes up, and it just says that we have
00:48master there as well.
00:50Remember we pushed up another branch as well, we pushed up the non_tracking branch.
00:54So there is both a new branch and a new commit on GitHub that Lynda can't see yet.
01:00Why is that? Well, it's because Lynda needs to do a fetch.
01:03Remember a fetch is what synchronizes origin/ master with whatever is on the remote repository.
01:10Origin/master doesn't automatically reflect what's on the remote repository, we have to
01:14tell Git that we want it to do a sync between the two.
01:18When I did this line here where I looked at the log of origin/master, that doesn't actually
01:22go out to GitHub to see what the log file is there.
01:26It's looking at the local copy that Lynda has in a repository from the last time that
01:31she synced up, the last time that she did a fetch, which was when she originally cloned
01:36to this repository.
01:37So this git log command can actually be done when we're away from a network connection.
01:40We don't have to have access to GitHub to find out information about origin/master.
01:45We won't get the latest information, we'll get the latest thing that we synced up the
01:49last time that we downloaded it.
01:52But when we do a git fetch, it does go out to GitHub and pulls down information, and
01:56we do need to have an Internet connection in order to do that. So let's try that now.
02:01The command is git fetch, and then we can provide the name of what we wanted to fetch,
02:06we want it to go to origin, which in our case is GitHub, so git fetch origin, and bring everything back.
02:13Because we only have one remote repository, we can just abbreviate it as git fetch.
02:18So you don't have to type it all out, you can just simply say git fetch, and it will
02:21know that you mean to fetch from the one and only remote repository that you have.
02:26So let's try that now and see what happens.
02:29So you can see it counted the objects we don't have, there's five of them, decompress them,
02:34brought them down, and here they are.
02:37This is the range of commit numbers.
02:39You can see this f3a370e is the commit that we were looking for, that's the one that wasn't
02:44there, and it found the new branch, right.
02:47This new branch non_tracking, it brought non_tracking from the remote non_tracking into origin/non_tracking.
02:57Now if I say git log --oneline -5 origin/master, now look at that, we see the change because
03:10now we've done a sync.
03:11Now origin/master is in sync with what is on the remote, so it has all the same commits
03:17that are there, all those same git objects have been brought down to our machine.
03:21And if we do git branch we can see we still only have one branch, the git branch -r now
03:27knows about the non_tracking branch.
03:30We downloaded information about that.
03:32So whenever we do git fetch it's synchronizing with the remote repo, and that means it pulls
03:36down any Git objects we don't have, and it pulls down bookmarks that reference the tips
03:41of each of the branches that are on the remote.
03:44Now if we look at the log for just master, not origin/master, but just our master branch,
03:51you can see that that commit is still not there.
03:53I didn't bring it all the way into our master branch, that's ours to manage, right? It just
03:58brought it into the origin/master, which is going to try and always be a perfect sync
04:03with what's on the remote repository.
04:05It's just our local cached version of the remote repo.
04:09So that's an important point, when we synchronize with remote repository using fetch, we just
04:14update origin/master. Master doesn't change at all.
04:18If we're in the middle of working on something, and we've got some edits in our working directory,
04:22those aren't affected.
04:23If we've made some commits over the last hour, those aren't affected.
04:27It has nothing to do with any of our non-remote branches whatsoever.
04:31A fetch is not harmful in any way at all, and because of that there is absolutely no
04:35reason not to fetch often.
04:37In fact, I want to give you three basic guidelines that you should try and follow.
04:41The first is always fetch before you work.
04:44The very first thing in the morning that you should do when you sit down at your computer is do a fetch.
04:49Find out what's on the remote repository, what commits were made over a night by your collaborators.
04:55Get those all down onto your computer, and then you can decide what to do with them from there.
04:59The second is fetch before you push.
05:02You've got your commits, you've made them, they're not on the remote repository, before
05:06you push them up there find out what else is on the remote repository.
05:09Maybe someone else already pushed the similar commit or maybe they pushed something that's
05:13going to conflict with what you're about to push. Go ahead and get those changes downloaded
05:16so that you know about them before you start putting new stuff on there.
05:20And then the last one is just to fetch often.
05:22It's not destructive, so there is no reason not to do it often, and you certainly want
05:26to do it anytime you're about to leave a network connection.
05:28If you're going to go take your laptop to work in the park or you're about to get on
05:31an airplane, you want to do a fetch to make sure that your repository is in sync with
05:36what's on the remote.
05:37Now because it doesn't automatically bring those changes into our master branch, if we
05:41want them there, then we're going to have to put them there ourselves by doing a merge,
05:45and we'll do that next.
Collapse this transcript
Merging in fetched changes
00:00In the last movie, we used git fetch in order to sync up origin/master with the master branch
00:06on the remote repository, but we noticed that while it brought those commits down into origin/master,
00:12it didn't bring them into master on our local repository.
00:16All it did was get origin/master in sync.
00:19If we want those changes to be incorporated into our master branch, we need to do that
00:22additional step ourselves, and that's we are going to learn how to do in this movie, using merges.
00:27Now you will recall earlier that I told you that origin/master is just a branch like any other branch.
00:33It's a remote branch, the only thing that really differentiates it from the branches
00:37that we normally work with is the fact that we can't check it out, other than that it's
00:41really the same, and it make sense that we can't check it out, because Git really needs
00:44to be able to keep it in sync with what's on the remote server, and it doesn't want
00:48us getting in the way of that.
00:49If we check that out, we might make a commit to it, and that would just confuse things.
00:53Instead, we have our branches that we are in charge of, but Git is going to remain in
00:57charge of origin/master and make sure that it mirrors what's on the remote.
01:01But other than the fact that we can't check it out, it is exactly like any other branch.
01:06That's an important point to remember, because we are going to merge with it just like any other branch.
01:11In this illustration, you can see that the remote server has five commits in it, and
01:14a fetch has taken place, because origin/master is perfectly in sync with what's on the remote server.
01:21Our master branch however is two commits behind, so it needs to have those two commits added
01:26to it, and the process that we do that is by merging, and the merging works exactly like
01:31everything that we learned about merging before in the merging chapter.
01:34The only difference is that we are using a branch called origin/master, instead of some
01:39other branch name that we worked with before.
01:40But in this particular illustration, if we were to do a merge right now, master would
01:45do a fast-forward merge just like the fast forward merges that we learned about previously.
01:50Now if we made additional commits on the master branch, in the meantime, then those would
01:54need to be merged in, and we would have a merge commit that would join those together
01:59just like we did before.
02:00And of course, it's also possible that the 923ea commit that's in origin/master has something
02:05that conflicts with what we have got in ba8ce in our master branch, and if it conflicts,
02:11well just like with the normal merge, we have got to resolve those conflicts.
02:14And we resolve those conflicts in the exact same way, and we commit the result into our merge commit.
02:20Let's try it out.
02:21Okay, notice that I am inside my lynda_ version folder, and I am on the master branch.
02:25First, let's just remind ourselves where our branches are, we have git branch, and we will
02:29use the -a option so that we see all of them.
02:32So what I want to do is I want to take master and merge it with origin/master.
02:36We can also just do a diff if we want first to find out what's the difference, master
02:41origin/master, and it tells us, so we can see what those changes are.
02:45Okay, now that I know it's different, yes, I do want to go through with that merge.
02:48So git merge and just like before, normally we would type a branch name, now we are going
02:53to type origin, and then the branch name.
02:57So merge in origin/master, so I will hit Return, and you can see sure enough it tells us right
03:01here that it was a fast-forward merge, and now get log --oneline, we'll do three lines
03:07for the master branch, and you see that now the change has appeared there.
03:12Now let's just look at the diagram again and just make sure that something is super clear
03:15you, when we do a merge, we are merging with origin/master.
03:20Our local version, that's where we are merging in, we are not going back up to GitHub to
03:24see what's there.
03:25So when we do a merge, we always want to make sure we do a fetch first.
03:29Fetch, then merge.
03:30Now it's possible that new things might have come in, in the meantime of the remote server,
03:33we will worry about those later, but we do want to do our best to be as up-to-date as possible.
03:38So now that we understand this process, git fetch, git merge.
03:41That's the process that we are going to go through.
03:43I want you to know about a shortcut called git pull.
03:46Git pull is equal to git fetch+git merge.
03:50It does it all in one step.
03:52It goes out there, finds the latest, brings it down and merges it into your current branch,
03:56all in one big shortcut.
03:58Now there are lots of pros and corns to using git pull.
04:02First, it's super convenient.
04:03So a lot of people use it by default for that reason.
04:06The bad part is, that for beginners, it obscures the fact that you are actually doing this
04:11two step process, and I think that a lot of people who use git pull a lot, forget about
04:16doing git fetch and git merge. They don't really realize that that's what's it doing
04:19for them under the hood, and then sometimes when things go wrong with git pull, it's hard
04:24for them to understand what actually went wrong and what happened and how to fix it.
04:29If you use git fetch+git merge, it's much harder for those kinds of problems to arise,
04:34because it's much clear what went wrong and how to fix it.
04:37So my recommendation is to try and use git fetch and git merge for a while, until you
04:41feel like you've got the hang of it and then if you know that what you really want is just
04:46git fetch and pull down the changes, then you can try using git pull.
04:50
Collapse this transcript
Checking out remote branches
00:00In this movie we are going to learn how to check out remote branches.
00:03First, I want you to notice that I am inside my lynda_ version directory, and I am on the master branch.
00:09If I do git branch, you will see that's the only branch that I have in this Lynda repository,
00:13and if I do git branch with the -r option to look at the remotes, you will see that
00:18there is also this non tracking branch out there.
00:21What I want to do is be able to have that non tracking branch where I can work with it.
00:26Someone posted up there, I want to see what it is.
00:28I want to see what code they have put in there, bring it down, maybe I can make some additions
00:31to it and then push it back up there again.
00:34Now you may remember in the last movie, I told you that these remote branches are exactly
00:39like regular branches with one exception, and that's that we can't check them out.
00:44That makes sense because Git stays in control of that remote branch so it can make sure
00:49it always stays in sync with what's in the remote repository.
00:52It doesn't want us getting in the way.
00:55But since it is just like every other branch, we can create a branch from it that we can then work with;
01:01git branch and then our new branch name, non_tracking.
01:07After that we can tell it where we want the non _tracking branch to come from, the starting
01:12point of this branch.
01:14Now in the past, we just used the default for that which is HEAD, which points to the tip
01:18of the current branch master.
01:21But you can specify other things here.
01:22You can specify a particular commit or we can specify origin/non_tracking.
01:29So there it is, git branch non_tracking, origin non_ tracking, this will create that branch for us.
01:35Let's go ahead and check that out, you can see branch non_tracking set up to track remote
01:40branch non_tracking from origin.
01:42It created it, and it's a tracking branch.
01:45It's going to track this.
01:47That's what that syntax does for us.
01:49Now if I do git branch, you will see that I have that non_tracking branch, and if I
01:54take a look at my git/config file, you can see that it has set it up so that non_tracking
01:58will track origin/non_tracking.
02:01Okay, the next thing I want to show you is I want to delete that branch, we remember
02:06how to do that, git branch -d non_tracking, now that branch is gone, again, that's my
02:13version, that has nothing to do with what's on the remote repository, has nothing to do
02:17with what's in origin/master, those are still there, git branch -r, but what I want to do
02:22is I want to show you that you also can do git checkout with the -b option. Remember,
02:27this is create a branch and check it out, all in the same step, or check it out as a new branch.
02:34Let's say non_tracking and origin/non_tracking.
02:41So it's that easy for us to get a copy of the non_tracking branch.
02:44So now we are on the non_tracking branch, we can make commits here and then when we
02:49do a push, those will be pushed up to remote repository non_tracking.
02:55If we want to switch back to master, git checkout master.
03:00Now we are on the master branch, and we can make changes here, when we finally are ready,
03:05we can say push and those will also go to the remote repository.
03:09If we do fetch, it will get all of our origins and sync with what's in the remote repository,
03:14and then we can merge in.
03:15Hopefully, now you are starting to get the sense of the flow of how we fetch and pull
03:20and work with these different branches.
Collapse this transcript
Pushing to an updated remote branch
00:00In this movie we are going to talk about what happens when you try to push to a remote server
00:05that has been updated.
00:06Here is the situation that I'm talking about.
00:09Imagine that we have our remote server and our local repository and both of them have
00:13three commits in it.
00:14We do a fetch, so we know that we are completely in sync, we just have these three git commits.
00:20So once I know that I am in sync, I start my work for the day.
00:23And over the course of the next hour I put together a commit.
00:26I then commit it to my local repository.
00:29At the same time though, my coworkers and collaborators have also been making commits
00:34and they've been pushing their commits up to the remote server.
00:38So now when I try to push my commits to the remote server, the remote server says, well,
00:42I don't know what to do with your commits, there has been some new stuff that's come
00:45in in the meantime.
00:47Git never tries to do a merge during a push.
00:51Instead what Git says is, some new stuff has come in. I'm not sure what to do about all
00:56this. You need to fetch the changes that are on the remote server, then sort it out on
01:01your end and come back and try again.
01:04So we do a fetch.
01:05We've got the new information about what's on the remote server, we now see why there's
01:09a problem, oh, there were some other commits there.
01:11But that doesn't solve our problem. We've still got to merge our changes in with those.
01:17This is not just because there's a conflict, it's not because I changed Line 37 of index.html
01:23and someone else changed Line 37 of index.html, it's just simply because there were new commits.
01:29So what we need to do in this case is git merge origin/master, that will then merge
01:34my changes in with origin/master and create a new merge commit, and then I can push again
01:41and the remote server will accept it.
01:43If there were merge conflicts, I would need to fix those just like we do with the normal merge conflicts.
01:47But in most cases you don't even get conflicts, you just simply have to do the merge in order
01:52to send it to the remote server.
01:54So just keep that in mind, if you can't push the remote server, you'll just need to fetch,
01:59then merge, then push again.
02:02That way we can make sure that everyone's changes are taken into account.
Collapse this transcript
Deleting a remote branch
00:00In this movie, we are going to learn how to delete a remote branch.
00:03Essentially, what we are going to do is be able to tell GitHub that it should erase one
00:07of the branches in its repo.
00:09First, let's decide what branch we want to get rid off.
00:12You can see that I am inside my lynda_version folder on the master branch, if I do git branch
00:17-a, you can see that I have got this non_tracking branch locally, and I have also got non_tracking
00:23up on the remote repository.
00:25That's the one that I want to tell GitHub to delete.
00:28There are two ways that we can do this.
00:30First, I want to show you the older and less intuitive way, then I will show you a newer one after that.
00:36The first way is to use git push and just like we did before when we are using git push,
00:41we push to the remote, and when we did it before, we did it like this, we said, push
00:47the contents of non_tracking up it the server.
00:50In order to delete it, you put a colon in front of it.
00:54Git push origin, and a :non_ tracking will have the effect of deleting the branch
01:00on the remote server. Let's try it.
01:02So it wants my username, my password, it comes up, and it says that it deleted it, and now
01:11if we say git branch -r, you can see that it's gone, and if we go to GitHub, if you
01:18have Firefox, reload the page, and sure enough under Branches, you can see that we only have
01:24a master branch now.
01:26Now notice that if I do git branch for my local branches, it's still here.
01:31All I did was a push up to origin, I didn't do anything to my local branches, so I still
01:36have all that information.
01:38Why this awkward non-intuitive way of doing it? What's the colon all about? Let
01:42me give you some insight into that.
01:44When we did our original push of the branch up to origin, we did it like this, git push
01:48origin/non_tracking.
01:50That's actually shorthand for git push origin non_tracking:non_tracking.
01:57What this is saying is push to origin my local branch non_tracking, to the remote branch
02:03called non_tracking.
02:05That's what it's doing.
02:07When we only have one, it assumes that they are the same, which they often are.
02:11But this colon divides those two.
02:14So when we are doing a delete, what you are actually doing is saying, push to origin nothing
02:21up to the branch non_tracking.
02:23So that's why that colon is there.
02:25That's where it comes from.
02:26But that's not very intuitive.
02:27Let me show you the newer way, this is a little easier to remember.
02:30First, let's push that branch back up there again, remember it is going to push my local
02:34branch non-tracking up to the remote repository, so there it is now, git branch -r, you can see it's there.
02:43Now let's do another delete, git push origin again, but this time it's --delete and then non_tracking.
02:51It requires a little more typing, but it is a little easier to remember, a little more intuitive.
02:56So now we hit Return.
02:58It's going to want me to log in again, and once again, it's deleted it.
03:03So there it is now it's gone.
03:04So that's all there is to being able to delete a remote branch.
Collapse this transcript
Enabling collaboration
00:00In this movie I want to talk about how we can enable collaborators on your project and
00:05also how you can become a collaborator to open source project.
00:08Now you maybe thinking, well, wait a minute we've already been doing collaboration right?
00:12We have our explore_california repository, and we have lynda_version, right? Those are
00:16two people collaborating.
00:17Well, we have been kind of faking it, because the thing is both of these repositories are
00:21logging into GitHub using the same set of credentials, in my case they're both logging
00:26in as Kevin Skoglund.
00:27So I have two repositories pretending to be two different people, but it's really the
00:31same GitHub user.
00:33What if we want other GitHub users to be able to access our project? The way we do that
00:37is you go to the project homepage, and you click on Admin, it'll bring up a page here
00:42with Collaborators as one of the options, and then we can start typing the GitHub username
00:47of the person that we want to collaborate on it.
00:50Whatever the person's name is it'll start looking it up.
00:52Obviously, I'm not going to add myself to the project, I'm already part of it, but I'm
00:55just going to look up my username just to see how it comes up.
00:58So there it is, you start typing and it starts narrowing down the Kevin's until finally it
01:03finds my username.
01:04You have got to know the person's username or at least be able to find it here, and then
01:09once you do, you'll click Add to add them to the project.
01:13Once you add them to the project, then GitHub will send them an email telling them that
01:17they been added to the repository, and also providing them with this URL here so that they
01:22can then clone it and start working.
01:25And they'll have the ability to both read and write to that project.
01:28So that's an important step in enabling people to be able to work on your project with you.
01:33Now if you want to work on an open source project, it works a little bit differently,
01:37and the reason why is not everyone in the world can make commits to the actual project
01:43itself. It'll be a total free-for-all if everyone could just commit whatever they wanted to
01:47the project, instead a limited number of people have write access and can actually make changes to it.
01:53But everyone has read access, so everyone can see it, but not everyone can actually make changes.
01:59Instead the way that you make changes is that you need to make a fork.
02:02Now before you even make a fork, I suggest the first thing you do is decide what changes
02:06you want to make, what contribution do you have to make. Look at the network, make sure
02:10that someone else isn't already working on that change, make sure there is not a branch
02:14that's dedicated to that change, and look through the issues list to see if someone has posted
02:18there about the problem or the feature and maybe has even started a discussion about it.
02:23There's no sense in duplicating someone else's effort.
02:26And then it's also good form for you to post an issue there so that other people can see
02:30that you've already staked out this territory.
02:33The next thing I want to do is make a fork of the project. This will make your own version
02:37of the project on your own GitHub repository. It's no longer part of the main one, and this
02:42one you will have write access to.
02:44So you go ahead and clone the repository, work with it locally just like you normally would,
02:49commit those changes up to your version of the project, and then once you got it all done,
02:54it's ready to go, you go back to the GitHub page for the main project, and you issue a Pull Request.
03:00Essentially a Pull Request is like raising your hand and saying I have something here
03:04that I want to show you.
03:05You submit a message with your request so you identify what the problem was that you
03:09saw, or what feature you decided you wanted to add, talk about how you want to do it, and
03:13why you think it's good for the project, and if you make the case effectively and your
03:17code looks good then they will accept your changes and incorporate them into the main project.
03:22They'll grab your branch and merge it in.
03:25And then at that point, everyone will have access to your new feature.
03:28So that's how you can enable collaboration using Git. The process is little different if
03:33you're going to give someone else read/write access or if you're going to work on a project
03:37where you don't have write access.
03:40
Collapse this transcript
A collaboration workflow
00:00In this movie, we will look at an example workflow showing how to use Git to collaborate with another user.
00:07My hope is that this kind of real-world example will help to give you a big picture and will
00:11pull together all the different pieces that we have learned.
00:14But we are not going to actually make the changes, that would take more time and would
00:17also keep you from seeing the workflows clearly.
00:20For this example, I am going to collaborate with my coworker Lynda on adding a new feature
00:25to the Explore California web site and our new feature will be a feedback form, so the
00:29customers of Explore California can share their comments and feedback.
00:33Let's start by looking at what my work would look like.
00:36Now this is an ongoing project.
00:37I've already got my repositories set up, and I have already pushed at least the master
00:42branch up to the remote repositories.
00:44So let's assume that we have already done that ahead of time, I am just logging in today
00:48to create this new feature.
00:50I am already on my master branch, if I'm not, then I will check out the master branch that
00:54I start there at master.
00:56And then the very first thing that we want to do every day, every time we start work,
01:01every time we have been away from the computer for a few hours, we want to do a git fetch.
01:05We want to find out what new commits have been made and pushed to the repository since
01:09the last time we checked in.
01:11So I do my git fetch, and it turns out that there was work done overnight by some of my
01:15coworkers. Their commits are unrelated to the feature that I'm about to add, but I still
01:19want to make sure that I have to master.
01:22So the next thing I want to do is I want to merge those changes which are in origin/master
01:27into my master branch.
01:29Now at this point, my branch of master is totally in sync with what's on the remote
01:34repository, and I am ready to start my work.
01:37I am going to do the work on my new feature in the separate branch, and that way it won't
01:41interfere with anything that's going on with master.
01:43And if in the end we decide not to do the feature for some reason, it's easy to just throw it away.
01:48So the next thing I want to do is create that branch, and I will do that using checkout
01:53-b that will check it out as a new branch, or create the branch and switch to it.
01:59So now even though the contents of my working directory are the same as master, I've
02:03switched to my new feedback form branch.
02:07So I open up my working directory, I make the changes that I want there, in this case
02:12I am going to be adding a page called feedback.html, and I go in, and I edit the form and get it
02:17all look exactly like I want.
02:19When I am done, then I am ready to make my commit.
02:22So I add it to the staging area, and then I commit it.
02:25At this point, my changes are now on my local repository inside my feedback form branch.
02:31I am not ready to merge them into master just yet, I want my coworker Lynda to have a look at them as well.
02:37So I need to put them on the remote repository for her to see them.
02:40Before I push them up there though, I want to do a git fetch again and find out if there
02:44been any more commits that have come in that I need to take into consideration.
02:48If there have been, then I want to take a look at those and see whether I need to bring
02:51them into my feedback branch or not.
02:53In this example there were no other commits on master.
02:57I can go ahead, and I can push my branch up to origin, and I am pushing the whole branch,
03:02not just to commit.
03:03The branch doesn't exist up on the remote server until I push it.
03:07So I use git push, origin feedback_form, and then I also use that -u option.
03:12You will remember that makes it a tracking branch, so now in the future, I will continue
03:17to track changes from feedback_form, and it will save me some typing, because git will
03:21know where I want to push to without having to tell at each time.
03:26So when that's done, my work is now on the remote repository, now my coworkers can all see it.
03:31So I send an email to Lynda saying hey Lynda, remember that discussion we had last night
03:35about adding the feedback form? Well I did a draft of it, and I put it up on the remote.
03:40Can you take a look and let me know what you think?
03:43So now let's switch over, and let's look at things from Lynda's point of view.
03:46So Lynda also already has the repository, she has been working on it for couple of weeks.
03:51If she hadn't been, we know that she would do a git clone, in order to get the repository,
03:56and she is also going to be on the master branch, if not we will go ahead and just switch
03:59to make sure that she is there.
04:01The very first thing that Lynda is going to do, she needs to do a git fetch. Always the
04:05first thing. Until she does that fetch, she can't even see the branch that I pushed up there.
04:11Her computer hasn't sunk up so it doesn't have that information about all of the other
04:15branches that might be available.
04:18After the git fetch though, now git branch -r will show her that new branch, and she can see it.
04:24There were changes that came in over night from other coworkers, so she will probably want
04:29to incorporate those into her master branch to just to make sure that master is always
04:33brought up to date.
04:34It's not strictly necessary, but it's a good practice.
04:37After she has done that, she will be ready to take a look at my work.
04:41So she will want to check out the branch that I pushed up there.
04:44Again she will use check out with the -b option.
04:47This time she won't just say feedback form which would take it from the branch that she's
04:51currently on, her version of master, instead she will say feedback form and the source
04:56from that is going to be origin feedback form, the one that I put up there.
05:00It will also make it a tracking branch at the same time, so she wants to see what I
05:05did, she is going to use git log and she can find the commit that I made or added feedback.form.html.
05:12She can also take a look at the actual commit itself, she will use the SHA probably. She
05:17could also use HEAD if that was still the last commit and see what that said. She could
05:21also use the branch name, git show feedback_form, and as long as it's the last commit that's
05:26the one she would see.
05:28After looking at my commit and bringing it up in the browser to take a look there, Lynda
05:32decides that we should add a select option to the form so that customers can pick which
05:37tour they took and include that with the feedback, and that way we will know which tour they
05:42are referencing when they talk about the tour that they took.
05:45So she makes that change and then she commits it and she does that using the -a option so
05:50that it both adds it to staging and commits it all at the same time.
05:55Now she has got that change on her local machine, she needs to put it on the remote where I
05:58can see it. So she does a git fetch to make sure no new changes have come in, they haven't
06:03so she does a git push.
06:05At this point Lynda is done.
06:08So she sends me back an email saying, it looks great I just made one quick change.
06:12On my side again, I want to see what change she has got, so the very first thing I do
06:16is fetch, so I can see the change.
06:20Before I merge it in though, I want to take a look at it, so I am going to using git log.
06:23I am going to use the -p option which is for patch, and it will show each of the log entries
06:29with a diff of all the changes that were made in that log entry.
06:32And I am going to ask it to show me everything from feedback form, my copy, up to where origin
06:39feedback form is. That's the difference between the state of mine and the state of what Lynda
06:44pushed up to the repository.
06:47So I can look at those, and I can take a look at all the changes that she made, those changes
06:50look fine, I like them.
06:52So I am going to now go ahead and merge them into my feedback branch.
06:57So at this point now, the feedback_form branch is in sync between me, the remote repository
07:03and Lynda. We all have the same things.
07:06In this case the merge was a fast-forward merge, so there is really nothing to commit,
07:10but if I had made other changes in the mean time that I needed to merge in, well then
07:14I would merge those together, and we will push the result back up to the remote.
07:18But since I didn't, since it was a simple fast-forward merge, I am ready to now call
07:22this feature finished and to fold it back into the master branch.
07:26So I am going to switch back to the master branch, after I switch branches, I want to
07:30do a git fetch and find out if there were any changes that came in, while I was looking
07:34at Lynda's changes.
07:36If there were new changes that came in, I am going to merge those back into origin/master.
07:41At this point now, master is completely up to date. I definitely want to make sure I
07:45have got master as up to date is possible before I do this next step.
07:49Then next step is that I am going to merge in the changes from feedback form.
07:53I am going to take the new work and merge it into the most recent possible state of master.
07:58I did a merge from feedback_form but I could have just as easily done a merge from origin feedback_form.
08:04They both point to the exact same commit and then after I have made that merge, and I've
08:10resolved any kind of merge conflicts that might have come up, then I do git push, and
08:15now my work is on the remote in the master branch where all of my coworkers can see it,
08:21where it can eventually be deployed on the Explore California web site.
08:24That gives an idea of the process which you go through when you're collaborating with the coworkers.
08:30It may change because you may be collaborating with three or four different people, you may
08:33all be checking in and out things, but it's the same basic kind of process over and over again.
08:39It may seem like a lot to remember when you're a beginner, but it becomes second nature very quickly.
08:43
Collapse this transcript
14. Tools and Next Steps
Setting up aliases for common commands
00:00In this movie, I want us to take a look at some of the tools and next steps that you
00:04should consider as you continue to grow your skill set.
00:07I want to start by talking about how to set up aliases, or keyboard shortcuts for common Git commands.
00:13Now aliases can be a little bit dangerous, especially if you are beginner, what you don't
00:17want to do is accidentally confuse yourself and start using an alias and thinking it is
00:21the actual command.
00:23So it may be to your benefit, to stick with the actual Git commands for a while, until you
00:27get really familiar with them, and then when you are really are looking for a speed increase
00:31and trying to have less typing, to do something that you already know how to do well, then
00:36you can start using aliases.
00:37When we set up aliases, we are going to set them up in any git config file, but it probably
00:42makes more sense to have them in our user global config file then it does to have them
00:46in the project config file, because we probably want to have them available to us in every
00:51project that we work on, and they are often going to be user specific.
00:55I don't necessarily want to have the same aliases as one of my coworkers does.
00:59So instead of putting them inside our explore_ california directory, we are going to put those in our
01:04user directory in the get config file there, which is a refresher, if we go back and take
01:09a look, that's going to be inside this directory here .gitconfig.
01:14On Linux you can also just use the tilde to represent your user directory.
01:19Now there are two ways to add aliases to that file.
01:23One is to go and then edit the file directory, the other one which we are going to use is
01:27the git config using the global option. We saw how to do that in the early configuration,
01:33and then we will use alias, followed by what we want to alias.
01:37So we want to have, what keyboard shortcuts related to what command. I am going to do status first.
01:44Status is something that we type all the time, and we definitely can save ourselves some time
01:48by just having to type st instead of having to type out status, so st space and then the
01:54command that we want.
01:56You can put the command inside double quotes here but they are optional unless the command
02:01has a space in it.
02:02If the command that you are going to enter has a space in it, you need the double quotes.
02:07Once I do that, it now adds it to my config file, we can take a look at that, I will use.. /..
02:13to get to my git config file.
02:16And you can see that it added an entry here for alias with square brackets around it,
02:22and I have got st = status.
02:25So you could go into the file directly and use the same format to just continue adding
02:28new entries, right under st, st= whenever, you don't need to do the alias portion again,
02:34you are just in a big block here. The same way that these are done, one after another for this block,
02:39but I am going to ahead and keep using git config to set these up.
02:43So let's try that out, I am inside my git repository, I can now say git st instead I
02:48get status, and you see that it comes up and tells me the status.
02:52Okay, let's try creating some more now.
02:54Now the set that I am going to give you is a very common, very popular set.
02:59I think probably most git developers use these or some version of them.
03:03So while you can use whatever aliases you want these have become kind of standard.
03:08The first one is co which is for checkout, makes sense, co checkout.
03:13The next one we can have ci which is for commit. When I see ci I think check in, which is not
03:21the same thing as commit, checkout and check in but just don't be tricked by it.
03:26Don't thing that check in is an actual command in Git, it's not. Commit is the command.
03:32And then we can have one for branch, we will use br for branch, and this one I find less
03:37useful, but for diff we can use just df.
03:40It really doesn't save that many keystrokes, so I usually go ahead and type diff myself.
03:46And then a lot of developers use some version of either dfc or dfs, and then they use diff
03:52--staged, or diff --cached.
03:56And that shows the difference between the staging index and your repository.
03:59Now because it has a space in it, we want to make sure that we do put double quotes around it.
04:05Now note that just because these are shortcuts for the command, we can still put other options
04:10and arguments after it.
04:11So for example, if want to do git branch with a -r option I can use br with the r option,
04:18and it does the exact same thing.
04:21That's kind of a standard set.
04:22Let me show you just one more that I think you might find useful, and that's a log, and
04:27I just do a logg with another g after it. You can use whatever you want, but log with
04:31a g after it, and I am going to say that is going to be in double quotes, log --graph,
04:38--decorate, --oneline, --abbrev-commit and --all and then double quotes that the end.
04:47I used this a couple of times during the tutorial, so you probably remember it.
04:52So now if I just type git logg I don't have to remember all of those options.
04:56It goes ahead and gives me the nice graphical representation of my log showing where all
05:01the branches and the merges are over the course of time.
05:05So feel free to customize the aliases to your liking, but don't let them become a substitute
05:10for understanding what the actual commands are and what they actually do.
Collapse this transcript
Using SSH keys for remote login
00:00Throughout the chapter on working with remotes, every time we want to communicate with the
00:04remote repository, we had to enter our credentials again, our username and our password, and
00:10we had to do it every single time, even if we were just doing git fetch, we had to login
00:15to that server again.
00:16It doesn't take very long before you get really sick of typing your username and password
00:20over and over again, so you're going to want a solution to that.
00:24There are basically two ways to do it.
00:26One is to have a keychain program that will store your username and password, and then
00:31Git will be able to go to the keychain program, get your username and password, and send it
00:36to the remote along with your request.
00:39If you decide you want to do it this way, GitHub has a help article that can help you to do it.
00:44They have a page on setting up Git, it's help.github.com/articles/ set-up-git, and then if you add the # sign, password-caching,
00:54it will take you right to the part of the page about caching your password in a keychain.
01:00And it uses OS X keychain, which of course is for Mac.
01:04You need to have Git 1.7 10 or newer to use it, and you need to be on a Mac.
01:10Then you can follow their instructions for getting that set up.
01:13And then it will remember your username and password in your Mac OS keychain.
01:17That's the keychain that you can see in your application utilities folder.
01:21If you aren't on a Mac, or if you decide not to do it this way, you can also use SSH Keys,
01:26and this is the way that I actually do it.
01:28The idea behind SSH Keys is different than caching your password in a keychain.
01:33Instead, we have a little bit of code, an actual file that resides on my computer.
01:39And I take that same code, or actually a complementary part of it, and put it up on the GitHub server.
01:46Then when I go to make a request, Git automatically sends that bit of code along with the request
01:52and uses those to authenticate me and see that I am who I say that I am.
01:57There are many resources out there on the web that can help you to get SSH Keys set
02:00up and to get them working with whatever host you provide.
02:04GitHub also has a help article, and that is help.github.com/articles/generating-ssh-keys.
02:13And you can see here that you can then pick between Mac, Windows, Linux or All, and it
02:17will give you step-by-step instructions on how to get those set up.
02:22One thing that you should note though that's very important is that when you go to the
02:25project, Git has http selected by default as the address format here for the repository.
02:34If you're using SSH, you need to press this button first to get it in SSH format.
02:39If you are going to type it each time or if you are going to use a keychain, you'll want to use http,
02:44but if you're using SSH Keys, you'll want to switch and use that.
02:48Whichever way you choose, you'll save yourself a lot of time by not having to type username
02:52and password every time you want to connect to the remote server.
Collapse this transcript
Exploring integrated development environments
00:00Many of you are probably new to Git, but not new to the world of development, and you probably
00:05have some tools that you already like to use.
00:08Typically, these would be editors and integrated development environments, or IDEs for short.
00:13If you have a favorite tool, it's very possible that that tool has some kind of Git integration
00:18available for it.
00:20For example, I'll just show you with TextMate, TextMate has bundles, and under Bundles you'll
00:25see there is a listing for Git.
00:27And there's lots of different features that we can do right from TextMate in Git.
00:32So if we want to see our status, we can just run git status right here from inside Git,
00:36and there are some quick keys and shortcuts that will make that faster.
00:39And if your favorite editor or IDE doesn't have Git support built-in, there may be a
00:44plug-in that adds that functionality.
00:47I won't go through all of them, but I am just going to list off some of the more popular
00:50editors and integrated development environments that you might use.
00:54All of these have some kind of Git integration available to them.
00:58So if any of these are something that you're already using, you'll definitely want to look
01:02for those features and find out how to use them.
Collapse this transcript
Exploring graphical user interfaces
00:00All the interaction we've done with Git so far we've done from the command line, and
00:04that really is where Git sort of lives, and it's the best place for you to get started
00:08as a beginner and get familiar with those commands.
00:11However, some people find that after they've had experience with the basics and they're
00:16familiar with the command line, they find that they can actually speed up their workflow
00:19by incorporating a graphical user-interface to help them to see the state of the Git project
00:25and actually work with Git by using a graphical user-interface instead of typing.
00:31There are number of options available to you for this.
00:33The first and simplest is just GitWeb.
00:36GitWeb is included with Git. You need to actually set up a web server to be able to do this, so
00:41it does requires some amount of technical knowledge, because you do need to be able
00:44to set up the web server to host it, but what it does is it let's you see your get repository
00:49as a little mini web site.
00:51Now that's a pretty basic and limited way of doing it, but it is on the web where it's
00:55available for everyone to be able to see which is kind of nice.
00:58And on a more personal level though you will probably going to be more interested in a
01:02graphical user-interface application that you can download onto your computer.
01:07Let's start by looking at a few of the most popular ones for the Mac.
01:10GitX is probably one of the oldest ones, it's been around the longest, GitHub of course
01:15we know is the hosting company, they also offer a application client that you can download and use.
01:22Now I'll give you a peek at GitX and GitHub just so you get an idea of what a graphical
01:26user-interface can do for you.
01:28But before we do that let also look at the list of Windows applications.
01:32So if you're on Windows, you'll probably want to look at one of these, these are the most popular ones.
01:36And again you'll see the GetHub is in that list with their Windows client, and SmartGit
01:42actually has one for both, they are cross- platform they offer it for both Mac and for Windows.
01:47Like I said, there are many, many of these and new ones are appearing all the time. There
01:51is actually a pretty good list maintained on the Git Wiki, so if you go to git.wiki.kernel.org/index.php/
02:00InterfacesFrontendsAndTools with caps in there, and it'll give you a list of all the different
02:05interfaces, front-ends, and tools that are available to you.
02:09Based on the popularity of the choices that I showed you earlier though, you probably
02:12won't need to go to this very exhaustive list.
02:15Let me can give you an idea of what a graphical user-interface can do for you.
02:19So this is GitX, and you can see here that it's showing me this kind of graphical view
02:24that I was looking at from the command line, its a little nicer looking here.
02:28If I click on any one of these edits, you'll see that it shows me down here what the edit
02:31actually looks like, I can switch to look at different branches. I'm on master now, but
02:35I can switch and take a look at non-tracking, seo-title, shorten_title, see what those all
02:40look like, and I can look at my remotes and see the state of things there.
02:44I also have the ability to stage in my commits here. It'll give me a list of all the files
02:49that have changed right here, I can select them, and I'll move them over here to the
02:54stage changes side.
02:56And then when I'm ready, I can write a commit message and actually do the commit from here as well.
03:01Up here this area just shows you the different changes, so you can review them. So as you
03:05click on the different files you can review the changes before you stage them and then commit them.
03:11Now it's got lots of other features but that does give you an idea of how you're able to
03:14see your repository and interact with it from a graphical user-interface.
03:19Let's take a look now at GitHub. This is the GitHub Mac client, so here once again, we can
03:25see all the different commits I've made. This is essentially my log, the history, if I want
03:29to view information about one of those I can just click on the arrow here, it'll take me
03:33to more information about it. I can revert the commit from here, go back to my history again.
03:39The changes I can also make from here, uncommitted changes, this is to let me put in my commit
03:44message, and then I can select the files that I want to stage and then add with commit,
03:49and this is the file viewer over here where I can watch those.
03:53I've also got branches here where I can see all the different branches, and I can even
03:56go up here to Repository, I can do things like switch branch if I want to quickly just change
04:01to my non-tracking branch, now I'm on the non-tracking branch. I don't actually have
04:05to check it out, it does it for me just like that.
04:09All these graphical user-interfaces all have a different look to them, a different sense
04:13of what's important, and probably you'll need to try three or four of them until you find
04:17one this sort of feels right to you, but again, as a beginner, I think it's important not to
04:22become too dependent on these graphical user interface tools. You want to make sure that
04:26your command line knowledge is still solid before you start using them to speed things
04:31up for yourself.
04:32
Collapse this transcript
Understanding Git hosting
00:00In this movie I want to talk about hosting Git repositories.
00:04Now obviously I am not talking about the local repository that you just have on your machine,
00:08all you need is Git to be able to do that.
00:10What I'm talking about are the remote repositories that are hosted somewhere where multiple users
00:16can all have access to that one remote.
00:19To do that, we need to have some kind of a Git server set up to handle requests from all
00:23those different users at the same time.
00:25There is basically two ways you can go with it.
00:28You can either have a hosting company take care of the hosting for you, or you can self-host.
00:32We've already seen how a hosting company works, because in the chapter on remotes, we were
00:37working with GitHub.
00:39GitHub is the oldest, most popular, and probably most reputable of the Git hosting companies.
00:45But they're not the only game in town, Bitbucket and Gitorious are also both very popular and
00:51rising quickly in popularity, so I encourage you to check out all three.
00:55See what their different pricing plans are like, see what features they offer, and decide
00:59which one you like the best.
01:01I think you can't go wrong with any of them.
01:03The advantage of using a hosting company is that either for free or very little money,
01:08they take care of everything for you.
01:10So they handle all of the server administration.
01:12They handle things like data backups.
01:14They make configuration easy.
01:16They give you a graphical user interface to do it.
01:18And they even give you tools to look at the information in your Git repository in interesting ways.
01:24However, hosting to these companies is not for everyone.
01:27For some people you need to go with self-hosting.
01:30And it's not just simply a matter of cost and trying to save that few dollars a month
01:34on hosting, for a lot of people they need to keep their code inside the firewall.
01:38If you work at a corporation, or especially for things like governmental agencies, it
01:42may be that you can't share your code with a third party, no matter how secure their web site is.
01:47You have to keep things inside the firewall.
01:50You won't be able to make, push, and fetch requests to some external entity.
01:55And in that case, you'll need to set up self-hosting.
01:57It used to be that the main way to do that was by using software called Gitosis.
02:02So you would set up Gitosis on your internal servers, and then that would be what everyone
02:06would connect to, and it would be like having your own personal GitHub, with a lot less features.
02:12The problem with Gitosis is that development on it stopped two or three years ago, so it
02:17hasn't been continually updated.
02:19Gitolite though is very much in active development, and it's constantly being improved.
02:25It's based on Gitosis, so both are going to be very similar, but I think you'll have better
02:28luck if you start with Gitolite first.
02:30And you may find it difficult if you are a beginner, but anyone with some server admin
02:34experience should be able to get them set up.
02:37
Collapse this transcript
Conclusion
Goodbye
00:00I want to thank you for taking Git Essential Training.
00:03We covered some powerful techniques for managing your source code in this training title.
00:07Using Git can revolutionize the way you code.
00:10You'll have more confidence to make big changes knowing that your old versions are only just
00:13a few keystrokes away.
00:14You'll feel empowered to try new ideas and code branches without worrying that you might
00:19break the main project.
00:21And you'll be able to collaborate effectively with other Git users, whether it's on your
00:24own project, on a company or client project, or on an open source project.
00:29I think you'll find that Git changes the way you code in less obvious ways too.
00:33Your changes will become smaller and more focused.
00:36The intentions behind each of your changes will be made more clear.
00:39Git forces us to continually consider what we are doing and why we are doing it.
00:44Git also helps us to see the changes that others make so that we can learn from their
00:48choices and their style.
00:50Once you start using it, you will quickly consider Git to be an indispensable tool for all development.
Collapse this transcript


Suggested courses to watch next:

Unix for Mac OS X Users (6h 35m)
Kevin Skoglund

Installing Apache, MySQL, and PHP (2h 43m)
David Gassner


PHP with MySQL Beyond the Basics (10h 27m)
Kevin Skoglund


Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,069 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,024 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked