= Git Users = [[TOC(Developer/GitUsers, depth=2)]] TODO: Managing a (private/public) git mirror, using github, accessing developer repos, submitting pull requests... = Browse the GIT Repository Online = You can browse all available repositories online by accessing http://git.rtems.org/. = Using the GIT Repository = The following examples demonstrate how to use the RTEMS' git repos. These examples are provided for the main rtems module, but they are also valid for the other modules. First we need to obtain our own local copy of the RTEMS git repository: {{{ git clone git://git.rtems.org/rtems.git rtems }}} This command will create a folder named rtems in the current directory. This folder will contain a full featured rtems' git repository and the current HEAD revision checked out. Since all the history is available we can checkout any release of RTEMS. Major RTEMS releases are available as separate branches in the repo. To see all available remote branches issue the following command: {{{ git branch -r }}} We can checkout one of those remote branches (e.g. rtems-4.10 branch) using the command: {{{ git checkout -b rtems410 origin/4.10 }}} This will create a local branch named "rtems410", containing the rtems-4.10 release, that will track the remote branch "rtems-4-10-branch" in origin (git://git.rtems.org/rtems.git). The 'git branch' command prints a list of the current local branches, indicating the one currently checked out. If you want to switch between local branches: {{{ git checkout }}} With time your local repository will diverge from the main RTEMS repository. To keep your local copy up to date you need to issue: {{{ git pull origin }}} This command will update all your local branches with any new code revisions available on the central repository. = Making Changes = Git allows you to make changes in the RTEMS source tree and track those changes locally. First you need to clone the repository: {{{ git clone git://git.rtems.org/rtems.git rtems }}} Or if you already cloned it before, then you might want to update to the latest version before making your changes: {{{ cd rtems git pull }}} Next make your changes to files. If you add, delete or move/rename files you need to inform Git {{{ git add /some/new/file git rm /some/old/file git mv /some/old/file /some/new/file }}} When you're satisfied with the changes you made, commit them (locally) {{{ git commit -a }}} The -a flag commits all the changes that were made, but you can also control which changes to commit by individually adding files as you modify them by using. You can also specify other options to commit, such as a message with the -m flag. {{{ git add /some/changed/files git commit }}} But you shouldn't do any of this on the branch that you cloned, instead you should create a new branch to work with, so that the cloned branch (master) is a pristine copy of the upstream RTEMS repository. = Working with Branches = Branches facilitate trying out new code and creating patches. Previous release of RTEMS are available through remote branches. To check out a remote branch, first query the Git repository for the list of branches: {{{ git branch -r }}} Then checkout the desired remote branch, for example: {{{ git checkout -b rtems410 origin/4.10 }}} Or if you have previously checked out the remote branch then you should see it in your local branches: {{{ git branch }}} You can change to an existing local branch easily: {{{ git checkout rtems410 }}} You can also create a new branch and switch to it: {{{ git branch temporary git checkout temporary }}} Or more concisely: {{{ git checkout -b temporary }}} If you forget which branch you are on {{{ git branch }}} shows you by placing a * next to the current one. When a branch is no longer useful you can delete it. {{{ git checkout master git branch -d temporary }}} If you have unmerged changes in the old branch git complains and you need to use -D instead of -d. = Viewing Changes = To view all changes since the last commit: {{{ git diff HEAD }}} To view all changes between the current branch and another branch, say master: {{{ git diff master..HEAD }}} To view descriptions of committed changes: {{{ git log }}} Or view the changeset for some file (or directory): {{{ git log /some/file }}} To view the changesets made between two branches: {{{ git log master..HEAD }}} Or for a more brief description use shortlog: {{{ git shortlog master..HEAD }}} = Reverting Changes = To remove all (uncommitted) changes on a branch {{{ git checkout -f }}} Or to selectively revert (uncommited) files, for example if you accidentally deleted ./some/file {{{ git checkout -- ./some/file }}} or {{{ git checkout HEAD ./some/file }}} To remove commits there are two useful options, reset and revert. git reset should only be used on local branches that no one else is accessing remotely. git revert is cleaner, and is the right way to revert changes that have already been pushed/pulled remotely. = git reset = git reset is a powerful and tricky command that should only be used on local (un-pushed) branches): A good description of what it enables to do can be found [http://progit.org/2011/07/11/reset.html here]. The following are a few useful examples. Note that adding a ~ after HEAD refers to the most recent commit, and you can add a number after the ~ to refer to commits even further back; HEAD by itself refers to the current working directory (changes since last commit). {{{ git reset HEAD~ }}} Will undo the last commit and unstage those changes. Your working directory will remain the same, therefore a "git status" will yield any changes you made plus the changes made in your last commit. This can be used to fix the last commit. You will need to add the files again. {{{ git reset --soft HEAD~ }}} Will just undo the last commit. The changes from last commit will still be staged (just as if you finished git adding them). This can be used to amend the last commit (e.g. I forgot to add a file to the last commit). {{{ git reset --hard HEAD~ }}} Will revert everything, including the working directory, to the previous commit. This is dangerous and can lead to you losing all your changes; the --hard flag ignores errors. {{{ git reset HEAD }}} Will unstage any change. This is used to revert a wrong git add. (e.g. I added a file that shouldn't be there, but I haven't 'committed') {{{ git reset --hard HEAD }}} Will revert your working directory to a HEAD state. You will lose any change you made to files after the last commit. This is used when you just want to destroy all changes you made since the last commit. = git revert = git revert does the same as reset but creates a new commit with the reverted changes instead of modifying the local repository directly. {{{ git revert HEAD }}} This will create a new commit which undoes the change in HEAD. You will be given a chance to edit the commit message for the new commit. = Merging Changes = Suppose you commit changes in two different branches, branch1 and branch2, and want to create a new branch containing both sets of changes: {{{ git checkout -b merged git merge branch1 git merge branch2 }}} Or you might want to bring the changes in one branch into the other: {{{ git checkout branch1 git merge branch2 }}} And now that branch2 is merged you might get rid of it: {{{ git branch -d branch2 }}} If you have done work on a branch, say branch1, and have gone out-of-sync with the remote repository, you can pull the changes from the remote repo and then merge them into your branch: {{{ git checkout master git pull git checkout branch1 git merge master }}} If all goes well the new commits you pulled into your master branch will be merged into your branch1, which will now be up-to-date. However, if branch1 has not been pushed remotely then rebasing might be a good alternative to merging because the merge generates a commit = Rebasing = An alternative to the merge command is rebase, which replays the changes (commits) on one branch onto another. git rebase finds the common ancestor of the two branches, stores each commit of the branch you’re on to temporary files, and applies each commit in order. For example {{{ git checkout branch1 git rebase master }}} or more concisely {{{ git rebase master branch1 }}} will bring the changes of master into branch1, and then you can fast-forward master to include branch1 quite easily {{{ git checkout master git merge branch1 }}} Rebasing makes a cleaner history than merging; the log of a rebased branch looks like a linear history as if the work was done serially rather than in parallel. A primary reason to rebase is to ensure commits apply cleanly on a remote branch, e.g. when submitting patches to RTEMS that you create by working on a branch in a personal repository. Using rebase to merge your work with the remote branch eliminates most integration work for the committer/maintainer. There is one caveat to using rebase: Do not rebase commits that you have pushed to a public repository. Rebase abandons existing commits and creates new ones that are similar but different. If you push commits that others pull down, and then you rewrite those commits with git rebase and push them up again, the others will have to re-merge their work and trying to integrate their work into yours can become messy. = Accessing a developer's repository = RTEMS developers with Git commit access have personal repositories on http://git.rtems.org/ that can be [wiki:Git_Committers#Pull_a_Developer's_Repo pulled] to view cutting edge development work shared there. = Creating a Patch = Before submitting a patch read about [wiki:Developer/Contributing Contributing] to RTEMS. The recommended way to create a patch is to branch the [wiki:Git git repository] master and use one commit for each logical change. Then you can use ''git-format-patch'' to turn your commits into patches and easily submit them. {{{ git format-patch master }}} Creates a separate patch for each commit that has been made between the master branch and the current branch and writes them in the current directory. Use the -o flag to redirect the files to a different directory. Patches created using ''git-format-patch'' are formatted so they can be emailed and rely on having git configured with your name and email address, for example {{{ git config --global user.name "Your Name" git config --global user.email name@domain.com }}} = Submitting a Patch = Using ''git-send-email'' you can easily [wiki:Developer/Contributing contribute] your patches. You will need to install ''git-send-email'' first: {{{ yum install git-email }}} or {{{ apt-get install git-send-email }}} Then you will need to configure an SMTP server. You could install one on your localhost, or you can connect to a mail server such as gmail. = Configuring git-send-email to use GMail = Configure git to use gmail: {{{ git config --global sendemail.smtpserver smtp.gmail.com git config --global sendemail.smtpserverport 587 git config --global sendemail.smtpencryption tls git config --global sendemail.smtpuser your_email@gmail.com }}} It will ask for your password each time you use ''git-send-email''. Optionally you can also put it in your git config: {{{ git config --global sendemail.smtppass your_password }}} = Sending Email = To send your patches just {{{ git send-email /path/to/patch --to rtems-devel@rtems.org }}} To send multiple related patches (if you have more than one commit in your branch) specify a path to a directory containing all of the patches created by ''git-format-patch''. ''git-send-email'' has some useful options such as: * --annotate to show/edit your patch * --cover-letter to prepend a summary * --cc=
to cc someone You can configure the to address: {{{ git config --global sendemail.to rtems-devel@rtems.org }}} So all you need is: {{{ git send-email /path/to/patch }}} = Troubleshooting = Some restrictive corporate firewalls block access through the git protocol (git://) If you are unable to reach the server git://git.rtems.org/ you can try accessing through http. To clone the rtems repository using the http protocol use the following command: {{{ git clone http://git.rtems.org/rtems/ rtems }}} This access through http is slower (way slower!) than through the git protocol therefore the git protocol is preferred. = Learn more about Git = Links to site with good Git information. * http://gitready.com/ - an excellent resource from beginner to very advanced. * http://progit.org/book/ - Covers git basics and some advanced features. Includes some useful workflow examples. * http://gitref.org/ - Fast and simple reference for the most used git commands.