|This page is part of a series on Guides.
Git is in most distributions' repositories by now. We use Arch Linux, so we type
# pacman -S git
to install it. If you were on Ubuntu or another Debian based distribution, you'd use
# apt-get install git-core
Basic Git Usage
- Starting a new project
You shouldn't need to do this for XOmB, as we have a repo you should be cloning from, but if you were starting a project of your own, you'd do this. It's kept here for completeness' sake.
- Setting up your account:
This makes sure that everything on GitHub gets attributed nicely.
git config --global user.name="githubusername" git config --global user.email="yourgithubemail"
- To check out a copy of the source from GitHub:
With an account:
Go to GitHub, click on the fork button. Then type this:
git clone email@example.com:YOURUSERNAME/xomb.git
Without an account:
git clone git://github.com/xomboverlord/xomb.git
- To add files to the staging area:
To add a file by name:
git add file_name
To add all files you've edited:
git add .
- To see what's been staged and what hasn't:
- To commit all files from the staging area to your repository:
Using your favorite editor to type your commit message:
Adding a message on the command line:
git commit -m "message goes here"
- To commit all files that have changed directly while skipping the staging area:
git commit -a
- To add your local changes to your GitHub account:
- To get the latest and greatest from the XOmB repository:
- To roll back changes that you've made:
git reset --hard
To roll back to two commits ago, you'd do this:
git reset --hard HEAD~2
Note that reset will make you lose those commits...if you want to save them, peel them off into a branch:
git branch branch_name git reset
Now the branch_name branch will contain things as they were before you rolled them back.
More Advanced Use-Cases
- Creating a branch
git branch branch_name
- Listing branches
- Switching to a different branch
git checkout branch_name
- Merging two branches together
Let's use these two branches as an example:
$> git branch * master experimental $>
Let's merge experimental into master:
git merge experimental
Let's say that the official 'master' branch of a project has been developing nicely:
At commit C, you make a branch, and work on it.
A-B-C \ D-E
However, implementing D and E takes some time, and extra work has been done on master in the meantime.
A-B-C-F \ D-E
Now our branch doesn't have these changes from F. So what we need to do is move the base of our branch to the latest changes. We do this with the 'rebase' command. This takes the previous diagram, and turns it into this:
A-B-C-F \ D-E
Which means that now our branch has all of the newest changes. Here's how you do this:
git rebase master
Note: for safety's sake, only use rebase on your private, local branches. If you want to share stuff with others, you'll want to be merging.
- Follow someone else' branches
Let's say that Wilkie wants to follow my experimental branch, as we're collaborating on a new project. He needs to do this:
git branch experimental git checkout experimental git remote add steve git://github.com/steveklabnik/xomb.git git fetch steve
Now he has a branch of mine.
My Git Workflow
Let's assume that I'm just starting to work on XOmB. I've forked the project on my GitHub account, and I've already done the configuration bit I talked about earlier. I'd do something like this:
$> git clone firstname.lastname@example.org:steveklabnik/xomb.git (1) $> cd xomb/src $> git branch experimental (2) $> git checkout experimental (3) $> git branch (4) master * unstable $> git branch awesome-feature (5) $> git checkout awesome-feature (6) $> vim super/awesome/file (7) $> make clean iso (8) $> sudo xm create ~/domu.hvm (9) $> sudo xm destroy XOmB-steve (10) $> git add super/awesome/file (11) $> git status (12) ... tons of stuff ... $> git commit -m "Implemented super awesome feature in super/awesome/file. It's super awesome." (13) $> git checkout unstable (14) $> git merge awesome-feature(15) $> git branch cool-feature (16) ...continue to develop each feature in its own branch, merging back into unstable as needed $> sudo xm create ~/domu.hvm (17) $> sudo xm destroy XOmB-steve ...okay, by now, I've determined that my feature works, and is ready to be included in my master branch $> git checkout master (18) $> git merge experimental (19) $> git push origin master (20)
And then log onto GitHub and click on the 'pull request' button to ask xomboverlord to merge my cool new features back into the main repository.
Some further explanation:
- Clone the original repository from my GitHub to my machine.
- Create a branch named 'experimental'.
- Move into that branch.
- Double check which branch I'm in. I'm not a trusting person.
- Create a branch called 'awesome-feature'.
- Move into that branch.
- Edit the file and add some sweet code.
- Compile up my changes.
- Since I don't make mistakes, my code compiles cleanly, and it's time to test it out!
- My test ran flawlessly, so kill the xen instance.
- Let's add that file to git's staging area
- Examine everything, if it's changed, and if it's staged or not. Make sure I'm committing what I want to be comitting.
- Commit my changes, while adding an eloquent soliloquy as my commit message.
- Switch back into the unstable branch.
- Merge the feature branch into the unstable branch.
- Make another branch called 'cool-feature' for my cool new feature.
- Once all of my features are merged into experimental, I need to test it out!
- Move into the master branch
- Merge experimental branch into the master
- Push the changes I've made to my master branch back to GitHub. I could just do a 'git push' to push the branches, if I wanted those to be publicly available.
Branches are super awesome like this. You can isolate your new features into their own branch, and merge everything together. This ensures that even if you screw things up pretty bad, your master stays stable, your experimental tests how each feature works together, and each branch tests each feature in isolation. And if your feature isn't working out, just kill that branch and start another one over!