====== 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.