Git Miscellany

Please open notebook rsepython-s1r9.ipynb

Git Stash

If you find you want to pull, but you’re not ready to commit, you can use git stash.

import os
top_dir = os.getcwd()
git_dir = os.path.join(top_dir, 'learning_git')
working_dir=os.path.join(git_dir, 'git_example')
os.chdir(working_dir)
%%writefile Wales.md
Mountains In Wales
==================

* Pen y Fan
* Tryfan
* Snowdon
* Glyder Fawr
* Fan y Big
* Cadair Idris

Overwriting Wales.md

We can now “stash” our changes:

%%bash
git stash
git pull

Saved working directory and index state WIP on master: 2919c37 Commit Aonach onto master branch

HEAD is now at 2919c37 Commit Aonach onto master branch

Already up-to-date.

When we are ready, we can apply our chnages:

%%bash
git stash apply

On branch master

Your branch is ahead of ‘origin/master’ by 1 commit.

Changes not staged for commit:

modified: Wales.md

Untracked files:

wsd.py

wsd.pyc

no changes added to commit

The “Stash” is a way of temporarily saving your working area, and can help out in a pinch.

Tagging

Tags are easy to read labels for revisions, and can be used anywhere we would name a commit.

Produce real results only with tagged revisions:

%%bash
git tag -a v1.0 -m "Release 1.0"
git push --tags

To git@github.com:UCL/github-example.git

! [rejected] v1.0 -> v1.0 (already exists)

error: failed to push some refs to ‘git@github.com:UCL/github-example.git’

hint: Updates were rejected because the tag already exists in the remote.

We add commits to existing versions:

%%writefile Pennines.md

Mountains In the Pennines
========================

* Cross Fell

Writing Pennines.md

%%bash
git add Pennines.md
git commit -am "Add Pennines"

[master 2219ad0] Add Pennines

2 files changed, 7 insertions(+), 1 deletion(-)

create mode 100644 Pennines.md

%%bash
git log v1.0.. --graph --oneline

* 2219ad0 Add Pennines

If .. is used without a following commit name, HEAD is assumed.

Working with generated files: gitignore

We often end up with files that are generated by our program. It is bad practice to keep these in Git; just keep the sources.

Examples include .o and .x files for compiled languages, .pyc files in Python.

In our example, we might want to make our .md files into a PDF with pandoc.

To do this we will need a Makefile:

%%writefile Makefile

MDS=$(wildcard *.md)
PDFS=$(MDS:.md=.pdf)

default: $(PDFS)

%.pdf: %.md
	pandoc $< -o $@

Writing Makefile

Once this is created, we can then use make to generate the pdf files:

%%bash
make

pandoc Pennines.md -o Pennines.pdf

pandoc Scotland.md -o Scotland.pdf

pandoc Wales.md -o Wales.pdf

pandoc index.md -o index.pdf

pandoc lakeland.md -o lakeland.pdf

We now have a bunch of output .pdf files corresponding to each Markdown file.

But we don’t want those to show up in git:

%%bash
git status

On branch master

Your branch is ahead of ‘origin/master’ by 2 commits.

Untracked files:

Makefile

Pennines.pdf

Scotland.pdf

Wales.pdf

index.pdf

lakeland.pdf

wsd.py

wsd.pyc nothing added to commit but untracked files present

Use .gitignore files to tell Git not to pay attention to files with certain paths:

%%writefile .gitignore
*.pdf

Writing .gitignore

%%bash
git status

On branch master

Your branch is ahead of ‘origin/master’ by 2 commits.

Untracked files:

.gitignore

Makefile

wsd.py

wsd.pyc

nothing added to commit but untracked files present

Now that the pdf files will be ignored, we can commit the Makefile and .gitignore to our repository:

%%bash
git add Makefile
git add .gitignore
git commit -am "Add a makefile and ignore generated files"
git push

[master 3a03c1c] Add a makefile and ignore generated files

2 files changed, 9 insertions(+)

create mode 100644 .gitignore

create mode 100644 Makefile

To git@github.com:UCL/github-example.git

5f73fff..3a03c1c master -> master

Git clean

If we wanted to remove files from our local repository we can use:

%%bash
git clean -fX

Removing Pennines.pdf

Removing Scotland.pdf

Removing Wales.pdf

Removing index.pdf

Removing lakeland.pdf

%%bash
ls

Makefile

Pennines.md

Scotland.md

Wales.md

index.md

lakeland.md

wsd.py

wsd.pyc

In this example the pdf files have been removed, this is because they were identified in the .gitignore file and the -X option was used.

Git Hunks

A “Hunk” is one git change. This changeset has three hunks:

+import matplotlib
+import numpy as np

 from matplotlib import pylab
 from matplotlib.backends.backend_pdf import PdfPages

+def increment_or_add(key,hash,weight=1):
+       if key not in hash:
+               hash[key]=0
+       hash[key]+=weight
+
 data_path=os.path.join(os.path.dirname(
                        os.path.abspath(__file__)),
-regenerate=False
+regenerate=True

Interactive add

git add and git reset can be used to stage/unstage a whole file, but you can use interactive mode to stage by hunk, choosing yes or no for each hunk.

git add -p myfile.py
+import matplotlib
+import numpy as np
#Stage this hunk [y,n,a,d,/,j,J,g,e,?]?

Next: Reading - GitHub Pages