MRC/Tutorials/Sharing your project through git
Creating a software solution together means sharing a project, which in our case means sharing code. We will be using git for this. Git is "a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency":
- version control means that the files and changes you make to them are 'tracked' over time, i.e., their 'history' is stored. You can always go back to previous version, show the difference since a certain point in time, etc.
- distributed means that you don't necessarily need a central server to store your changes. Every team member has the full history available, and can always stored his changes and go back to previous versions, even if he or she is off-line. However, note that we will use a central server every team member stores his or her changes to, and loads the changes others made from.
The first part of the tutorial shows how to initialize a git repository and how to store your local changes to the server. However, imagine that this may soon become a mess if every team member will do so. Therefore, it is advised that only one team member actually runs all the commands in this tutorial, but it is strongly recommended for the others to also take a good look and understand the different steps and commands.
Intializing a git repository
Navigate to your project directory. For this tutorial, we will use '~/emc/my_project', but if you renamed your project in the meantime (which is actually advisable), use that name instead.
Turn the directory into a git repository:
It's that easy! Now let's have a look at the current status of the git repository. Run:
You will see a list of untracked files, e.g., something like this:
Untracked files: (use "git add <file>..." to include in what will be committed) CMakeLists.txt bin/ build/ src/
Untracked means that these files are not under git version control. Note that we only want some of the files to be tracked by git. For example, the bin and build folder are automatically generated by CMake and compilation. We should therefore only add the source files, and the CMakeLists.txt (and possibly other files that you want to share). To make sure git will keep track of these files, use git add:
git add src CMakeLists.txt
Now, run git status again. You should see something like this:
Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: CMakeLists.txt new file: src/example.cpp Untracked files: (use "git add <file>..." to include in what will be committed) bin/ build/
As you can see, you now have some 'changes to be committed'. Committing means we store the added files as they are now. From that point on we can make new modifications, and we can always roll back to this version, see the changes since this version, and, we can share the changes with others. To commit the changes:
git commit -m 'Type a meaningful sentence here'
The part after '-m' is the commit message. It is important that this message is a meaningful message that describes what the added changes are, for example 'fixed this-and-this bug' or 'added this-and-this feature'. That way, you can look in the 'git log' and easily see what was added when, and to which version you need to roll back if you have to.
So, we have commited our changes. Let's see the status using git status. It no longer indicates any changes. That is correct, we just committed them! Now, have a look at the git log:
It outputs an overview of who committed what and when. You should see your name and commit message, and some long code with letters and numbers. This is a commit hash, and can be thought of as a unique id for this commit.
Storing your changes on the server
Alright, you work is now safely stored on your computer. You can make changes, and commit these as well (remember, first use 'git add', then 'git commit'). But you also want to share these changes with your team mates!
- Browse to http://roboticssrv.wtb.tue.nl:8800/
- Log-in using the username and password you received
- Change your password: Profile (upper-right corner) -> Password (tab)
- Create a new project: 'New Project' (+ sign in upper-right corner)
- Set the project name
- Leave visibility level to Private
- Create project
Well remember we created a new project on GitLab. We can now push the local commits to this project. Once we've done that, the commits are also safely stored on the server. So, let's do this!
First, we need to tell git where it has to store the commits. For each repository, we can set a different URL. This URL depends on the name of your project you set earlier in GitLab. If your group number is 1, and the project was called 'my_project', you can set the URL as follows:
git remote add origin http://roboticssrv.wtb.tue.nl:8800/emc01/my_project.git
So, we've told the git repository where it should send the commits to. But we still have to tell git to actually send them there. This is called 'pushing'. The first time you push commits to the server, you have to user this command:
git push -u origin master
and enter your username and password (emc... and the password you received in the email, if you did not change it yet).
We won't go into details here, but the command basically states that the current commits should be send to the origin (of which we set the URL above) and that the git repository should 'keep an eye' on what happens on the server. This means that if one of your teammates also pushes commits to this address, we can 'pull' them to your local repository. This is exactly how the synchronization works. You push your changes, and pull changes that others made.
Now, make a small change to one of the files. Then if you run 'git status', you will see which file was modified. If you type 'git diff' you can see the actual changes. Quite useful, isn't it!
Again, you can commit the change once you've done something useful, but first you need to tell git again which files you want to commit by using 'git add'. Then once you've created the commit, you can push it to the server, this time simply using 'git push'. So, to sum up:
- Make your changes
- Add the files of which you want to commit the changes:
git add ...
- Commit your changes:
git commit -m '... message ...'
- Push your changes to the server:
Up until now, you have seen how you can commit your changes to the server, but it is not very useful if you cannot share your changes with your teammates. Well, sharing is easy in git! Instead of creating there own project, they can get a local copy of the repository you created. This is called 'cloning', and works as follows (change the URL to the correct project url)
git clone http://roboticssrv.wtb.tue.nl:8800/emc01/my_project.git shared_project
This will create a directory called 'shared_project' in which you will find the files that someone else committed. Have a look at the git log, and you see who committed what. Now, this is just a normal git repository to which you can make changes, commit and from which you can push your commits to the server. It is advised that ''one'' person in the group creates a project and corresponding git repository, and that the others clone it. One thing is not yet explained, and that is how you can get the changes that others pushed to the server since you cloned it. Well, it's easy: <pre>git pull
This will 'pull in' the latest commits and your files will be updated accordingly. Note that this won't work if you have modified files, i.e. file changes that you have not yet committed. You don't these changes to be overwritten by a 'pull', so git doesn't allow it. To get the latest changes, you have to commit your changes and try pulling again.
Above tutorial showed how to create a repository in Gitlab, how to push changes to it, and how to pull changes from it. We now suggest the following:
- One person creates a repository as stated above and puts some initial files in it (perhaps you already have some code that you share) and commits the changes
- The others clone this repository
- From now on, you work in this project, and commit all your changes. However, before you start working, make sure to do a 'git pull'