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.
Installation
- *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
sudo
before 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):
apt
,apt-get
oraptitude
. - macOs:
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. - Fedora:
dnf
. - Android and derivatives: install termux.
It gives you a terminal emulator with access to
apt
,pkg
(anapt
wrapper) 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.
Git commands
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) git command
.
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.,https://
orssh://
);
it is usually in the formhttps://addresss.example.com/path/repo.git
orssh://user@example.com:/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 torepo
(the same string as in the other argument); from now on the commands will assume that you are inside the directory<local>
.add <file>
tell git that it should start tracking (i.e., considering)<file>
and modifications to it. The option-A
can 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 anadd
command before (but possibly when the file was different). If<file>
is omitted, the commit will include all the changes added withadd
since 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.status
Shows the list of changes that would be committed by acommit
command 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.pull
Fetch the repository from the server (supposing you configured one; if you cloned the repository then one was automatically configured) and integrate any changespush
Publish the on the server (supposing you configured one, seepull
). It will fail if someone else has published changes you do not have locally; in that case you will have topull
first.
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).
branch
can 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, calledmaster
.log
show a list of commits, the most recent on top. The output is a list of item looking likecommit 9ef5fc30befccf25d7143c9ad860aab795320e46 Author: Author <email> Date: Mon Nov 16 18:39:01 2020 +0100 commit message
The hexadecimal number aftercommit
is actually an hash and it's unique for that commit. "Commit message" is the one that you provide after-m
when usinggit commit
. Some lines could also look likecommit 9ef5fc30befccf25d7143c9ad860aab795320e46 (HEAD -> master, origin/master)
telling you that it is themaster
branch most recent commit (andorigin/master
as well, but you can ignore that part in the beginning).checkout <commit>
(temporarily) revert all the files to the state they where when<commit>
was recorded.
Be sure to check withgit status
that 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 likemaster
. You can use the latter to return to the state you were before thecheckout
command (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 likefileName_version_201912121102_author1_draftfinal_paragrap3line4unsure.tex
; you just commitfileName.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).stash
discard any changes that are not committed, nor added yet (the red lines ingit status
).branch <newbranch>
orcheckout -b <newbranch> <commit>
Suppose you are working on a file with two functionsf1
andf2
. You are currently rewritingf1
so 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 inf2
: a small typo, but you need to correct it to allow the others to test their code. What will you do?- Finish fixing
f1
first: your team can wait (say) 6 hours until you fix it; - Immediately fix
f2
if you push now, however, your program will crash because of the state off1
; - Save you current changes of
f1
in a file outside the git repository, stash, then fixf2
, commit, push then copy your changes off1
back 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 onf1
. You can do so withgit branch <newbranch>
that creates a new branch, then switch to it withgit checkout <newbranch>
(yes, it's the same command, butcheckout
is 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 usegit 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<newbranch>
),git checkout <oldbranch>
, fixf2
, commit, push,git checkout <newbranch>
and resume working onf1
. The old branch will in most cases bemaster
.- Finish fixing
merge
you now started working with branches, and you finished you changes onf1
. You need to have them together with the fixes onf2
in the master branch. So you can switch to master:git checkout master
, then usegit merge <newbranch>
. If the changes onf1
andf2
happened 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.rebase
do 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.
Git non-commands
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.