Showing posts with label git. Show all posts
Showing posts with label git. Show all posts

Saturday, October 26, 2013

git/github workflow

In the past, I've only used github for personal projects, so I didn't have to deal with collaborating with other folks. Now that I'm working on an open-source project, I'm starting to get more familiar with all the cool features of git and github. So here's the scenario:
  • Project A is on github (aka the original repo).
  • Alice has forked Project A on github and created a branch(/patch) off of that fork. (As a side note, the branch was already sent as a pull request to the original repo, but it hasn't been merged yet.)
  • I have to work on a new feature that is based off of Alice's branch. So should I fork off of Alice's repo or the original repo?
I decided on the latter option. Why? Because I'd like to make sure I keep up-to-date with the original repo, in case there are changes there that aren't being pulled by Alice in her copy of the repo. So here's how I set things up:
  • Went on github and forked Project A so that I had my own personal copy of the original repo.
  • Cloned my copy of the repo onto my machine. By default, cloning creates a remote called origin that points to my copy of Project A on github.
    git clone https://github.com/kpytang/[project-name.git]
    
  • To make sure I keep tabs on the original repo, I add a remote called upstream pointing to the original Project A on github.
    cd [project-name]
    git remote add upstream https://github.com/[project-github-username]/[project-name].git
    
  • Before pulling in Alice's changes, I wanted to make sure my master branch remained as clean as possible, so I created a new branch for the feature I'm working on, and pulled Alice's repo into that branch. To make sure things semantically made sense, I gave the branch a generic name based on the feature I'm responsible for (instead of the specific feature, which I'll use later).
    git branch [generic-feature-name] # creates a new branch
    git checkout [generic-feature-name] # makes it the active branch
    
    Alternatively, the shortcut below does the same thing:
    git checkout -b [generic-feature-name]
    
  • Added Alice's repo as a remote off of the newly created branch. I needed to add her entire repo before I could get to the one branch that I really wanted.
    git remote add [alice] https://github.com/[alice]/[alice-project-name].git
    
  • Grabbed Alice's repo and merged that into my branch (off of the master branch, which is a clean copy of the original project).
    git fetch [alice]
    git merge [alice]/master 
    
  • Grabbed Alice's branch and merged that into the same branch
    git merge [alice]/[branch-name]
    
  • Created a new branch for the specific feature I'm working on. This way when I go to create another feature that's also based Alice's branch, I have an easy starting point to work off of.
    git branch [specific-feature-name]
    git checkout [specific-feature-name]
    
Now I can start working and doing local commits of the new [specific-feature-name] branch and then when I'm ready, I can push my local commits to github. From there I can do a pull request to Alice's branch and she can see what changes I've done. Alternatively, I can also do a pull request to the original repo as well. By separately out the two repos (Alice and the original repo), we can also easily do merges from one or both of those remote repos. Other tips:
  • To pull changes from the original repo later on, make sure you're on the right branch (i.e., the master branch) and pull in upstream changes from the original repo.
    git checkout master # makes "master" the active branch
    git fetch upstream # grabs commits from the original repo
    git merge upstream/master # merges commit from original repo with the master branch
    
  • To merge changes from one branch to another:
    git checkout master # makes "master" the active branch
    git merge [branch] # merges commits from "branch" to the master branch
    
  • To get a list of all your branches:
    git branch
    
  • To delete a branch:
    git branch -d [branch] # deletes the "branch" branch locally
    git push origin :[branch] # deletes the "branch" branch on github (note the ':')
    
  • Push changes to your own github repo doesn't change:
    git checkout master # makes "master" the active branch
    git push origin master # push commits from master branch to your copy of the repo on github
    
  • Merging a pull request locally (useful for when you want to test things out first or when you don't have push permissions for a repo):
    git checkout master # makes "master" the active branch
    git pull https://github.com/[other-user]/repo.git [branchname]
    
    Now you can work on the pull request, make local commits, etc. When you're happy with the merged fix, you can push it back to your own repo:
    git push origin master # push commits from master branch to your copy of the repo on github
    
Refs: https://help.github.com/articles/fork-a-repo
https://github.com/Kunena/Kunena-Forum/wiki/Create-a-new-branch-with-git-and-manage-branches

Thursday, August 29, 2013

bitbucket setup

While I do have a GitHub account, I've decided to give BitBucket a try. The biggest selling point for me is that they have unlimited private repos. I still think GitHub is better for the general open source community, since more developers are on that site so it's one less account they have to create when they are contributing to a particular project. But for tinkering on small, personal projects, it seems like BitBucket is more along the lines of what I'm looking for.

After creating a BitBucket account, I went ahead and setup SSH so that I could use a SSH connection (and avoid the username/password hassle of using HTTPS) to push to my BitBucket repo. BitBucket provides pretty thorough instructions on how to do that here: https://confluence.atlassian.com/display/BITBUCKET/Use+the+SSH+protocol+with+Bitbucket

Getting BitBucket up and running was relatively straightforward. I created an empty repo on the BitBucket site. Then, on the client side, I decided to go with EGit since I was using Eclipse to do my dev work. My version of Eclipse came with EGit installed, so there's no need to install additional software. Looking at this tutorial, I skipped to Section 5 to start configuring Git in Eclipse. Note that, instead of using '/home/username/' I used '/Users/username/' since I was doing this on a Mac. What I like about the EGit interface is the Git Staging Perspective that they have. It makes it super easy to see what hasn't been staged, what's been staged and waiting to be committed, and what's already been committed.

To push the changes to a cloud Git server, just run these commands:
cd /path/to/my/repo
git remote add origin ssh://git@bitbucket.org/username/helloworld.git
git push -u origin --all # pushes up the repo and its refs for the first time
git push -u origin --tags # pushes up any tags

setting up git

Continuing my installation streak, I wanted to setup Git. I find this particularly useful when mucking around with a new coding language. As I'm making my way through what works and what doesn't, it's a tremendous help to know that in case I accidentally get too creative in my coding experiments, I always have something to easily fall back to. Now there are already lots of good discussions (e.g., see here and here) about Git vs other versioning control systems (VCS) (I personally used to use Subversion before switching to Git). As a Mac user, Git was already installed, though it was an older version (v. 1.7.12). Since I use Macports to do nearly all of my installs, I use these commands to update everything:
sudo port selfupdate         # updates macports
sudo port outdated           # lists which ports have a newer version
sudo port upgrade outdated   # upgrades the ports to the newer versions
Macports is usually smart about building/installing any dependencies first, but sometimes you run into errors. Also, there are a few ports that take a long time to build, so be patient! During my install, I encountered an error building arpack:
 --->  Computing dependencies for arpack 
--->  Configuring arpack 
Error: org.macports.configure for port arpack returned: configure failure: 
command execution failed 
Please see the log file for port arpack for details: 
/opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_ports_math_arpack/arpack/main.log
To solve this, I first ran this:
 sudo port clean arpack 
 sudo port install arpack +openmpi -gcc45 -gcc47 
...and then continued running sudo port upgrade outdated

Note that others (http://mac-os-forge.2317878.n4.nabble.com/MacPorts-39476-arpack-s-openmpi-variant-conflicts-with-gcc45-td220687.html) have cited that they still encountered errors when building arpack. If that's the case, then try: sudo port install arpack -accelerate +atlas instead.
To check that the version was updated, run:
 git --version