New terms from treehouse – Git Basics Part 2 – Merging, Working with Remote Repositories, and Workflowst

Merging

Intro to Merging

This how you get your branches back together, it’s like the opposite of branching. It merges all of the branches’ changes and commits into one cohesive timeline. The other branch doesn’t go away, and you can keep merging and working on it as long as you like, you’re just copying the commits from one branch into another.

If a file was changed in both branches, this is called a merge conflict and you need to decide which one to keep. Git does its best to auto resolve these for you, and if it can’t it will ask you.

Basic Merging

If you don’t have conflicting changes between two branches, merging can be done easily. Let’s merge foo_feature back into master. Start with git branch to see where you are, and make sure you’re in master. Then, use the git merge command followed by the name of the branch you want to merge into the one you’re in now.

Screen Shot 2014-11-04 at 3.57.49 PM

Let’s set up some merge conflicts by changing the README in our two branches.

Screen Shot 2014-11-04 at 4.01.38 PM

Since they were on different lines, git auto merged them for us. Both commits are now listed in master. It does this by creating a new automatic merge commit.

Screen Shot 2014-11-04 at 4.02.43 PM

Remember that the foo_feature branch is still around, and that the merge only affected the master branch.


Merge Conflicts

Here, git will present you with the conflict and ask how you want to handle it. We’ll set one up by making changes to the same line in file1.

Screen Shot 2014-11-04 at 4.09.13 PM

When we go to merge, we get this conflict message.

Screen Shot 2014-11-04 at 4.10.49 PM

To resolve this, you can just edit the conflicted file so it matches. If we open file1 in our text editor we’ll see conflict markers which show us where the conflict occurred. The angle brackets surround the conflict, and the equals signs separate the two versions.

Screen Shot 2014-11-04 at 4.13.11 PM

You can just remove the conflict markers and save that if you want, delete the change from one of the branches, or combine them, which I’ve chosen.

Screen Shot 2014-11-04 at 4.15.02 PM

Now, we need to add our commit to the staging area, then run git commit.

Screen Shot 2014-11-04 at 4.16.16 PM

Git knows we’re correcting a conflict, and has created a useful commit message for us.

Screen Shot 2014-11-04 at 4.16.52 PM

Screen Shot 2014-11-04 at 4.17.44 PM


Working with Remote Repositories

Working with Remotes

If someone needs to work on a project with you, they can’t use your repository because it’s on your computer. But, they can make a copy of yours for their computer, and this is called cloning.  Later, after you’ve both worked on it for a while, you can merge your copies of the repository, much like you would merge branches. You’d have a central repository on a server somewhere that is the official version of the code.


Cloning

In this example, we’re going to clone a repository on our computer, but cloning a remote one would work the same way. You can clone a repository using the git clone command, followed by what to clone. You can optionally add what you’d like it to be named after that.

Screen Shot 2014-11-04 at 4.39.46 PM

If we look inside our new directory, we’ll see it’s a copy of our files, and we can access the git log just like before.

Screen Shot 2014-11-04 at 4.41.09 PM

Git also automatically set up our original repository, named origin, as a remote one when it set up this new one. The git remote command lets us see all the remotes available to this repository. In this case, there’s just the one called origin.

Screen Shot 2014-11-04 at 4.43.12 PM

If go to our original repository and run the git remote command, nothing gets printed out, which means the original repository isn’t affected at all by the clone. This is good, because if a lot of people were making copies, you wouldn’t want to have have it affect the original every time.

Screen Shot 2014-11-04 at 4.45.10 PM

Still to get the origin to notice and be able to talk with the remote one, use the git remote add command. Note that you can choose a name for it, in this case “our_clone”.

Screen Shot 2014-11-04 at 4.48.56 PM


Pushing and Pulling

We’ll start by creating a new branch in our cloned repository, then changing file2’s text and committing it.

Screen Shot 2014-11-04 at 4.52.52 PMTo get this back to the remote repository, we can push our change using the git push command, which should send all of our changes to there.

Screen Shot 2014-11-05 at 1.39.04 PM

It says everything is up to date, which seems like nothing happened. This is because the new_feature branch we created doesn’t exist in the remote repository yet. Git doesn’t know it needs to be tracking changing in that branch across both repositories. You need to explicitly say that by adding it to the git push command.

Screen Shot 2014-11-05 at 1.41.17 PM

Once again an issue. By default, the first argument you provide git push needs to be the remote. Otherwise, it will assume you’re referring to git origin. Seems we need to explicitly state that here.

Screen Shot 2014-11-05 at 1.43.31 PM

If we switch back to our origin repository and check it’s branches, we can see it’s now there. If we were to check its git log, we’ll see the commit for file2 there as well.

Screen Shot 2014-11-05 at 1.44.27 PM

Let’s say the person working on the origin didn’t like the change to file2 in the new_feature branch and wants to edit it. They do that, then switch back tot he master branch.

Screen Shot 2014-11-05 at 1.49.26 PMMeanwhile, the other dev is working in their clone project repository, and edits file2 again. We’ll then push the change to the remote.

Screen Shot 2014-11-05 at 1.52.40 PM

But, we get an error saying that our file is not up to date, so we can’t push. We can update our end with the git pull command. It takes two arguments, the remote to pull from, and what branch. It tries to pull it over and gets a merge conflict error.

Screen Shot 2014-11-05 at 1.54.38 PM

Pull works like merge, the difference being instead of pulling in changes from another branch, it grabs them from another repository. Time to resolve the conflict by editing the file2 with nano, and picking what we want to keep.

Screen Shot 2014-11-05 at 1.56.21 PMScreen Shot 2014-11-05 at 1.57.11 PM

We save, add our file to the staging area, and then commit it. We confirm our git message, the try git push again.

Screen Shot 2014-11-05 at 2.00.30 PM

Back in the master, we’ll make an edit to file1 and commit it, then try running git push.

Screen Shot 2014-11-05 at 2.01.43 PM

We get an error about no configured push destination, so let’s add that.

Screen Shot 2014-11-05 at 2.03.36 PM


Workflows

Git-Flow

Git-flow is a sub command you can install for git. Once installed, we’ll add a new branch, then initialize it using the git flow init command, which will ask you a series of questions about your preferred workflow. First you choose what will be your production branch. In this case we’ll choose master, which is the usual choice.

Screen Shot 2014-11-05 at 2.41.29 PM

Next it asks you to set the branch for integration of the next release, where features will go when they’re finished, but before they go live on the site. This is what we created the integration branch for.

Screen Shot 2014-11-05 at 2.43.00 PM

Next it asks you about branch prefixes. Git-flow’s model is to handle everything by creating a branch, which can be overwhelming if you’re not careful with the organization of them. These prefixes help to categorize the branches.

Screen Shot 2014-11-05 at 2.45.36 PM

Next it asks you about the version tag prefix. Git allows you to add tags for your commits. Anytime you move a change to the master branch, git-flow will tag it with a special message so you can find it later.

Screen Shot 2014-11-05 at 2.54.02 PM

The initialization process is done, and now you can use git-flow. To start a new feature, enter git flow feature start, then the features name. You’ll see it tells you the branch was added with feature/ before it, in the integration branch. It also tells you what to do when you’re done.

Screen Shot 2014-11-05 at 2.55.24 PM

When you’re done, it will merge the branch into the one specified and switch you to it (integration in this case), as well as delete the branch you were working on.

Screen Shot 2014-11-05 at 2.57.04 PM

To make a hotfix, it works the same way, only you use the command git flow hotfix start, then its name. Note that it’s based off the master branch this time, because it’s a hotfix.

Screen Shot 2014-11-05 at 2.59.29 PM

When you’re done, finish it the same way as before.

Screen Shot 2014-11-05 at 3.01.19 PM

Git-flow will prompt you for a tag message, save, and you’re good to go.

Screen Shot 2014-11-05 at 3.02.30 PM

Advertisements

New terms from treehouse – Git Basics Part 1 – Why Version Control Matters, Getting Started with Git, and Branches

Why Version Control Matters

Introduction to Git Basics

VCS means version control system, and lets a developers work in the same code base together without stepping on each others’ codes.

Life without Version Control

Cowboy coders – coders who don’t follow best practices.

If you write a feature, decide you don’t want it and delete it, but then then decide you want it later, it helps to have a version of each time you saved on hand, with a description so you can pull up what you need. Even then, if you were working on this with another person, it’d be hard to compare your code and changes.

How Version Control Works

It’s called a VCS because it let’s you control all the versions of what you’re working on. Revision Control or Source Control mean the same thing. A repository is a collection of all the different versions of a project. It includes the the order the changes occurred in, a description of each change, and who was responsible for each change. Each project will have its own.

It wouldn’t make sense to treat unfinished work as a version. The VCS doesn’t know when a change has occurred, you have to tell it, which is called committing.  Versions are often referred to as commits. Doing this manually is messy, and the VCS tries to hide this from you by storing the files in special hidden folders.

To explore your changes, it will give you a set of tools to explore your revision history. Like being able to view and filter the list of commits, or what version is displaying. They also allow you to share your repositories with other to work on things together.

Why Git?

Inventor of Linux made this as well. Linux is a huge project, and Git was designed to help with collaboration on that. Git is a distributed VCS. Some VCS are centralized, meaning that the repository sits on one server. You can’t access it without a network connection, and it can be easily lost if the server is destroyed. For distributed ones, there is no central repository, everyone who works on a project has their own.

Originally Git was going to be a set of tools and commands (plumbing) for you to build your own VCS (porcelain), but eventually it evolved into one itself. It still has the internal tools and commands though, which give you a lot of power.

Github is the most popular site for sharing your repositories.


Getting Started with Git

Working with Git Repositories

Creating and working with repositories is a simple process in git. First, we’ll check to see if git is installed using the –version flag.

Screen Shot 2014-11-03 at 4.17.10 PM

To create a repository, type git, then init, then the name you want to give it. This will give you a success message saying where it’s been created.

Screen Shot 2014-11-03 at 4.18.33 PMScreen Shot 2014-11-03 at 4.20.39 PM

Screen Shot 2014-11-03 at 4.21.42 PM

Looking inside it, there’s nothing there. It’s not just an empty directory though, remember it puts a lot of stuff in hidden files and folders. With -a we can see those, including the .git directory, which will contain all the info on our project eventually.

Let’s say you made a directory with a bunch of files before making the repository.

Screen Shot 2014-11-03 at 4.24.24 PM

Just run git init without giving it a project name. Since you didn’t give it a folder name, it will assume you want a new repository for this folder.

Screen Shot 2014-11-03 at 4.25.52 PM

Note that the name of the repository is not essential, so long as the .git folder exists within it.

Screen Shot 2014-11-03 at 4.28.07 PM

The .git is the only thing that matters, you could actually delete everything else in that folder and still restore your work. To remove the repository, you’d just delete the .git folder.

Screen Shot 2014-11-03 at 4.29.19 PM


Committing Changes

We’ll start by making a repository, going into it, then creating a read me file with nano.

Screen Shot 2014-11-04 at 2.03.44 PM

We’ll then add some text, and save it. We’ve now created a new file in our repository.

Screen Shot 2014-11-04 at 2.05.36 PM

Before we can commit it, we need to add the file to the repository, letting git know the file is important and that its changes should be tracked there. We do this with the git add command. You have to do this manually as there may be some files you don’t want to add or track.

Screen Shot 2014-11-04 at 2.07.10 PM

Next we use the git commit command to commit our changes.

Screen Shot 2014-11-04 at 2.09.05 PM

Lines starting with # are comments. It tells us some info like the committer, what branch we’re on, and what we changed, in this case, we added a new file README. We’ll add our description at the top, which should be short and meaningful. Save and exit nano.

Screen Shot 2014-11-04 at 2.11.29 PM

You get a success message, and info on your name and email. It’s important to know who did what, in case someone needs to get in touch with you. If it’s not listed, it will try to guess based off your username. To change them, we’ll use the —global flag to let them know we want to change this for all of our repositories.

Screen Shot 2014-11-04 at 2.16.09 PM

Now that the file is in the repository, let’s go back and edit it a bit.

Screen Shot 2014-11-04 at 2.17.35 PM

So we’ve made a change, should we commit it? Good rule of thumb: if there is a good commit message you should use, then you should. You should commit when there is good reason to, the more often you do, the better your version history will be. We’ll use git commit again, this time with the -a flag, for all, which means to commit all the changes it can find. The -m stands for message, and let’s us add the commit message from the command line without having to go into nano.

Screen Shot 2014-11-04 at 2.21.14 PM

It’s better to err on committing more often than not.


The Staging Area

The staging area let’s you control what you want to include in the commit. The git status command shows the current version control status of the project. It tells us what branch we’re on, and that there aren’t any changes to commit, as nothing has changed.

Screen Shot 2014-11-04 at 2.25.48 PM

Right now we just have the README, let’s add some more files and rerun git status.

Screen Shot 2014-11-04 at 2.27.55 PM

It tells us we have three untracked files, and you can see it tells us we need to add them to the repository before they can be tracked.

Screen Shot 2014-11-04 at 2.29.11 PM

File1 has been moved to the “changes to be committed” section, which is known as the staging area. If we add the other two files to the repository, they’ll be there as well.

Screen Shot 2014-11-04 at 2.30.35 PM

We can then add them like before.

Screen Shot 2014-11-04 at 2.31.23 PM

Now, we’re back to the original status of nothing to commit.

Screen Shot 2014-11-04 at 2.31.59 PM

Let’s change file1 and 2 with nano. You can see they’re listed under “changes not staged for commit”. Git knows the files are in the repository and it needs to track them, but they’re not in the staging area.

Screen Shot 2014-11-04 at 2.33.48 PM

Let’s just add and commit file1, using the git add and commit commands.

Screen Shot 2014-11-04 at 2.37.00 PM

If we rerun git status, we can see file2 is still there. We can add it the same way.

Screen Shot 2014-11-04 at 2.37.47 PM


Looking Back on what We’ve Done

How do we review the commits we’ve saved to the repository? The git log command shows us a log of all the commits, starting with the most recent. Each entry includes a unique commit identifier, aka a hash. You can see the author and date of the commit as well, and the commit message.

Screen Shot 2014-11-04 at 2.42.36 PM

To see the details of a specific commit, use the git checkout command, which uses the git identifier. It doesn’t need the whole thing, just enough so it knows which one you’re referring to, usually the first 5-6 characters.

Screen Shot 2014-11-04 at 2.48.08 PM

The detached head state warning just lets you know that you’ve pulled up an older version of your code, and if you try to make any changes things could get weird.

If you ls, things will look like they did before, but if you cat file1 and file2 you can see they’re empty here.

Screen Shot 2014-11-04 at 2.49.59 PM

So how do you get back to where we were before, to the present state? Use git checkout, then master.

Screen Shot 2014-11-04 at 2.51.03 PM

The get diff command lets you see what’s changed between two versions of a project. It takes two arguments, the id of the first commit, and the id of the second.

Screen Shot 2014-11-04 at 2.52.35 PM

You can see the only difference is that “This is file2” was added to file2.


Branches

Branches are like alternate realities for your project, they let you pursue different course courses of action for your project in parallel.

Beginning to Branch

Master is the default branch in any git repository, and is usually the canonical version of your project, meaning the one that’s deployed in production. This is optional of course, but is the typical convention.

Screen Shot 2014-11-04 at 3.25.44 PM

To make a new branch, use the git branch command, and give it a name, which should be short and meaningful.

Screen Shot 2014-11-04 at 3.27.54 PM

We made it, but we’re still on the master branch. To switch, use the git checkout command again, which makes sense because a branch is just another version of our code. By default it will take you to the latest commit for that branch, aka the head commit.

Screen Shot 2014-11-04 at 3.29.13 PM

Screen Shot 2014-11-04 at 3.30.11 PM

Let’s change and commit file3 here.

Screen Shot 2014-11-04 at 3.31.39 PM

We can see this commit is at the top of our git log now for this branch.

Screen Shot 2014-11-04 at 3.32.46 PM

If we were to switch back to the master branch with git checkout master, then check its git log, this commit would not be there, only in its branch.

You can create a new branch and switch to it at the same time by adding the -b flag to the git checkout command. Now, while in the foo_feature branch, let’s do this. Since we created it off that branch, and not master, the file3 commit is here as well. When you make a branch, it copies whatever branch you were on at that time.

Screen Shot 2014-11-04 at 3.36.37 PM


Managing Branches

The git branch command will list all the branches, with the one you’re in at the moment starred.

Screen Shot 2014-11-04 at 3.41.31 PM

To delete a branch, use the -D option with the git branch command, followed by the name of the branch. NOTE: You can’t delete a branch you’re currently in.

Screen Shot 2014-11-04 at 3.43.03 PM