Ruby Programming – ODIN Project – 6

odinGit

You should be familiar with the basic Git workflow since you’ve been using it to save your projects along the way. This section will start preparing you for for the more intermediate-level uses of Git.

Step 1: A Deeper Look at Git

Beyond just `$ git add` and `$ git commit`…

Hopefully you’ve been using the basic Git commands to create repositories and push your code up to Github.

Git is a crucial skill to have whether you’re a professional web developer or just a hobbyist who needs to back up your code base. There really aren’t all that many commands for you to learn either.

In this lesson, we’ll dive deeper than just the $ git add . and $ git commit and $ git push commands you’ve mostly been using. This section should help you take the first steps towards expanding your Git toolkit.

The axiom used to be “save early and often” and now it’s “commit early and often”. Hopefully, after you’ve finished this lesson you will feel much more comfortable with the basics and at least know what to Google if you’d like to do more.


Points to Ponder

Look through these now and then use them to test yourself after doing the tasks

  • How do you amend a commit message that you just messed up?
  • How do you view the history of your most recent commits?
  • What are two different uses for $ git checkout?
  • How do you undo a recent commit?
  • What are branches?
  • How do you create a new branch to work on?
  • How do you push that (non-master) branch up to Github?
  • How do you merge the changes from your new branch into the master branch again?
  • Why is working with feature branches useful?
  • What is the difference between using $ git merge and $ git rebase? (hint: history)
  • What is the difference between a “remote” and your local repo?
  • How do you add your Github repo as the remote?

 Tasks:

Note:Subversion (SVN) was the widely used version control system prior to Git (and is still widely used in larger corporations) and that’s why many of the readings below will reference it.

1. Look at 8.1 Git and Other Systems – Git and Subversion (https://git-scm.com/book/en/v1/Git-and-Other-Systems-Git-and-Subversion)

2. Look at Git Basics (http://bedford-computing.co.uk/learning/ruby-on-rails/web-development-101-odin-project-3/)

3. Read Setting up a repository (https://www.atlassian.com/git/tutorials/setting-up-a-repository/)

4. Read Undoing Changes (https://www.atlassian.com/git/tutorials/undoing-changes/)

5. Read Using Branches (https://www.atlassian.com/git/tutorials/using-branches/)

6. Read Rewriting history (https://www.atlassian.com/git/tutorials/rewriting-history/) to understand how Rebasing works. There’s a lot of debate out there about whether it’s best to use a “Merge” or “Rebase” based workflow. We’ll stick with merge because it’s a bit more straightforward and the errors can be a bit easy to get over, but you should be aware of rebasing as an alternative type of flow.

7. Read Syncing – Working with Remote Repositories (https://www.atlassian.com/git/tutorials/syncing/)

8. Read the Pro Git book (https://git-scm.com/book/en/v2) Chapters 2 and 3

Chapter 2: Git Basics

Chapter 3: Git Branching


 Additional Resources


Step 2: Using Git in the Real World

We’ve just scratched the surface, so here’s what to be aware of as you start developing more and more using Git.

Git basics are very simple, but it sometimes feels like a bottomless pit when you find yourself on the wrong side of a confusing error situation. It’s doubly frustrating because you think that messing up or trying the wrong solution can lose data. It’s actually very hard to “lose” data with Git but it can certainly be hiding somewhere you wouldn’t think to look.

You’ll have your share of misadventures, but everyone does. The best remedy is to commit early and often. The smaller and more modular your commits are, the less that can go wrong if you mess one up.

There’s some debate out there about how to properly use Git in your workflow, but I try to think of it this way: Your commit message should fully describe what the commit includes, ie. “add About section to navbar on static pages”. If you need to use a comma or the word “and”, you’ve probably got too much stuff in your commit and should think about keeping your changes more modular and independent.

It can also be tempting to immediately fix bugs in your code or tweak some CSS as soon as you see it. Everyone’s guilty of that. But it’s really best to keep that pen and paper next to you, write down the thing you want to fix, and continue doing what you were doing. Then, when you’ve committed your current feature or merged its feature branch or somehow extricated yourself from the current problem, go back and tackle the things you wanted to touch originally.

Again, it’s all designed to keep your workflow modular and the commits independent so you can easily jump around your Git timeline without messing up too many other things along the way. The first time you need to go back and modify a single monolithic commit, you’ll feel that pain and mend your ways.

The thing about Git is that, unless you’ve got a seriously impressive memory, you can’t just learn it by reading about it – you need to do it.


A Git Workflow For Open Source Contribution

Let’s say you want to contribute to the web application that powers this website (https://github.com/TheOdinProject/theodinproject).

How do you do that? This is a production-ready workflow that is actually used by contributors to this website. We’ll assume here that you do not have write access to the original repository.

The key players in this story will be the upstream (the original Github repository), the origin (your fork of that repo), and the “local” repository (your local clone of origin).  “local” can only pull from upstream, not push.


Initial Setup

1. Fork the original (“upstream”) repository into your own Github account by using the “fork” button at the top of that repo’s page on Github.

2. Clone your forked repository onto your local machine using something like $ git clone git@github.com:your_user_name_here/theodinproject.git (you can get the url from the little widget on the sidebar on the right of that repo’s page on Github)

3. Because you cloned the repository, you’ve already got a remote that points to origin, which is your fork on Github. You will use this to push changes back up to Github. You’ll also want to be able to pull directly from the original repository on Github, which we’ll call upstream, by setting it up as another remote. Do this by using $ git remote add upstream git@github.com:TheOdinProject/theodinproject.git.

4. If this is your first time using git, don’t forget to set your username and email using:

$ git config --global user.name "YOUR NAME"
$ git config --global user.email "YOUR_EMAIL@EXAMPLE.COM"

Ongoing Workflow

We’ve got two main branches master and dev. master is just for production-ready code. Any code deployed to masterwill be tested in staging and shipped to production. You’ll be working in a feature branch and submitting your pull requests to the devbranch. Pretend master doesn’t even exist

1. Create a new feature branch for whatever feature you want to build, using $ git checkout -b your_feature_name.

2. Code, commit, code, commit, code, commit (see a pattern?)

3. When you’re done with your feature, odds are that someone has made changes to the upstream repository in the meantime. That means that your master and dev branches are probably out of date. Fetch the most updated copies of these using $ git fetch upstream.

4. Type $ git branch --all to see a list of all the branches, including the ones that are normally hidden (ie. the remote branches you just grabbed). You should see upstream/master and upstream/dev among them.

5. Now merge the upstream’s changes into your local version of dev using $ git merge. Specifically, you’ll first want to $ git checkout dev to get onto the dev branch and then $ git merge upstream/dev to merge in those upstream changes that we just fetched.

6. Note that a $ git fetch upstream followed by a $ git merge upstream/some_branch is the EXACT same thing as doing a $ git pull upstream/some_branch. I prefer to split it up so I can explicitly walk through the steps.

7. Now that your dev branch is up-to-date, you need to merge it into your feature branch. Yes, that is correct and it seems odd at first. Don’t you want to merge the feature branch into the dev branch instead? Yes, you do, but not yet. Your feature branch is dirty. You don’t know if it has any conflicts which might creep up. Any time you are merging in more “senior” branches (e.g. merging the feature into dev or the dev into master), you want it to be a clean and conflict-free merge. So you first merge the “senior” branch into your dirty branch to resolve those conflicts. So do a $ git checkout your_feature_name to jump back onto your feature branch then a $ git merge dev to merge dev into it.

8. You may have merge conflicts… resolve those with $ git mergetool or just manually open up the files that have conflicts. Basically, merge conflicts will insert markers into your conflicting files to denote what lines are part of the incoming code and which lines are part of your pre-existing code. You’ll need to manually edit those files one-by-one (including removing the merge marker text) and then resave them. Once you’ve finished fixing all the files that have conflicts, you need to commit your changes to finish the merge.


Sending Your Pull Request

1. Now that your feature branch is sorted and you know it’ll merge cleanly into dev, the hard part is all over. Merge into dev with $ git checkout dev$ git merge your_feature_name.

2. Now you want to send your local version of the dev branch back up to your origin (your fork of the upstream repository). You can’t send directly to upstream because you don’t have access, so you’ll need to make a pull request. Use $ git push origin dev to ship dev up to your fork on Github.

3. Finally, submit a pull request to send your forked version of dev back to the original upstream repository’s dev branch. This can be done using Github’s interface. You just need to make sure you’re sending it back to the dev branch and not the master branch.


Points to Ponder

Look through these now and then use them to test yourself after doing the tasks

  • How often should you commit?
  • How large should your commits be?
  • What should your commit messages say?
  • Can you commit unfinished features?
  • Which workflow should you use? (e.g. Merge? Topic Branches? Git-Flow? Rebase?) Hint: There’s no right answer.

 Your Tasks:

1. Read Version Control Best Practices (http://www.git-tower.com/learn/git/ebook/command-line/appendix/best-practices#start)

2. Look at Seth Robertson’s Commit Often, Perfect Later, Publish Once: Git Best Practices (https://sethrobertson.github.io/GitBestPractices/)

3. Read Think Like (a) Git – Git shouldn’t be so hard to learn (http://think-like-a-git.net/)


Additional Resources

https://www.youtube.com/watch?v=ieoHg0Vb-xo&list=PLxNY6twFc_xCxdSPLlxUS4C0VO3sni2DA

Published on 12 October 2012
Lecture 13 – 10/10/2012 – Computer Science 169
Software as a Service

Project: Ruby Final Project

Now would be a good time to refresh your memory on how to play Chess. Building it is actually more fun (and more rewarding)!

Chess is a classic game that appears very complicated at first but can be broken down into logical steps that make it a great Ruby capstone project. If you’ve never played, be sure to read up on the rules (https://en.wikipedia.org/wiki/Chess) first.

The problem specification is deliberately sparse for this, your final project of Ruby. It’s up to you to attack the problem with very little prior information or structure, which is good practice for real world programming challenges. You have all the tools you need. You already did a lot of the heavy thinking in the Knight’s Travails project (http://bedford-computing.co.uk/learning/ruby-on-rails/ruby-programming-odin-project-4/).

The main difference is that this problem has the broadest scope of anything you’ve done yet. The keys here will be thinking it through logically ahead of time and maintaining a disciplined workflow. It’ll be much easier on you if you’re able to stay organized and break it down into components that you can tackle one by one.

This is a great project to have as a part of your portfolio going forward because it shows you can take on something with a lot of different components to it.


 

Your Task

1. Build a command line Chess game where two players can play against each other.

2. The game should be properly constrained. It should prevent players from making illegal moves and declare check or check mate in the correct situations.3. Make it so you can save the board at any time (remember how to serialize?)

4. Write tests for the important parts. You don’t need to TDD it (unless you want to), but be sure to use RSpec tests for anything that you find yourself typing into the command line repeatedly.

5. Do your best to keep your classes modular and clean and your methods doing only one thing each. This is the largest program that you’ve written, so you’ll definitely start to see the benefits of good organization (and testing) when you start running into bugs.

6. Check out the Chess symbols in Unicode (https://en.wikipedia.org/wiki/Chess_symbols_in_Unicode) for a little spice for your game board.

7. (Optional extension) Build a very simple AI computer player (perhaps who does a random legal move)

8. (Optional extension) Look into using sockets to play it over the network with someone else (remember the server project you built earlier?)


 

Additional Resources

  • Look at Ruby Best Practices -Increase Your Productivity – Write Better Code by Gregory Brown. Free download.
  • Look at exercism.io (http://exercism.io/). A site where you can grow and improve your ability to write code by reading others’ code and commenting on it.