First we'll just import a project into git and fool around with it a bit. Then we'll play with the linux kernel repository. But before we do either of those we need to get git and install it.Installing git
Distributions don't necessarily have up-to-date versions of git yet, so you need to install it yourself. Thankfully that's fairly easy.
First, download the latest snapshot fromhttp://www.codemonkey.org.uk/projects/git-snapshots/git/Unpack and cd into the git directory, and domake PYTHON_PATH=/usr/bin/python2.4 prefix=/usr/local all doc
sudo make prefix=/usr/local install install-doc
(I need PYTHON_PATH because git wants python 2.4 but /usr/bin/python on my machine is 2.3. You may not need it. The "prefix" arguments are also optional if you're happy with the default of "$HOME/bin".)
If the compile fails, check to see whether it's finding all the libraries and headers it needs. The mostly likely culprits are libcurl and asciidoc, so you may need to install those before getting a successful compile.
To be sure of having the most absolutely brand new version of git, you can then rungit clone git://git.kernel.org/pub/scm/git/git.git git
cd gitand build and install as before. At any time you can update just usinggit pull
and get a quick view of the latest changes to git usinggit whatchangedImporting a new project
First, note that you can get documentation for any git command usingman git-commandname
Assume you already have a tarball myproject.tar.gz with your initial work.tar -xzvf myproject.tar.gz
git init-dbYou've initialized the working directory; now tell git that you want it to track every file (recursively) under the current directory, withgit add .Finally,git commit -a
creates the initial commit that imports all of these new files. It will prompt you for a commit message, then record the current state of all the files to the repository.
Try modifying some files, then rungit diff
To see your modifications so far. When you're happy with the change,git commit -a
will commit it.
To add a new file, first create the file, thengit add path/to/new/file
then commit as usual. No special command is required when removing a file; just remove it, then commit.
At any point you can view the history of your changes usinggit whatchanged
or, to see the history, together with complete diffs at each step,git whatchanged -p
A single git repository can maintain multiple branches of development. To create a new branch named "experimental"git branch experimental
If you now rungit branch
you'll get a list of all existing branches.experimental
The "experimental" branch is the one you just created, and the "master" branch is a default branch that was created for you automatically. The asterisk marks the branch you are currently on; typegit checkout experimental
to switch to the experimental branch. Now edit a file, commit the change, and switch back to the master branch:# edit file
git commit -a
git checkout master
Check that the change you made is no longer visible, since it was made on the experimental branch and you're back on the master branch.
You can make a different change on the master branch:# edit file
git commit -a
at this point the two branches have diverged, with different changes made in each. To merge the changes made in the two branches, rungit pull . experimental
If the changes don't conflict, you're done. If there are conflicts, markers will be left in the problematic files showing the conflict;git diffwill show this. Once you've edited the files to resolve the conflicts,git commit -a
will commit the result of the merge. Finally,gitk
will show a nice graphical representation of the resulting history.
Note that, unlike cvs, git doesn't use a single central repository; instead the repository is being kept inside your current working directory (in the ".git" directory). One way to share changes with someone else is by asking them to do a "git pull". In the example git pull which we used to do the merge above,git pull . experimental
we were asking git to "pull" changes from the branch named "experimental" in the current directory (specified by the period). Instead of the current directory, we could have specified a different directory. Sogit pull /path/to/different/repository experimental
would pull changes from the branch experimental in the git repository at the given path. Orgit pull html://foo.com/pub/repository experimental
would pull changes from a git repo on a website. If the second argument is left out, the default is to pull from the branch named "master". It is also possible to pull via ssh or via a git-specific protocol; see the git-pull man page for details.
Git can also be used in a mode more like CVS, with a central repository that various users push changes to; see the git-push man page and Documentation/cvs-migration.txt in the git source tree.Examining the Linux kernel repository
You can fetch the linux kernel repository withgit clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git linux-2.6
as usual, you can see recent changes with any ofgit whatchanged
git whatchanged -p
You can see the list of available "tags" (which mark release versions) withls .git/refs/tags/
and reset the current working tree to a known version with, for example,git reset --hard v2.6.12
To update your already-existing repository to the latest upstream, just rungit pull
The URL you used on the original clone is stored in .git/remotes/origin, so there's no need to tell git that URL again.
Some good commands to explore next:
- git diff: We saw it this used above to compare the current state of the working tree with the last checked out version. But git diff can be used to compare arbitrary versions from the repository, and can be restricted to consider only certain files; see the man page for details.
- git bisect: When there is a regression in your project, one way to track down the bug is by searching through the history to find the exact commit that's to blame. Git bisect can help you perform a binary search for that commit. It is smart enough to perform a close-to-optimal search even in the case of complex non-linear history with lots of merged branches.
You may also want to look through the Documentation subdirectory of the git source tree for further information.