5.3 Working with Remotes
When working with Github, you’re working with remote repositories. But remember, this information is true for any remote repositories, even ones on your own Git servers.
1.Introduction3 lessons, 19:10
2.Basic Commands4 lessons, 23:13
3.A Bit of Theory2 lessons, 23:37
4.Logs and Branches4 lessons, 33:30
5.Github and Remotes4 lessons, 41:49
6.Intermediate Usage6 lessons, 41:55
7.Conclusion1 lesson, 01:07
5.3 Working with Remotes
I hope you've been wondering how the Git repository on our local computer knew where to send the project history when we originally sent it up to GitHub. That's what we're gonna be looking at in this video, and it's all about remote branches. But before we can actually talk about remote branches, we need to have a remote repository. A remote repository is just a reference to another repository, usually one that we have write access to. When we first connected or project files up to GitHub, we ran a command that looked a lot like this. git remote add and . This is the way we add a remote to our project. The name is the unique name that we want to give the remote repository, and the link is the link to the repository. In our case, we added a remote called origin, cuz that is the default that GitHub recommends. And then, we had git@github etc., link, and that is the link to the remote that we added. So if we actually just run git remote, you can see right there we have a single remote that's named origin. So now that we have this remote, this other copy of the same repository on a different computer, that means we can have remote branches. And if I run git branch -a, you can see we have two branches. The master branch, which is what we are on, and we have remotes/origin/master. When we pushed all our content up to the GitHub repository, and we'll look at how to do that soon, it actually made a master branch in that repository, and that is what this remote/origin/master branch refers to. We have a reference in our local repository here that points to the commit that origin/master is currently pointing to. But we can't actually change what origin/master points to without actually pushing something across the network. So if we run git log --oneline --graph --decorate, as we've done in previous screencasts, notice that one of the decorators is origin/master. And as you can see, HEAD, origin/master, and the master branch are all pointing to the same commit. That basically means there are no changes on our local master branch that have not also been sent to the origin master branch. So the master branch on our remote repository is up to date with our local repository. So now, let's make a change and see how that does not automatically get copied onto our remote branch origin/master. Remember in how our previous screencast we saw that the README file was not being converted from markdown to HTML when GitHub was displaying it? It just was showing the raw markdown. We want to make sure that it's being converted to HTML. So we're gonna use the git mv command to rename the README file to README.markdown. Now if I run git status, you can see that we have a change to be committed. That's great, we're gonna run git commit -m, we'll just change README to README.markdown. Excellent, so we've made that change. Now let me clear this again and we're going to once again run git log --oneline --graph --decorate. And now notice something interesting. HEAD and master have moved up commit. But origin/master has stayed at the same commit, because origin/master represents the status of our remote repository that's across the network. And the only way to actually update that branch is to push our content to GitHub. So this is going to introduce a new command, and that is git push. So we want to run git push. We want to push to the origin remote. And we want to push the master branch. So git push origin master. I'm gonna hit enter, and you'll notice it's going to take a second to connect to the network, and then we're gonna see a bit of content spit out here. Oh, and actually before we do that, I have to give it my SSH passphrase, and that's because last time I didn't choose to remember the password in my keychain. So I'm going to choose to remember that password in my keychain, I'll click OK, and there you can see that everything has been pushed up to master. You can see right here, to github.com/sherlock project, we have updated master to master. So now if I clear the screen and run the same git log command, you can see that HEAD, origin master, and master all point to the same commit, because that commit is now up on the remote, and origin/master is pointing to it. Here we are on our Project page on the GitHub site. And notice that the latest commit here was made by the Sherlock Tuts user as opposed to the Andrew Burgess user that we saw previously. And we have changed README to README.markdown. Now if we scroll down the page here, you can see that this is actually being converted to HTML and it looks much better than it did before in its raw markdown state. So that is how we will push content up to GitHub. You'll use the git push command, and there are many different ways to use the git push command. But for now just remember the basic way that you'll probably use most often is git push, the name of the remote which in our case is origin, and the name of the branch, which is master. And that's the most basic way to use the push command. Now that we're here on the GitHub page, I want to point out something else to you. You'll remember in the last screencast, I mentioned pull requests very briefly, but we didn't actually get into it. Here's the idea. A pull request is when another user uses the fork command here to fork your repository, they make some changes to it, and then they send you a pull request to let you know I've made some changes. Check them out, if you like them maybe you want to pull them in to your own repository. So that's what we're gonna do here. I've actually signed into GitHub in my primary account, forked this very repository, made a change, and sent a pull request. If we go here to the pull request tab, you'll see that we have one open request, and the request says that we updated the TODO file to add another todo item. So let's pull this change in. I'm gonna click on that link there to view the pull request, and let's see, if we look at the commits here we can see there's only one commit that we're gonna be pulling in by this pull request, and that's the update todo commit. Now if I look at the diff, we can see very easily that what I've done is I just added another todo item to the bottom of this file. All right, I like that, so let's pull it in. Let's go back to the discussion, here. And if we scroll down here, we can see that this pull request can be automatically merged. GitHub can look at the contents of the pull request, and see, is it gonna cause any kind of a merge conflict when you pull it in? In this case, it's gonna be merged cleanly, so I can say, merge pull request. I'm just gonna leave it with the same merge commit. And I'm gonna confirm the merge. As you can see, this pull request has now been marked as closed, because the commit was merged successfully less than a minute ago. Now if we come back here to the code, you'll be able to see that the latest commit was Merge pull request number #1 from andrew8088/master. If we come down to the TODO here we can see over here that the message update TODO Was made by user andrew8088. If I look at that TODO file, you can see that our fourth todo item is in that TODO file. But now this raises an interesting point. The master branch in our project repository on GitHub is actually ahead of our local repository by one commit. So what we have to do now is actually pull those changes down from GitHub to our local repository. The easy way to do this is to use a git pull. And those changes will be pulled down from GitHub and merged right into our repository. If we go ahead and do that, you can see exactly what's happened. Our master branch here has been updated from origin/master, and the TODO file has been fast forwarded by one commit. We have changed one file. So now, if I just cat out the TODO file, you can see that our last line is added there. And you might wonder why did our prompt not actually get put on down to the new line, and that's because the TODO file doesn't have a newline character at the end of it. However, in more complex cases that could be kind of careless, don't you think? We're pulling down changes from GitHub and accepting them without even knowing what they are. Now of course, in this case, we do know what they are, because we had to accept them into our repository. But here's another scenario. Let's say that instead of forking the repository in GitHub and creating our own version of the project, we just wanted to use git clone too clone down another repository. For example, the coffee-script repository. Right here, I can just copy this URL and use the git clone command to clone this down. And if I clone this, you'll see it's cloning into the coffee-script folder. And now you can see, we've downloaded the coffee-script repository. So I can cd into coffee-script. So back to our hypothetical pulling scenario. What we just did is pull down the changes, and merge them in right away, because we knew what those changes were, because that was our own repository we were pulling them from. But let's say I'd made changes to the coffee-script project, and then I was gonna do a git pull from the coffee-script project. That could override or get rid of some of my changes, and I wouldn't even have the option to not do that. So let's do this. So what we want a way to do is to pull down the changes, look at them, and then merge them in ourselves. So I'm going to move back into our project folder, which I've magically pushed back in time to before we actually pulled down that commit, as you can see. And now we're going to actually break that pull into two separate commands, one that gets the content, one that merges it. But we already know the merge one. That's git merge, which we've done with branches before. But how do we get the content? For that, we use the git fetch command. Since we're not passing it any parameters, it just looks at our remotes and we only have one remote, which is origin. So it pulls those down. So now, we've pulled those changes down. Let me clear the page again. And once again, I'm gonna run git log. As you can see, origin/master isn't even on this graph anymore. So I'm gonna have to add the --all flag, so that it will include graph items that are not part of this specific branch. Now, you have a better view of what actually happened. Right here, as you can see, is the last commit that we made in our local repository. But since then, on this branch off here, we've done that update TODO commit. This is the commit that my other GitHub account made and then issued the pull request for. Up here you can see that origin/master has actually merged those two branches. And therefore, from the view of origin/master, we're actually all the way up there. So now, what we have to do is merge the master branch with origin/master. So I'm going to do git merge, and we want to merge, since we're on the master branch, we want to merge origin/master, and as you can see it was very quick and simple. We did a fast forward, and now if I clear the page, and run that git log again, you can see that HEAD, origin/master, and master are all on the same commit. And now our local content is the same as our contents up on the GitHub page, and if I run git push you can see that everything is up-to-date and there was nothing to send across the wire. So now, everything has been updated. So there you go. Those are the basics of working with your GitHub repository or any remote repository. We've pushed content up to our Git repository, pulled content down. We've done a fetch and merge to make the pulling action a lot more granular, and we've even issued a pull request from one GitHub account to the other. I'd say you're getting pretty good at using Git in a network situation.