My instructor script for steps 1-9 of the software carpentry git lesson with some additions.
- Pre-checks
- Motivational Scenarios
- Check that we have git in the shell
- Getting help
- Registering with git
- Setting up a proxy
- Creating a repository
- First commit
- More commits
- Directories
- Changing a commit message
- Exploring history
- Ignoring files
- Tagging
- Collaborating
- Branching
- Finishing off
- Miscellaneous items
Make sure that:
- Your
~/.gitconfig
file has been temporarily moved. - People can be paired up for the collaborative working.
Can motivate the use of a revision control system:
- Development encompassing multiple systems.
- Collaborative development.
- Keeping provenance (if you have a student working/researching for you)
- Good skill for them to learn.
- Keeps provenance (if they do good comments)
Just to check that git
is installed in the local machine.
$ git --version
You can get help from git
by just typing it at the command line.
$ git
by itself returns most common commands. Same as:
$ git help
You get an extended list of commands by doing:
$ git help --all
Want to know more about a command you can do:
$ git help add
which is the same as:
$ git add --help
Git will complain if you do not set:
$ git config --global user.name "Mario Antonioletti"
$ git config --global user.email "mario@epcc.ed.ac.uk"
Can also set:
$ git config --global color.ui "auto"
$ git config --global core.editor "nano -w"
You can see what configuration parameters you have set by doing:
$ git config -l
Putting entries into:
$ ls ~/.gitconfig
You may have to create a proxy if your organisation does not allow you to directly go into the internet:
$ git config --global http.proxy proxy-url
$ git config --global https.proxy proxy-url
to unset:
$ git config --global --unset http.proxy
$ git config --global --unset https.proxy
Let's create a repository:
$ mkdir paper
$ cd paper
Check what is there:
$ ls -A
Initialise the repository:
$ git init
Check to see what has changed:
$ ls -A
Check the status of the repository.
$ git status
Edit a file (use an editor you are familiar with):
$ nano README.md
Could add:
# My Paper
Check the state:
$ ls
Check the file contents:
$ cat README.md
and what is the repository status?
$ git status
Workflow
working directory --> staging area --> git repository
^ |
| |
+-------------------------------------+
Add the file to the staging area:
$ git add README.md
Let's check the status:
$ git status
Suppose you made a mistake and you want to unstage:
$ git rm --cached README.md
Check:
$ git status
$ git commit -m"Starting my paper."
[master (root-commit) 18e86a7] Starting my paper.
1 file changed, 2 insertions(+)
create mode 100644 README.md
Check the status again:
$ git status
If you do not specify the "-m" flag it will fire an editor for you.
$ git log
Can have a shortened version of the commit log
$ git log --oneline
Modify the text file:
## Section 1
This discusses the ...
Check the contents:
$ cat README.md
and the status:
$ git status
Suppose you can't remember what you changed, you can do:
$ git diff
If we add the file to the staging area:
$ git add README.md
If you do:
$ git diff
You can not see the difference because the file has been staged. However, you can do:
$ git diff --staged
Make more changes to show that there is a difference between what is committed comes from the staging area and not the working copy.
Cannot add directories by themselves:
mkdir imgs
git status
git add imgs
git status
you need to add a file - you can create a temporary file:
cd imgs
touch .gitkeep
ls
ls -a
git add .
git commit -m"Added directory for images."
Can get rid of the temporary files later.
If you commit with a typo you can change:
$ git commit --amend -m "New message."
Can do a diff with earlier versions:
git log --oneline
pick as specific revision and do:
git diff RevNum README.md
Can short hand this by:
git diff HEAD~N README.md
where the N
signifies how many revisions back you want to go
and HEAD
points to the current version of the repository.
If you want the specific contents of a file at given revision you can do:
git show RevNum README.md
You make modifications to a file that you no longer want to keep:
$ git checkout -- README.md
Or you can even checkout earlier versions of the code:
$ git checkout RevNum -- README.md
If you want to recover the state of the repository you can go back
to HEAD
by doing:
$ git reset --hard HEAD
You have seen that git status
is a really useful command to
show you what has been changed. However if you have files that
you do not want to put in the repository such as emacs back up
files, binary files, etc you can tell git to ignore these by
creating a .gitignore
file. You can create this file and
add content that will apply recursively:
*~
.\#*
\~*
bin/
add and commit this file and you will reduce the clutter you get.
$ git add .gitignore
$ git commit -m".gitignore: files to ignore."
git will not let you commit files that are contained in the .gitignore
file.
Can put a human readable version. Lightweight tag:
$ git tag v0.1
$ git tag # Lists available tags
$ git show v0.1 # gives you information about the commit
We can do some more edits and do an annotated tag:
$ git tag -a v1.0 -m"First release."
$ git show v1.0
Use lightweight tags for your own use and annotated tags for the benefit of others.
You should have set up a bit bucket account - we use bit bucket because it provides private repositories by default but there are several others you can use:
We shall:
- Go to http://github.com.
- Login (if you have not created an account you will have to sign up).
- Click on the
+
and chooseNew repository
. - Choose a name for your repository
paper
. - Use
…or push an existing repository from the command line
. - Follow the instructions there.
- Click on
Overview
on the left hand menu and you should see your file together with the commits. - click on source and you should be able to browse your sources.
Now we going to do something drastic:
rm -fr paper
We shall take a copy of the remote repository:
git clone https://github.com/marioa/paper.git Person1
If you go into the repository you should see that all your history is there:
cd paper
git log --oneline
Now want you to pair up.
- One of you will open up your repository to the other.
- Person 1 click on the
Settings->Collaborators
button. - Type in their collaborators GitHub username.
- Person 2 should get an email and see Person 1's repository on their dashboard.
- Person 2 should clone the repository.
Note you can clone giving the repository a name:
git clone https://github.com/marioa/paper.git Person2
Now person 2 will change the README.md
file and then add and commit:
$ git add README.md
$ git commit -m"README.md: updated the contents."
But this change has only registered in the local repository. We need to push it to the remote repository:
$ git push
Now person 1, in order to see these changes will have to pull the changes, in order to register these in their repository:
$ git pull
and the changes should be merged. Now person 1 and 2 add a line to the mars file.
## Conclusions
Try to make sure that the fruit is different and you are in the same location. Then:
$ git add README.md
$ git commit -m"README.md: added conclusions section."
Person 1:
$ git push
Person 2:
$ git push
This will fail because person 1 has pushed their data before you did. You
have to do a git pull
before you can push:
$ git pull
But now you find you have a conflict - you have both tried to edit the same line and git
does not know how to resolve the problem. You will have to edit the file, resolve the conflict (talk to the other person!!):
$ git add
$ git commit -m"README.md: resolved the conflict."
$ git push
Person 1 should be able to pull the file and together you can enter into a happy collaboration.
Branching allows a very powerful way of forking your code. Suppose you want to instrument it for performance analysis or you are collaborating and you do not want to be modifying the same code at the same time. Unlike CVS and SVN branches are really cheap and uncomplicated.
Can use to:
- Explore/deveop a new feature
- Stop developers clashing on development
- Create a particular branch, a version of a release
Let's write a bit of Python code to demonstrate hello.py
:
print("Hello World!")
Run the code python hello.py
. Now suppose you want to instrument the
code (put in timing calls). You do not want to do this in your master
branch:
$ git branch # list the branches available, only master $ git branch profile # Creates the new branch $ git checkout profile # Change to the new branch
Now change the code:
import time
start = time.time()
print("Hello World!)
end = time.time()
print("Code took ",(end - start)," seconds)
Execute the code. Add, commit. Go back to the master branch. Change the original code.
print("Hello World!")
print("I am a real programer now!")
Execute, add, commit.
$ git checkout profile
$ cat `hello.py` # Execute
$ git log --oneline # Check local changes
$ git log --oneline master # Check changes on the master branch
$ git merge master # Incorporate changes from the maser branch
Make a change on the Hello World
line. Execute, add, commit. Change
back to the master branch. Change the same line, execute, add and commit.
Go back to the profile branch and try to do a merge
which should result
in a conflict. Show how to resolve the conflict.
To push the branch to the remote repository:
git push origin profile
We want to clone the Edinburgh bootcamp content. This is on GitHub. We did not start using GitHub because they do not offer free
private accounts by default. GitHub have a slightly different approach to doing
things - you fork
code which is a clone at the server end.
- Go to https://github.com/hpcarcher/2014-12-03-edinburgh
- You have a choice:
- Fork the repository and then clone.
- Clone the repository as is (but you will have no write access).
Ideal way of doing this it to create (or use if you already have one) an ssh public/private key and register your public key with the remote repository.
Can also do
git config credential.helper store
which will store the credentials in plain text at ~/.git-credentials
(not very secure).
On a mac you can do:
git config --global credential.helper osxkeychain
and on Linux you can do:
git config credential.helper cache
which stores the password in memory.
Sometimes the GIT_ASKPASS
gets a password to be asked via a fancy window prompt that does not appear (e.g.
terminal may not support X).
This work is licensed under a Creative Commons Attribution 4.0 International License.