= Git Distributed Version Control = [[TOC]] Git is a distributed version control system currently maintained by Junio C. Hamano. You can find valuable information * at the official [http://git-scm.com/ Git homepage] * in the [http://git-scm.com/book Git Book] * in the comprehensive [http://git-scm.com/docs Git Reference Manual] = General Git Workflow = For in-depth information on how to use various aspects of Git, please consult the excellent [http://git-scm.com/book Git book] and the comprehensive [http://git-scm.com/docs manual]. The very first thing you should do, is to setup your personal information as this is associated with all the commits you are about to produce. So simply add this with: {{{ $ git config --global user.name "Your Name Here" $ git config --global user.email "Your E-Mail Here" }}} To checkout a project, there are two options depending on the overall accessibility of the projects' repository. If the project is ''publicly'' available, you can checkout ''anonymously'' with {{{ $ git checkout http://ufo.kit.edu/git/repo-path }}} if the project is ''private'' you need to have your public SSH key be associated with the repository. If this is the case, you can checkout a project via SSH with {{{ $ git checkout git@ufo.kit.edu:repo-path }}} == Pulling remote changes == Now, you have the complete projects' history and can start to build the project or develop contributions. In any case, you want to regularly keep up with the changes made by others, so if you haven't touched the code, you can simply pull in changes with {{{ $ git pull }}} == Commit changes locally == To record changes, you need to ''stage'' the change by adding the affected files with {{{ $ git add FILE [FILE ...] }}} and ''commit'' the staged changes with {{{ $ git commit }}} Note that this two-step process easily allows you to organize your commits in a logical way by staging only relevant changes. If you are sure that all changes are relevant to a certain commit you can by-pass this and simply call {{{ $ git commit -a }}} In any case you will be presented with an editor to insert a summary line and a detailed commit message. == Branches == Branching with Git is cheap and should be used at all times. The main branch is called ''master'' and should be left untouched for most of the time. To branch off of it, simply type {{{ $ git branch new-branch-name }}} and change to the new branch with {{{ $ git checkout new-branch-name }}} You can now develop independently of the main branch that you should synchronize regularly as shown above. If you want to merge the changes in your branch either use {{{ $ git merge master }}} to pull in changes and intermingle them with yours. If you want to have your changes always be together, you can replay the changes ''on top'' of the master branch with {{{ $ git rebase master }}} however, you should ''never'' publish a branch that has been rebased, otherwise people pulling from you will get in trouble. == Push changes remotely == Depending on the access rights to the repository you can push your changes back to the server with {{{ $ git push }}} However, in some cases you won't have write rights to the master branch. You have several options here. First you can generate patches with {{{ $ git format-patch master..new-branch-name }}} and send them to the maintainer. You can also put your changes on a server that is accessible to the maintainer and tell him the location. He can setup a remote branch and merge the changes himself. If you have an associated public key and the maintainer asked to have personal branches, you can push your changes with {{{ $ git push origin new-branch-name:/dev/user-name/new-branch-name }}} The branch name in front of the colon is your ''local'' branch name, the one after is the ''remote'' branch name containing the path where you can store changes. If you want to delete the remote branch, you push an empty branch to the same location {{{ $ git push origin :/dev/user-name/new-branch-name }}} === Push changes to a /user branch === Some repositories allow users to push to designated branches with a certain prefix. For example `ufo-core`, `ufo-filters` and `libuca` have a special `/user` prefix to which approved people and only those can push. To do so, simply checkout a new local branch (or use master but make sure to remove the tracking remote) and push {{{ $ git checkout -b my-feature $ git push -u origin my-feature:/user/my-name/feature }}} The `-u` sets up automatic tracking, which means you can push and pull without specifying the remote and the remote branch. = Creating a New Repository = The Trac is now fully integrated with Git and you can register user-repositories on your own, like it was always possible with bzr. * You need to provide public ssh key which will be used to access both git and bzr repositories. * Then, just register git remote using ssh protocol. * To simplify navigation, it is better to employ two-level directory hierarchy. In most case, the first level is just your Trac user name. Example: {{{ $ git remote add origin ssh://ufo.kit.edu/user/repo $ git push origin master }}} The same way, you may access the published repositories: {{{ $ git clone ssh://ufo.kit.edu/csa/pcitool }}} For public read-only access, use: {{{ $ git clone http://ufo.kit.edu/sources/git/csa/pcitool }}} The major projects have to be added as before. If you have a project that you want to have version controlled with Git open a new ticket with the Infrastructure component and add the following information: * Repository name (very short) * Repository description * Maintainer * Should people from outside be able to see it on http://ufo.kit.edu/repos? * Should other developers be able to push to personal branches? * Public keys and user names for all people that you want to have * write rights to master * read rights * write/read rights to certain branches When the repository has been created and your project is already version controlled with Git locally, just register the repository URL as the new origin {{{ $ git remote add origin git@ufo.kit.edu:repo-name $ git push }}} otherwise create a local Git repository {{{ $ git init . }}} and commit all files {{{ $ git add $ git commit }}} and register the repository URL. = Best Practices and Tips = == Commit Message == Never, ever exceed the 50-character limit of the commit message summary in the first line! If you keep it short and concise, browsing through the logs becomes much more easier. More detailed information about the commit can and should be presented in the commit messages' body that has a 80-character-per-line limitation. In any case, you should setup your editor to respect these limitations. == Aliases == Aliases save you ''a lot'' of time if used properly. See for example [http://robots.thoughtbot.com/post/4747482956/streamline-your-git-workflow-with-aliases this] blog entry.