What follows often sacrifices precision and proper definitions to give a more intuitive description for first time users: refer to the documentation of the relevant tool for more precise information.
- *Nix: the best (in my opinion) way is the command line, as you can just type (it depends on your system, but you probably need to write
sudobefore it, or execute it as root):
<PackageManager> install git
You may need to refresh the package list first, refer to your package manager documentation to learn how to do this.
<PackageManager>is the command to invoke your package manager; some examples follow:
- Debian and derivatives (including Ubuntu):
brew. You may need to install Homebrew first. As I do not use macOs you should refer to someone who does (or online guides) for instructions on how to install Homebrew.
- Android and derivatives: install termux.
It gives you a terminal emulator with access to
aptwrapper) and possibly other similar commands. You can even install (among other things) python, texlive (a LaTeX distribution) and a C/C++ compiler. You will install packages as a regular user, not root, with termux.
- If you are using a different unix-like system you probably already know how to invoke your package manager.
- Debian and derivatives (including Ubuntu):
- Windows: install cygwin, that gives you a unix-like environment (then check the instructions above), or check the windows installer. As I do not use windows, I did not actually try either of these.
Optional: Creating a repository on a shared server
The structure that git uses to track a project is called "repository".
Unless you want to email your git repository every time you make a change, you should create a repository on a server that all the people working on your project can access.
The Institut für mathematik offers its own git server, where you can create a private repository, only shared with specific persons, or a public one, available to everybody; if you are only interested in a public repository you may also use some alternatives not related to the university (e.g., github or gitlab). Usually after you have created a repository on the web interface, there is a widget displaying the command you should use to clone the repository (see below)
Note that in theory you could host your git repository in your home computer, laptop, or phone. However this would make it difficult to access it for anybody else, and even your other devices if they are not sharing the same internet connection (i.e., if they are in different local networks).
Working with git
Git is a powerful but complex tool, therefore you should familiarize yourself with the “essential” commands, and gradually start using the more advanced ones later.
It can help you manage your project more efficiently, and synchronize your changes with other people working on it. The biggest difference with respect to most others synchronization tools is that synchronization does not happen automatically; you always have to tell git which modifications you want to publish instead (this happens because git can do much more than just synchronization).
The following will assume you are using git from the command line. If you are using a different tool, there are probably equivalents for each of these commands, you should consult the documentation of your tool. Most git servers provide a web interface; it is however very limited: you will only be able to perform some very basic tasks using it.
Here I list some commands that I find useful, and their explanation; you actually cannot (almost) work with git without some of them.
I will assume in the following that you are using the command line (terminal emulator);
when I describe the command
command you should call it as (i.e., type on the terminal)
clone <repository> <local>creates a copy of the repository on your machine.
<repository>is the address of the repository you want to copy, including the transport protocol (e.g.,
it is usually in the form
ssh://firstname.lastname@example.org:/path/repo.git, where the part ".git" can usually be omitted; also, some servers require "user" to be "git".
<local>) is optional; if it is given, it must be the name of a directory that does not exist yet, or is empty. If it is not given, it defaults to
repo(the same string as in the other argument); from now on the commands will assume that you are inside the directory
add <file>tell git that it should start tracking (i.e., considering)
<file>and modifications to it. The option
-Acan be used instead of
<file>to tell git to start tracking all the files in the directory.
commit <file> -m <comment>record a new "entry" in the history of the repository, including the current version of
<file>, which must have been added with an
addcommand before (but possibly when the file was different). If
<file>is omitted, the commit will include all the changes added with
addsince the last commit.
<comment>is mandatory and is a string describing the changes. If it is missing, git will try to open an editor (usually the environment variable
$EDITOR), where you can enter it.
statusShows the list of changes that would be committed by a
commitcommand with no arguments, the list of files that were modified/created/deleted since the last commit and whether push (and in some cases pull) will do anything.
pullFetch the repository from the server (supposing you configured one; if you cloned the repository then one was automatically configured) and integrate any changes
pushPublish the on the server (supposing you configured one, see
pull). It will fail if someone else has published changes you do not have locally; in that case you will have to
Other git commands
With the commands above you can make git work as a synchronization service, like dropbox or nextcloud, just more difficult to use. Some commands follow that start to use some git specific functionality (git can actually do much more, only some basic commands are explained here).
branchcan actually do multiple things; if called without any other argument, well tell you the list of local branches, and signal with an asterisk the current one. Unless you already used this command on the same repository there will probably only be one, called
logshow a list of commits, the most recent on top. The output is a list of item looking like
commit 9ef5fc30befccf25d7143c9ad860aab795320e46 Author: Author <email> Date: Mon Nov 16 18:39:01 2020 +0100 commit messageThe hexadecimal number after
commitis actually an hash and it's unique for that commit. "Commit message" is the one that you provide after
git commit. Some lines could also look like
commit 9ef5fc30befccf25d7143c9ad860aab795320e46 (HEAD -> master, origin/master)telling you that it is the
masterbranch most recent commit (and
origin/masteras well, but you can ignore that part in the beginning).
checkout <commit>(temporarily) revert all the files to the state they where when
Be sure to check with
git statusthat there are no uncommitted changes before issuing this command! If there are, in the best case the command will fail and do nothing, in the worst case you won't notice, the git objects will be messed up and you will be stuck in a “broken” state!
<commit>is either the hexadecimal commit identifier, or a name like
master. You can use the latter to return to the state you were before the
checkoutcommand (assuming that was your current branch). This is probably the most important feature of git: it eliminates the need for a lot of backup files named like
fileName_version_201912121102_author1_draftfinal_paragrap3line4unsure.tex; you just commit
fileName.tex, the date and author will be recorded by git, you can put the rest in the commit message (which will also be much more readable).
stashdiscard any changes that are not committed, nor added yet (the red lines in
checkout -b <newbranch> <commit>Suppose you are working on a file with two functions
f2. You are currently rewriting
f1so that it works better, but you are not finished, if you run your program now it will crash. And one of your group mates just spotted a bug in
f2: a small typo, but you need to correct it to allow the others to test their code. What will you do?
- Finish fixing
f1first: your team can wait (say) 6 hours until you fix it;
- Immediately fix
f2if you push now, however, your program will crash because of the state of
- Save you current changes of
f1in a file outside the git repository, stash, then fix
f2, commit, push then copy your changes of
f1back in the file inside the repository, an finish working on it.
Actually, if you are in the situation above it's too late (not really, but things will be very complicated). What you can do, is switch to a new branch before you start working on
f1. You can do so with
git branch <newbranch>that creates a new branch, then switch to it with
git checkout <newbranch>(yes, it's the same command, but
checkoutis also used to tell git to record your new commits in another branch). If you need to start a new branch from a previous commit you can use
git checkout -b <newbranch> <commit>, which also has the side effect of immediately switching to the new branch. If the situation above occurs, you can commit (in
git checkout <oldbranch>, fix
f2, commit, push,
git checkout <newbranch>and resume working on
f1. The old branch will in most cases be
- Finish fixing
mergeyou now started working with branches, and you finished you changes on
f1. You need to have them together with the fixes on
f2in the master branch. So you can switch to master:
git checkout master, then use
git merge <newbranch>. If the changes on
f2happened in well separated parts of the file, the merge process will succeed and all you have to do is writing a message for the commit recording the merge. If, however, you modified the same line in both the old and new branch, git will not be able to tell which commit should take precedence, and you will have to fix the “conflicts” manually. This can be VERY difficult, so avoid being in that situation for now.
Technically, a merge happens every time you commit your changes, and then you have to pull before you can push because someone else has modified he repository. For the same reasons as before, the merge can fail at this point.
rebasedo not use it! If you use git it is very difficult to lose your work, even if you delete some files; the easiest ways of losing work are: not committing (if you write a function, and the delete it before committing, as far as git is concerned that function never existed), using checkout or merge with uncommitted changes, and rebase. Besides, rebase can also create problems when to the other people working on that repository. It is a useful command, but don't use it unless you are very very sure you understand git well and you know what you are doing.
What I describe here are not git commands, but things/suggestions that are related to git.
.gitignore is a file that contains a list of files git should ignore.
It should list files that are likely to be generated by tools used to work on that project, not files that you want to place there but do not belong to the project (as the file is also part of the repository and will be synchronized with everybody).
A good examples for a python project includes
*.pyc, meaning that git should ignore all pythons compiled files.
The example above works because
* can be substituted with any string (it is called a “wildcard”), and if such a file exists, git will detect and ignore it.
Another good example is the list of files generated by pdflatex if you have LaTeX sources in your project.
Someone took care of compiling a list of example ignore files for various languages, and store it... on a git repository, of course.
Take care that you never have two people working on the same file at the same time, otherwise git may be unable to integrate the changes (see the merge command for more information). Until you learn how to fix this problem, of course.