Top Most Used Git Commands

Thought process using Git

Starting a new branch and push
1) git checkout -b ‘my-new-branch’
     – new branch because new feature (think of this as putting things in silos)
2) git diff
     – Once I’m done, I look at the diff to look for obvious human / logic errors
3) git add -A
    – stage all changes
4) git commit
    – Write a useful commit message so others know what this commit is about
5) git pull rebase –origin master
     – Rebase to get your changes to the very top. (You’re change can be buried deep down if the company follows continuous deployments and your branch is old. Also this will catch merge conflicts
6) git log
    – Look at the log
7) git push “remote-v” my-new-branch
    – push to your branch. Then you’ll have to merge from Github

Testing a PR locally. 
1) git remote add john ‘ssh clone url’
2) git pull john pr-branch
3) git pull –rebase origin master
 4a) IF merge conflict. Tell commiter about conflict and ask them to fix
 4b) IF rebase goes smoothly. Continue to step 5
5) git checkout master
6) git merge –no-ff pr-branch
7)Add message saying “sign-off: John”

List of Git commands I use as a developer.

git add -A
Stage all un-staged changes

git commit 
Commit all staged files. This will open a editor for you to write a message in
git commit -m  ‘Add new commit message’
Commit all staged files. Add commit message directly on the same line

git remote -v
Display all remote connections
git remote add origin “SSH clone URL”
Add a remote endpoint
git remote remote origin “what”
Remove remote endpoint

git log
displays commit message and history
git log -G /regex/ (Tom C.)
display commit with specified regex
git log -S /search string/ (Tom C.)
display commit with specified string
git log –stat –max-count=10
see last 10 logs

git log –all — path_of_file (Thomas O.)
Displays all commits made to the specific file

E.G –  git log –all — app/views/blogs/index.html.erb
git log –diff-filter=D –summary | grep delete | grep somezing (Thomas O.)
Filter your logs by using grep

git pull –rebase origin master
My top 5 used git command. In a continuous development environment, you’re branch can become outdated easily. This pull’s in the master branch underneath your current branch. Your commit will be on top.

git diff 
Display changes made on the current branch

git status
List modified files
List committed files and uncommitted files

git stash
All changes will be stashed away to it’s pre-change state
git stash –keep-index
All changes that hasn’t been committed will be stashed away.
git stash drop
All stashed changes will be removed
git stash apply
All stashed changes are restored

git whatchanged -p –abbrev-commit –pretty=medium
Combination of git log and git diff. It will show the diff for each commit

git commit -m ‘wip’
wip = work in progress. I use it to mark commits that I’m still actively make changes to. I don’t actually push this to production. I would either rename the commit once it’s done or I’ll rebase.

git rebase –soft HEAD~1
Two things with rebasing. Either squash commits (squish multiple commits to a single commit) or Edit commits messages

git rebase –i ‘sha’
Allows you to squash, edit commit messages but you can specify the ‘sha’

git rebase –abort

When I mess up my rebase (merge conflicts or what have you). This comes in handy to put me back in the original step before rebasing.
git revert ‘sha’
Return branch to the state where sha (commit)
git reflog 
See all steps committed. I personally don’t use this often. Only in crucial times when I’m messing up in git will I have to use this. 

git merge –no-ff pr-576 (Chris A.)
adds the merging commit so others can see thats the following 3 commits are part of 1 commit. I like to `sign off: john moon` so others can see that I added/merged the list of commits.

git reset –hard origin/master (Chris A.)
Resets back to Master. This one’s nice. Creating spikes often leaves a mess of a code on your branch. This helps you go back to zero. 
ssh-add ~/.ssh/id_rsa_private
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

I manage multiple accounts. 1 for work and 1 for personal use. I defaulted my .ssh to my work github. This led to problems with my personal account not having access to push or pull. I had to figure out how to give my personal account permission. I added an account id_rsa_private for my private use. Then every time I encounter that error message, I run this command and everything is groovy. 

ssh-add -K ~/.ssh/id_rsa_private (Chris A.)
Adds key permanently 

Happy Git 
John 

Standard

Using Ruby memoization

In a service oriented architecture we make many requests to external services. These requests time adds up and slows down the site. To improve our performance I can use the memoization technique to make our pages faster.

memoization is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.

When I program I memoize by setting an instance variable to a request.

  1. @foo || = bar.new(params)

This makes a request once, then sets the value to @foo. This persists as long as the instance of the class.

Recently I faced a problem where a method was being called twice. We’ll call it external_request? method. I pass in foo and bar, then check to see if it returns true. The issue was the method was being called twice. The first call returned true, but the second call would return false.


  1. def external_request?(foo, bar)
  2.     @foo = foo
  3.     @bar = bar
  4.     @foo && @bar
  5. end

 Because I care about the first call I knew I could solve this by memoizing the values.

  1. def external_request?(foo, bar)
  2.     @foo ||= foo
  3.     @bar ||= bar
  4.     @foo && @bar
  5. end

This returned true even after the second call, because I saved the value into the instance variable.  Now something to keep in mind. When you are using this technique you want to be careful not to memoize a class variable.

The danger is that this class variable is shared between all users who are on the same instance(unicorn, dyno, etc). Can you see the problem there? If user A makes a request and returns true, then every time the method is called this will return true even if it should be false for other users. This will persist until the unicorn is switched or we refresh the server.

How did I solve the above problem? By making a new method that calls external_request? and sets a cookie during the first method call.

  1. def make_request
  2.   if self.external_request?(foo, bar)
  3.     cookie[:external_request] = 1
  4.   else
  5.     true
  6.   end
  7. end
  8. def self.external_request?(foo, bar)
  9.   foo && bar
  10. end

The lesson is that memoization is great for performance, but we need to be careful what we memoize. In almost every case you don’t want to memoize the class.

This post was inspired by Jon Phillips.

Standard

Refactoring And Building The Next Big Thing

Code refactoring is the process of restructuring existing computer code – changing the factoring – without changing its external behavior


Refactoring is important and necessary, but many times it gets pushed to the backlog. I want to make three point with this post. Why refactoring isn’t taken seriously. When to refactor. And changing refactoring habits. 

As developers, we are paid to build features and fix bugs to increase value for customers. From the project managers point of view, refactoring does neither one of them. So we can say that refactoring is for the developer. This realization gives us insights to why the time allocated to refactor, is so minimally. The PM’s would rather see new feature and bug fixed instead. Code doesn’t get refactored. We keep digging the hole deeper and deeper.


So when should we refactor? If we’re constantly swamped with tickets from our PM we’ll never have time to refactor. The solution? If we’re not given adequate time, we need to refactor in small batches. Tickets should be completed along side small incremental refactoring. This helps us release features reasonably and fix parts of the code. These little batches are now easier to work with and speeds up development time. These refactoring should be within the files we are currently working in. We shouldn’t go out of scope. This will keep us grounded to meet our deadlines.

These are some habits I have learned throughout out the months (1 year in November; Yay!). First following the TDD way (red, green, refactor). As a professional this didn’t fit our team’s agile approach. We refactor but test doesn’t drive our design. Next refactoring in chunks. Asking for time to refactor and going through our codebase to clean up dead code and smelly implementations. To be honest, this doesn’t happen to often. There is little time. So we end up having a larger than necessary codebase with dirty implementations.

I recently began refactoring while creating features and it’s been going great. I’m still not satisfied with the codebase, but I see little win’s over the map. This makes me happy as a developer. 

Credits goes to Ronald Jeffries, 3 founders of the Extreme Programming (XP), for inspiring me to think of refactoring in a different light. His original blog post can be found here: http://xprogramming.com/articles/refactoring-not-on-the-backlog/

Standard

5 Mistakes That Junior Programmers Make

As a young developer, I had the opportunity to make mistakes, some costly and some not so much. And I have no doubt I will continue to have many more opportunities in the future.

Here are my top five rookies mistakes that I’ve made in the past half a year.

  1.  Not being decisive with my code. As a rookie on the team, it’s nerve recking to display your work. It’s similar to practicing violin for hours after hours (8th grade until I graduated high school), but still being afraid to perform in front of the teacher. I try to delay it as long as possible. This was not a good idea. I ended having longer review cycles. The problems in my code would have surfaced sooner, if I reached out to my tech lead sooner. Advice: get a second eye on your code as soon as possible
  2. Working only within the boundary. I tried to fit my code within the models and controllers that are available. Having to work with the Accounts service, I wanted to fit this aspect in the closest javascript file. This led me to the application.js (the all knowing) file. However, talking with other programmers it made sense to create it’s own accounts.js file. I handicapped myself by creating an imaginary boundary line. Advice: talk to another developer and get feedback on your implementation
  3. Git issue. Merging Conflicts. As my first programming job, I wasn’t too familiar using git with in a team. I made awful decisions of pushing without pulling, pushing without running the full test suite, and creating merging conflicts. Those are the worst. Advice: after you commit. Git pull –rebase origin master. Run tests, then push. By rebasing you’re putting your newest commit on top of the latest master. 
  4. Not specifying order of commit. I created two separate pull requests in two different services. I did not specify that PR 1 is contingent to PR 2. Then PR 1 was reviewed first and got merged in. This created issues as the PR 1 tried to make ajax requests that PR 2 was suppose to create. Advice: Always notify in the PR if it needs another PR to be merged in before hand. 
  5. Lack of defensive code. First time Redis user. I didn’t think that Redis would ever go down. Didn’t put in a rescue clause when Redis service goes down. This caused my app to break. Advice: Get in the habit of writing defensive code against potential issues.  

Let me know what mistakes that helped you grow as a developer!
John

Standard

Dead Code Is Dead Code

As a programmer you’re going to come across code that are residue of dead features. You need to figure out what you are going to do with the mess. Are you going to delete it or leave it?

You have several options.

 Door #1. Exterminate dead code. The idea is that you’re not going to use it anytime in the near future and it’s taking up space. So you delete it.

  • Key Benefits
    • Less lines of code, less problems
    • Easier to navigate through your code base. No need to scan through code thinking if it’s in use or not 
    • No dead code laying around
    • IF you wrote tests for these, you’re test suite will be reduced
Door #2. Walking Dead. Let it be in the codebase because it’s not doing anyone harm. The possibility of brining the code back for a different feature
  • Key Benefits
    • This is only true if you know the time line you’re going to reuse the code
    • Saves time implementing the feature as you have a pieces of the feature or all of the feature ready with this old code 
Door #3. Give up. This world is too harsh for you to bear. 
  • Dead

I’m going to make couple assumptions. You use tools like Git, or Mercury. Less lines of code (LOC) makes codebase easier to read. Less time it takes to run the test suite the better. With these assumptions the benefits of door #1 far outweighs those of door 2.

The only benefit door 2 has is if you’re team decided to reuse the code soon.

However, this is also possible in door 1. When you use a subversion tool you’re writing commit messages with your changes to quickly notify others what you did.

git commit -m ‘Removing daily mush feature as it is not being used anywhere in the project. This feature allowed us to deliver coupon to users emails’

Now that you have a good commit message to reference to. In the future if you need to see what that commit did (what methods you deleted), you’ll grep through the logs and find your old commit.

git log --all --grep='daily mush'

Now you’re free of dead code and you’re able to revert back to the original state if it comes down to it.

Leave a comment and let me know what you think!
John

Standard