Version Control with Ben Morgan

advertisement
Version Control with
Ben Morgan
Developer
Workflow
Log what we did:
“Add foo support”
Edit Sources
Add Files
Compile and Test
Logbook
=======
1. Initial version
Logbook
=======
1. Initial version
2. Remove ‘using’
directive, use ‘std’
Logbook
=======
1. Initial version
2. Remove ‘using’
directive, use ‘std’
3. Output command line
arguments to stdout
Logging via a text file?
«database»
Repository
«commit»
Working Copy
Files
State
Files
Changes
+- main.cc
+- README.txt
1
2->2.1
3
|
4
|
5 2.2
6<--|
7
+- main.cc
+- README.txt
«update»
Version Control Systems
Managing change and logs
Centralized Version Control
My Working Copy
Files
State
Central Repository
Examples
Your Working Copy
Files
State
Subversion
CVS
Perforce
Distributed Version Control
My Working Copy
Files
Files
State
Repo
Repo
State
Your Working Copy
“Central” Repository
Examples
Git
Mercurial
Bazaar
A Version Control Walkthrough with Git
• We haven’t actually written anything yet, and this is the perfect time to get
pp6calculator under version control so you can use it through the whole
course. We’ll be using git as our version control system, with github.com
acting as our central repository. Why not SVN? It’s slightly more awkward to
get this set up and using github.com allows all of you to see how a central
repository works.
• Aims of the walkthough:
• Create a local repository, add files, commit changes and make tags
• Show diffs and logs for the commits we’ve made
• Create a central repo on GitHub, push our local changes to the new central
repository
Tools you’ll need
1: Project Organization
First of all, we want to create a suitable directory structure to hold our project. Open a terminal
session and check that you’re in the HOME directory and cd to it if not. For this project, we need
a two level directory structure, the reason for which will become apparent next week.
We simply create directories mpagspp6/pp6calculator.git under HOME and cd into the
bottom level directory:
Notes
If you want to keep the
mpagspp6 directory
somewhere other than in
HOME, that’s fine.
Directories holding git
repositories are often
named with a .git
extension. This is not
required, but is helpful in
noting the directory as a
repository!
2: Creating the Repository
As pp6calculator.git is our working copy, and git is a distributed version control system, we
create the repository in our working copy. Git makes this very easy, and all we need to do is run
the simple command (in the pp6calculator.git directory!):
$ git init
Notes
All that init does is create
the .git directory in the
directory where it’s run.
You can use ls to explore
the contents of this
directory, which is where git
stores all you changes. For
more details on the
contents, see the O’Reilly
text “Version Control with
Git” or git-scm.com
3: Getting Help
Ask us! If we’re not around though, then man git will provide plenty of useful information. Like
Subversion, git also provides a fast command line help interface, so you can also just type
$ git help
Notes
As the output of git help
notes, to get help on a
specific command, simply
append its name to git
help. It will open a man
style page for the command
(simply use ‘q’ to exit this).
Of course, also refer to text
books and online resources
such as git-scm.com.
4: Viewing Repository Status
As we add and edit files, it’s useful to keep track of the repository status without changing
anything. With git, simply use the status command to view the current repository status:
$ git status
Notes
Of course at the moment,
there’s not much to report
as we just have an empty
repository.
Get into the habit of running
git status regularly to
see what you’ve changed.
5: Adding a README file
We’re going to start our project by adding a README for pp6calculator. This is a file that sits in
the top level of the project and provides some basic information about what the project is, plus
other information like installation instructions, authors and copyright/license details.
Our README will be in plain text, using Markdown formatting. We use Markdown because it is
human readable but easily convertible to other formats.
Open your favourite text editor and begin to write your README, saving it as README.md
Tips
The example on the left
shows the most basic
README structure, but you
can change it as you wish.
We’ll be adding to it later!
Underlines using ‘=’ are
major sections, and those
with ‘-’ are subsections.
When we upload our project
to github, we’ll see how
these are displayed.
6: Adding the README.md File
Having saved README.md, if you run git status again, you can see that git recognises a new file
exists. To add this to the repository, and make hit track it in the future we use git’s add command
and then the status command to see the changes
$ git add README.md
Notes
“staged” files
- Ready to be commited
“unstaged” files
- Changed but not staged
“untracked” files
- Not tracked by git yet
“deleted” files
- Deleted by git and ready
for removal
No color? See later!
7: Committing
You’ll have noticed that when you ran git status after adding README.md it only says
“Changes to be committed”. Git stages changes before committing them to the repository. To
store the changes we use the commit command with a message describing the changes:
$ git commit -m “Add skeleton README.md”
Notes
The staging area is a place
to queue up (or remove)
changes before they are
committed. This is useful
when we start to deal with
multiple files.
A “commit” is a snapshot of
the repository.
After the commit, status
shows WC and repo in sync
8: Making Changes
Now we’ve staged and committed README.md, we can make some further changes. So edit
your README.md, for example, add an empty section “Installation”. Save the file and run git
status again. You’ll see that git recognises we’ve made changes, but these are not yet staged.
To actually update the repository, we run git add again to stage the change then git
commit to update the repository. This cycle of staging and committing is the basic git workflow.
Try This
Make a few more edits to
README.md and use git
add and git commit for
each to get into the feel of
staging and committing.
Remember to use git
status regularly to see
what’s happening!
9: Unstaging Changes
So you’ve staged a change, and then you realise it either breaks something or you want to add
something else. As you may have noticed, git status actually tells you what to do in this case,
so make a change, stage it up and then use reset to unstage it:
$ git reset HEAD README.md
Notes
If you have a change staged
and simply want to add to
it, simply use git add.
That works even if for
changes to the same file.
10: Viewing Logs
We’ve now made a few commits to our repository, so how do we go back and see what we’ve
done and why? Just use the log command!
$ git log
Notes
Plain log displays
everything! To get the N
most recent commits, use
git log -nN.
You can also use git log
--summary to get a more
detailed overview, though it
doesn’t show much as
we’ve only worked with one
file.
11: Viewing Changes
The basic log command shows the timeline of changes, but not what changed. To see what
actually changed between commits, we can use git log -p or the diff command. Without
any arguments, it shows a diff between the last commit and any local changes:
$ git diff
Notes
Git shows difference using
the standard diff format for
additions/removals. On the
left, additions are in green,
removals in red.
Depending on the default
configuration, the diff may
be output to a pager, in
which case use ‘q’ to quit.
No color? See later!
12: Changes between Commits
As you’ll have seen in using git log, git labels commits using a 40 character hash code (cf
subversion’s revision numbers). You can use these labels to view differences between any two
commits, though because hashes are unique, you don’t have to type out 80 characters!
$ git diff a567 40a2
Hints
The commit specifier needs
to contain enough
characters to uniquely
identify the commit.
The arguments to git diff
can take a variety of forms.
See man gitrevisions
for more details, or the more
helpful Git SCM Book! Try
some of these out.
13: Writing Good Commit Messages
Our edits so far have been simple and confined to one file. In these cases, a single line commit
message using git commit -m “commit message” is completely sufficient (e.g. “Fixed
typographic errors”). As we start to make more involved commits involving several files, then we
need to provide more detail. Because of the way git works with patches and email, it tends to
recommend the specific style of commit message listed below.
Why?
There’s a good example in
the text on the left (taken
from a post by Tim Pope).
If you “fixed a bug” you
should say which bug, and
how it was fixed. You might
also say (and include in the
commit) that a test has
been added to check for
the bug in the future.
14: Configuring Git
To write more involved messages, we clearly don’t want to type them out on the command line!
Thankfully git is aware of modern editors, so we just need to make it aware of the one we want
to use. The config command allows us to do this, as well as configure color output and so
on
$ git config --global <key> <value>
Hints
Git can use the EDITOR
environment variable rather
than core.editor
You can configure git
options globally (-global) or locally in a
repository (--local)
Also see the Git SCM Book
and try out some options!
15: Getting Started on Github
Our repository is completely isolated at present, so if you want to work with it later on another
machine, you need some way of sharing it. Whilst git is completely distributed, we can create a
repository to be an authoritative one. We’ll use the GitHub hosting service to do this, so if you do
not have an account already, sign up for one now using the link below.
Notes
Similar hosting services
exist for other VCS, so this
is not unique to git.
16: Creating a Repository
Use the create new repo tool (highlighted below), naming it as you wish and creating a useful
description. Make sure it’s public (otherwise you have to pay!) and that the Initialize this
repository with a README is unticked and that no .gitignore or license file is
selected. We’ll add and see what these are for in a bit. When you’re happy, click the Create
Repository button.
Notes
BE CAREFUL: DON’T
create the repository with a
README! That will conflict
with the README in your
repository!
We don’t create a .gitignore
file for the same reason. If
we create it, then our github
repo has an initial commit,
and can get confused with
that in our local repo.
16: Creating a Repository
Use the create new repo tool (highlighted below), naming it as you wish and creating a useful
description. Make sure it’s public (otherwise you have to pay!) and that the Initialize this
repository with a README is unticked and that no .gitignore file is selected. We’ll
add and see what this is for in a bit. When you’re happy, click the Create Repository button.
Notes
All being well, you should
see the screen on the left,
but we need to take a little
detour before we can
connect the repository
we’ve been working with to
our freshly created github
repository.
17: Github and SSH Keys
Whilst your repository is public, this only means others can browse your repository, but not push
to it. In fact at this point, neither can you! The best way to connect to git is via ssh, and to do
this we need to create an ssh keypair and make github aware of this.
Github provide a very useful help system which walks you through the steps needed to do this,
and this is linked below. It benefits from a little adaption, which is described in the notes.
Step A
Whilst github recommend
https, ssh is actually a bit
easier to setup, and likely to
be more familiar.
As you may already have
some keys present, you can
skip straight to Step 4 on
the github page
17: Github and SSH Keys
Whilst your repository is public, this only means others can browse your repository, but not push
to it. In fact at this point, neither can you! The best way to connect to git is via ssh, and to do
this we need to create an ssh keypair and make github aware of this.
Github provide a very useful help system which walks you through the steps needed to do this,
and this is linked below. It benefits from a little adaption, which is described in the notes.
Step B
Step 3 can be followed as
is, but, it’s useful to create a
unique key for github.
To do this, use the -f
argument to ssh-keygen
with the filename you want,
or change the output file
interactively.
17: Github and SSH Keys
Whilst your repository is public, this only means others can browse your repository, but not push
to it. In fact at this point, neither can you! The best way to connect to git is via ssh, and to do
this we need to create an ssh keypair and make github aware of this.
Final Note: You will need to create a keypair on each machine you connect from, so Warwick
users will need to repeat these steps back home!
Step C
Steps 4 and 5 should be
followed as is. If you have
issues with connecting, you
can edit the ~/.ssh/config file
and add the stanza
Host github.com
User git
Hostname github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/github_rsa
if github_rsa is your
private key
18: Pushing your Repository to Github
Will ssh keys set up, we can return to the repository creation page. Github has actually provided
instructions on how to push our local repository to Github: “Push and existing repository from
the command line”. We go through the two steps needed in the next couple of slides
Notes
Of course, if we were
starting from scratch again,
it would be easier to create
the repository on Github
first!
We’ve done the
walkthrough this way to
show that you can use git
without github!
18: Pushing your Repository to Github
First of all we use remote to add our github repository as a remote our our local one. Of course,
use the correct details after the git@github.com: to point to your repository!
$ git remote add origin git@github.com:<>
Notes
Use ‘-v’ to list remotes.
You can add as many
remotes as you want. For
example, you could add
one of your colleagues
repositories, whether local
or on github. That would
allow you to share changes
and updates.
Of course, sufficient
permissions are needed!
18: Pushing your Repository to Github
With a remote added, we simply push our changes to the ‘origin’ using the push command.
If your github repository was created with a README.md, then you should pull (see next slide!!)
before doing the following push:
$ git push -u origin master
Notes
You must have a clean local
repository first! So before
you add the remote, commit
any local changes first.
Note that the commands on
the left do everything in one
step. If you’ve already
added the remote, you
don’t need to do it again.
‘master’ is roughly
equivalent to ‘trunk’ in SVN.
18a: Fixing Errors when Pushing to Github
If you accidentally created your github repo with a README file, you will see an error along the
lines of “error: failed to push some refs to ...”. This is due to the remote and local repository not
being in sync. To resolve this, we need to pull upstream changes, resolve conflicts, then push
back to github. (git pull origin master, fix conflicts, git add, git commit, git push origin master)
Notes
In general, git will try to be
helpful when problems arise
by outputting hints on how
to resolve issues.
Even if you find these
confusing, plugging the
error message into Google
or StackOverflow will
provide helpful answers.
19: Pulling Remote Changes
For today, we’ll be only working with our local repository and pushing to github. If changes have
happened upstream on the github (or other remote), we can update our local repository with this
changes using the pull command
$ git pull origin master
Notes
The pull command takes
the remote to pull from and
the “refspec” of changes.
Updates in git can also be
done in two steps using the
fetch and merge
commands. These are good
for cherry picking changes.
pull will be important in
coming weeks!
20: Viewing your Github Repository
Github provides a nice web interface for viewing your repository, the files in it and the history of
changes. Of course, the command line is usually the core way of interacting with your local and
remote repositories, the web based viewer and other GUI tools are very helpful.
Of course, similar tools exist for other version control systems!
Notes
Now we can see the
advantage of writing our
README in Markdown Github has rendered it
nicely for us! There’s plenty
more you can do with
Markdown,
21: The .gitignore File
When you run git status, git will report any files it doesn’t track (“untracked”). In some cases
we’ll have files that we don’t want git to track, for example files generated by the build or text
editor temporaries, but we may accidentally add them to the repository (e.g. by git add .).
To make git ignore these, we’ll add a file named .gitignore in our repository. This contains a list of
filename patterns that git should ignore, so open your text editor and write:
Notes
You can also have a global
ignores file. You could have
a file named
.global_gitignores in
your HOME directory. Git can
be made aware of this file
by setting the
core.excludesfile
variable to point to it in the
global git config
21: The .gitignore File
Just like any other file, .gitignore should be tracked by the repository, so add it, commit and
push to the origin:
Notes
Once you’ve pushed to the
origin, refresh the webview
of the repository on github.
You should see the file
added! If there are extra
patterns you want to ignore,
simply treat .gitignore
like any other file.
For more information, see
man gitignore
22: Tagging
We’ve seen that in git, commits are described by a 40 character hash. At certain points in
development, we’ll want to mark a commit as a usable, stable piece of work. The hashes aren’t
an easy way of marking these points, so instead we create a “tag”. Current tags are listed via:
$ git tag
Notes
Tags can have any name,
but git convention is
‘vMAJOR.MINOR.PATCH’
for version numbers.
“Annotated” tags are the
best to use to begin with, as
they can take extra info
about the tag.
Use show to see this info.
22: Tagging
Like any other repository entry, tags can be pushed to a remote repository. However, push does
not push tags by default. To do this, we have to either specify the tag name or use the --tags
argument:
$ git push origin v0.1.0
Notes
You should always push
tags so they appear when
others pull from your remote
repo (including you!).
If you look on your github
repository, you should see a
‘1’ next to the “Tags”.
Clicking on this will take you
an interface where you can
download a source archive
for you code at the tag!
23: And we’re done
That about covers the basic usage of git and github. All of the techniques are applicable to other
VCSs you may work with, of particular importance being the writing of good commit
messages so you (and your collaborators) know not only what changes were done, but why!
As we move through the course, remember to stage and commit your files regularly when you
have got something working (you should never commit code that doesn’t work for you!). Use
tags at the end of each day to record your work at those points, again, the tag should work!
Don’t Forget Resources
The Following Slides Describe
how to Work With your Repository
Outside of Birmingham!
I: Cloning Your Repository
If you want to work with your repository outside of the Birmingham Workstations, e.g. at
Warwick, or on a laptop, then you can simply clone it from github. You will first need to set up
ssh keys just as we did earlier and upload the public key to github. The use clone:
$ git clone <repo> <dir>
Notes
If you see any problems
here, check your local ssh
settings and the public keys
on github. You can make
changes in your cloned
repo without needing a
network connection pushing them to github
later.
II: Homework and Future Weeks...
Outside of the course, you can work with your repository as you wish. Birmingham people may
just work locally, pushing their changes up to github. Warwick people, or anybody using a laptop
can take a clone of your github repository, work on the clone and then push changes up to
github. In any case, before next week, make sure you have pushed all your changes to github.
Then to begin work again, simply pull the changes into your repository at Birmingham!
Homework
Whilst the homeworks will
concentrate on coding,
remember to keep your
README file up to date,
and make regular commits
and pushes.
When your homework on
pp6calculator is complete,
make a tag so we have a
reference we can access!
Download