If you do not remember what version control is, or git, please start by reading this and then this. If you want some basic help in installing git, look here.
Du kommer att använda GitHub för att dela och versionshantera all kod som skrivs för kursen. För att undvika situationer som formellt räknas som fusk kommer alla att få ett privat repo att använda i kursen. Följ de här stegen:
Först behöver du ett konto på GitHub. Om du redan har ett kan du hoppa över det här steget. På GitHubs förstasida kan du skapa ett konto genom att fylla i ett (unikt) användarnamn, din epostadress och ett lösenord, och trycka “Sign up for GitHub”:
file:./images/GitHub1.jpg
På nästa sida behöver du inte göra någonting. Klicka bara på “Finish sign up”:
file:./images/GitHub2.jpg
Efter ett litet tag ska du få ett mejl till den epostadress du angav. Klicka på “Verify email address”
file:./images/GitHub3.jpg
Once you have a GitHub account, simply click on the GitHub icon in the AU Portal. This will prompt an authentication song-and-dance with GitHub which ultimately allows us to read your user name from GitHub and attach to your repository.
Så snart du har skickat in dina uppgifter kommer vi att lägga till dig i vår GitHub-organisation. Du kommer då att få ett mejl med en inbjudan:
file:./images/GitHub4.jpg
Om du går till http://www.github.com/ioopm-uu kommer det se ut ungefär så här:
file:./images/GitHub5.jpg
Klicka på ‘View Invitation’ och välj “Join IOOPM-UU”.
file:./images/GitHub6.jpg
Det ska redan finnas ett repo som heter samma sak som ditt student-ID. Du kan söka efter ditt repo på organisationens förstasida. För att klona repot, kör “git clone https://github.com/IOOPM-UU/elias.castegren.1234.git” i en terminal (där “elias.castegren.1234” ersätts med ditt eget namn). Notera “.git” i slutet av adressen! Om du vill kan du ändra namnet på mappen där ditt repo hamnar – det påverkar inte repots namn på GitHub.
Ditt repo kommer att vara synligt för alla i din grupp, så du och den du programmerar med kommer att kunna arbeta i samma repo under tiden ni jobbar tillsammans. När samarbetet är klart kommer den vars repo inte användes vilja kopiera över koden till sitt eget repo så att den finns tillgänglig för nästa sprint också.
If you haven’t used git before on your machine, you need to tell git your user name and email address, which is part of every git commit. Use your real name and student email address:
$ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com
Following this, set up emacs
to be your default editor for
writing commit messages (etc.) like so:
$ git config --global core.editor emacs
If you do not want to use emacs, or skip this step, the system’s default editor will be used, which can vary depending on what OS you are using.
Checking out your repository for the first time will create a directory on your machine with the same name as the repo on GitHub. This directory should hold all your work during this course. All the hand-ins happen through your git repository.
Once you have been added to our GitHub organisation, there should be a GitHub account created for you with your student ID. Check it out like this:
git clone https://github.com/IOOPM-UU/first.last.1234.git ioopm
This creates a directory called ioopm
on your machine where you
will be doing your work. You can name it what you want, but on
these pages we will assume you call it ioopm
.
There will be one or more local copies of your repository (one for each machine where you are working, counting all thin clients as a single machine since they are just mirrors for accessing the same file system), and one remote copy on the GitHub servers.
The idea is to pull changes from the server and integrate them with your local copy, work locally on the local copy, and add a set of edits into a commit that represents some sensible, ideally coherent change to the code (e.g. implement feature X or add test for Y). Commits are pushed to the server so that we can pull them into another local copy, or accidentally destroy the local copy without losing work. When you work with others, multiple people can be pushing commits to the server while you are working on your local copy. To identify key commits, e.g., finishing an assignment, we tag these commits.
If you use version control correctly, most commits will not be tagged, because most commits will be a small improvement, inching towards feature completeness (or whatever the goal).
If you haven’t made a local commit yet, and wish to update GitHub with your local changes, read under Making a Commit first, and then go back here.
If everything is set up correctly, i.e., you have cloned the repository according to the instructions, pushing your local commits to the server is as easy as pie:
$ git push
This should write a message to the terminal saying things went fine. However, in the event that things have changed on the server, your push is going to fail.
In that case, you are going to pull the changes from the server to your local repository and merge those with your changes before you can commit. Note that if someone pushes to the server again in the meantime, you are going to have to pull those changes too, etc.
The section on Downloading Updates from GitHub to Your Local Machine covers how to pull changes from the server.
Note that you can write
$ git push --tags
To push all your tags to the server. Or simply git push origin <tagname>
to push a single tag.
To make a commit, you must first add the files to be committed. Instructions for that is found under Adding Files.
Once you have added the files in your commit, you can go ahead and make the commit. This means taking a snapshot of the current state of the added files. Here is an example of what this might look like:
$ git commit -m "...a good commit message..."
It is a requirement to write a commit message for each commit. If you omit the comment, one of two things will happen: either git will abort with an angry message, or it will fire up an editor in which you can write your message. If you try to write an empty message, it will complain and abort.
The reason for being so anal about the commit message is that it is important. It is quite common to want to look at the history of commits to search for e.g. where some bug might have been introduced. Unless there is a good high-level description, which ideally should be less than 50 characters and on a single line, the history is going to be even harder to navigate.
Here is an example from a git repo. These messages are not particularly good, but vastly superior to no messages or stupidities like “foo” and “changed some files”.
2017-06-04 22:41 Tobias Wrigstad o [development] Added coin flip 2017-06-07 13:03 Kiko M─┐ {origin/development} {origin/HEAD} Merge pull 2017-06-01 16:42 EliasC │ o Add implicit constructor call in main class 2017-05-09 15:10 Karolina Nikamo │ o desugar method calls, default params and fixes 2017-05-02 11:25 Casper Strömberg │ o initial impl. of default params working 2017-05-01 22:03 Lowe Fredriksson │ o pdefault=Nothing in awaitParam to make the com 2017-05-01 20:48 Karolina Nikamo │ o started with default parameters 2017-04-07 12:08 Casper Strömberg │ o Parsing and input default fields to AST 2017-06-02 12:07 EliasC o │ Fix bug when printing non-sugared strings (#81 2017-06-01 00:15 Kiko o─┘ cast print (#811) 2017-05-30 15:01 helanhalvan o Adding Pedestrian simulation stress test (#794)
Here are some opinons about how to write commit messages:
- How to Write a Git Commit Message
- Anatomy of a “Good” commit message
- Useful Tips for writing better Git commit messages
The last link, for example, contains this list of rules:
- Separate subject from body with a blank line
- Limit the subject line to 50 characters
- Capitalize the subject line
- Do not end the subject line with a period
- Use the imperative mood in the subject line
- Wrap the body at 72 characters
- Use the body to explain what and why vs. how
Add files using the git add
command in the terminal:
$ git add list.h list.c
This is often referred to as staging in Git parlance.
To check what files have been changed (or added and not ever
checked in yet), use git status
for a listing. To restrict
yourself to the current directory and subdirs, use git status -s
.
.
Git allows us to tag a commit as a special mark. For example, we might mark a certain commit as Release 4.3.1 so that we can go back to this particular release in the future if needed, e.g., to fix a bug or retrofit a security patch or whatever.
On the course, we are going to use tags to mark finished assignments and also discrete labelled steps in assignment one (for example).
To list all tags for a git repo, simply write git tag
. In the
beginning, you will have no tags.
To tag a commit, a so-called lightweight tag will do fine. To tag
the current commit assignment1_done
, meaning that we can check
it out to get a working assignment 1, simply do the following:
$ git tag assignment1_done
IMPORTANT: Note that, by default, git push
does not transfer tags to remote
servers! Thus, as a final step to tagging your commits, you must
explicitly push tags: git push origin <tagname>
where
<tagname>
is e.g., assignment1_done
, or write git push --tags
followed by a normal git push
to push both tags and normal commits.
If you realise that mistagged something, or you later find a bug so that you want another commit to be the finished assignment one, you must first delete the tag:
git tag -d assignment1_done git push origin :refs/tags/assignment1_done
Then you can go ahead and add the tag to the right commit.
In git parlance we talk about fetching and pulling changes. For simplicity, we are only talking about pulling here, which essentially means fetching and subsequently integrating the changes with your local copy.
When you pull changes from the server, you have two options: merge and rebase. A nice introduction to these can be found here.
Merge looks like this:
$ git pull
It will pull the changes from the server and merge them with your
local changes. If there are conflicting edits that cannot be
resolved automatically, you will have to resolve these manually,
and the resolved changes will eventually be contained in a commit
of its own. Thus, it is likely that if you do git pull
, you will
end up creating an additional commit if things have moved on the
server.
Rebase looks like this:
$ git pull --rebase
When you pull with the --rebase
flag, git will download the
change set and insert it in the commit history before your
commit. Essentially pretending that you made these edits “on top”
of the current state on the server. If all goes well in the merge,
the git history stays a straight line, making it easier to travel
back in time and still have working and sensible code.
There are pros and cons with both ways of integrating changes, but
the way we are going to use git on this course, I would recommend
to always use git pull --rebase
.
git reset HEAD filnamn
- ångrar “add”git checkout filnamn
- motsatsen till “add”. Om du har ändrat i en fil men inte vill spara ändring. Obs! Om du checkout:ar en fil försvinner alla dina ändringar i den filen!git rm filnamn
- ta bort en fil från ett repo (ändringen kommer med i nästa commit)
git checkout -b branchnamn
- skapa branchgit branch
- se alla brancher du har tillgång tillgit branch -r
- se alla brancher, även de du inte har lokaltgit checkout branchnamn
- byt branch till branchnamngit push origin branchnamn
- pusha upp dina commits i den lokala branchen branchnamn till GitHub. Till exempel,git push origin master
för att pusha till master.git pull origin master
- dra ner master från repot online
Om du vill merge:a ändringar i en lokal branch med master efter en pull som ovan:
git checkout origin branchnamn
- ställ dig i branchnamngit merge origin/master
- merga branchnamn med din lokala master
git fetch
- Hämta ändringar från GitHubgit checkout branchnamn
- Efter det här står du i branchnamn
git remote -v
- se vilka repon du är kopplad till
Se till att alltid stå i rätt branch!!!