====== Version Control With Git ======
Git is a version control system (like SVN and CSV). Among Git's many powerful features, these were most attractive to me:
* Git makes it easy to create branches. The idea is that you have a master branch that's always in a "releasable" state, while you add new features on a separate branch. Once your new feature is finished, you merge the "new feature branch" into the master branch.
* It's very easy to specify which files and directories git should ignore.
* Git has a "bisect" feature which assists you in finding the specific revision where you unknowingly introduced a bug.
Please check this excellent tutorial for a high level introduction to the concepts behind Git: [[http://www.eecs.harvard.edu/~cduan/technical/git/|Understanding Git Conceptually]].
===== Setting Up a Remote Repository =====
Please Note: if you're using github.com as the remote repository server, just create a new repository on their website and follow their instructions.
The following procedure is taken from "[[http://toolmantim.com/articles/setting_up_a_new_remote_git_repository|Setting up a new remote git repository]]".
Set up the new bare repo on the remote server:
$ ssh myserver.com
Welcome to myserver.com!
$ mkdir /var/git/myapp.git && cd /var/git/myapp.git
$ git --bare init
Initialized empty Git repository in /var/git/myapp.git
$ exit
Please note: this assumes that you have a ''git'' user on your remote system who is authorized to log in through ssh. Also: use chmod and chown for the new directory!
On your local system, add the remote repository and push (omit ''git init'' if you already have a local git repository):
$ cd ~/Sites/myapp
$ git init
$ git remote add origin ssh://git@myserver.com/var/git/myapp.git
$ git push origin master
The original tutorial goes on to explain that you can specify the default remote repository by updating the git config file. However, when I checked my config file, it already contained the necessary settings for pushing and pulling to the default remote repository:
[branch "master"]
remote = origin
merge = refs/heads/master
Now you can simply ''git push'' and ''git pull''.
===== GIT Client under Windows (7) =====
To start using the GIT client for Windows you can use the following tutorial:
[[http://nathanj.github.com/gitguide/tour]].
When you get to the step **Pushing to a Remote Server** follow the following instructions:
* Generate a private and public key
* Specify your passphrase
* Export the key using //Conversions// -> //Export OpenSSH key//
* Save the file with the name //id_rsa// at the source location of your ssh. This is usually //C:\Users\[username]\.ssh//
* Save the private key
* Copy the public key to the clipboard. Do not save the public key as it saves in a different format than recognized at github.com
* Add the public key to your account at github.com
Now follow the rest of the instructions as specified in the tutorial.
===== Adding foreign repositories as a plugin =====
You can use the command ''git submodule'' to populate a directory of your own project with a foreign repository.
Use cases:
* Adding a 3rd party Rails plugin to ''vendor/plugins''.
* Importing the Moodle Soda module into your ''mod'' directory.
Here's a tutorial: [[http://woss.name/2008/04/09/using-git-submodules-to-track-plugins/|Using git submodules to track plugins]], which explains everything in great detail. This tutorial is more concise: [[http://chrisjean.com/2009/04/20/git-submodules-adding-using-removing-and-updating/|Git Submodules: Adding, Using, Removing, Updating]].
The short version:
git submodule add git@github.com:solin-repo/soda public_html/local/soda
By default, git will checkout the master branch. If you need a different branch, just move into the submodule's directory and perform a 'normal' checkout:
git checkout moodle19
==== Making changes to a submodule ====
Go ahead, make the changes. Move into the submodule's directory and perform the exact same git commands that you would normally use to commit and push.
==== Cloning a submodule ====
To update your local repository with a remote submodule, do the following in the root of your git repository:
onno@mac-mini:~/php/kompas$ git submodule init
onno@mac-mini:~/php/kompas$ git submodule update
The result:
Initialized empty Git repository in /home/onno/php/kompas/public_html/mod/soda/.git/
remote: Counting objects: 337, done.
remote: Compressing objects: 100% (133/133), done.
remote: Total 337 (delta 238), reused 295 (delta 196)
Receiving objects: 100% (337/337), 259.68 KiB | 58 KiB/s, done.
Resolving deltas: 100% (238/238), done.
Submodule path 'public_html/mod/soda': checked out 'bf7200df78ff0d9a80494e30170ba04d12233e4d'
===== Various =====
==== How do I Make Git Ignore Mode Changes (chmod)? ====
From [[http://stackoverflow.com/questions/1580596/how-do-i-make-git-ignore-mode-changes-chmod|Stack Overflow]]:
git config core.filemode false
From git-config(1):
core.fileMode
If false, the executable bit differences between the index and the
working copy are ignored; useful on broken filesystems like FAT.
See git-update-index(1). True by default.
==== Ignore Things (Files, Dirs) Locally ====
The ''.gitignore'' file is committed to the repository - everybody using the repo is affected by it. If you want to ignore things (files, directories) locally, use: **''.git/info/exclude''**. The ''exclude'' file uses the same directives / instructions as the .gitignore file.
===== Tags: local and remote =====
Adding a tag to a commit allows you to easily find the commit, even after a while. The tag will serve as a name that can be used besides the commit id.
To add a tag to a certain commit, you'll have to find the commit id. You can look them up with the following command:
git log
With the commit id you can create a new (local) tag:
git tag tag_name commit_id
To push the tag to the remote server you can use:
git push --tags
===== Adding Branches Remotely =====
Here's how to push a local branch to remote:
git push --set-upstream origin new-branch
===== Search a Repo Using Git Grep =====
Use ''git grep'' to search a local repository. Example:
git grep 'function get_users'
To limit the search to a subtree, specify the directory outside the commandline options, using a 'pathspec':
git grep 'function get_users' -- 'mod/usermanager'
The '--' signals the end of the commandline arguments. Please **note the space between -- and the pathspec**.
ATTENTION: if you have a git submodule in your repo, git grep will not search this submodule. You have to descend into the submodule first.
===== Ignore files that are already in the repo =====
To stop tracking a file that is currently tracked, use:
git rm --cached $THE_FILE_NAME
(and add the file name in .gitignore or .git/info/exclude).
This will not delete the actual file.