Git Stash
Contents
Git Stash¶
Before you can git pull
, you need to have committed any changes you have made. If you find you want to pull, but you’re not ready to commit, you have to temporarily “put aside” your uncommitted changes.
For this, you can use the git stash
command, like in the following example:
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)
Remind ourselves which branch we are using:
%%bash
git branch -vv
* experiment 497c32c Add Cadair Idris
main 71cdbbe [origin/main] Merge branch 'main' of github.com:alan-turing-institute/github-example
%%writefile Wales.md
Mountains In Wales
==================
* Pen y Fan
* Tryfan
* Snowdon
* Glyder Fawr
* Fan y Big
* Cadair Idris
* Penygader
Overwriting Wales.md
%%bash
git stash
Saved working directory and index state WIP on experiment: 497c32c Add Cadair Idris
%%bash
git pull
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.
git pull <remote> <branch>
If you wish to set tracking information for this branch you can do so with:
git branch --set-upstream-to=origin/<branch> experiment
---------------------------------------------------------------------------
CalledProcessError Traceback (most recent call last)
Input In [5], in <cell line: 1>()
----> 1 get_ipython().run_cell_magic('bash', '', 'git pull\n')
File /opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/IPython/core/interactiveshell.py:2358, in InteractiveShell.run_cell_magic(self, magic_name, line, cell)
2356 with self.builtin_trap:
2357 args = (magic_arg_s, cell)
-> 2358 result = fn(*args, **kwargs)
2359 return result
File /opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/IPython/core/magics/script.py:153, in ScriptMagics._make_script_magic.<locals>.named_script_magic(line, cell)
151 else:
152 line = script
--> 153 return self.shebang(line, cell)
File /opt/hostedtoolcache/Python/3.8.13/x64/lib/python3.8/site-packages/IPython/core/magics/script.py:305, in ScriptMagics.shebang(self, line, cell)
300 if args.raise_error and p.returncode != 0:
301 # If we get here and p.returncode is still None, we must have
302 # killed it but not yet seen its return code. We don't wait for it,
303 # in case it's stuck in uninterruptible sleep. -9 = SIGKILL
304 rc = p.returncode or -9
--> 305 raise CalledProcessError(rc, cell)
CalledProcessError: Command 'b'git pull\n'' returned non-zero exit status 1.
By stashing your work first, your repository becomes clean, allowing you to pull. To restore your changes, use git stash apply
.
%%bash
git stash apply
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: Wales.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
__pycache__/
wsd.py
no changes added to commit (use "git add" and/or "git commit -a")
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.
NB: we delete previous tags with the same name remotely and locally first, to avoid duplicates.
git tag -a v1.0 -m "Release 1.0"
git push --tags
You can also use tag names in the place of commmit hashes, such as to list the history between particular commits:
git log v1.0.. --graph --oneline
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:
%%writefile Makefile
MDS=$(wildcard *.md)
PDFS=$(MDS:.md=.pdf)
default: $(PDFS)
%.pdf: %.md
pandoc $< -o $@
Writing Makefile
%%bash
make
pandoc Scotland.md -o Scotland.pdf
pandoc Wales.md -o Wales.pdf
pandoc lakeland.md -o lakeland.pdf
pandoc test.md -o test.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 main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: Wales.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
Makefile
Scotland.pdf
Wales.pdf
__pycache__/
lakeland.pdf
test.pdf
wsd.py
no changes added to commit (use "git add" and/or "git commit -a")
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 main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: Wales.md
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
Makefile
__pycache__/
wsd.py
no changes added to commit (use "git add" and/or "git commit -a")
%%bash
git add Makefile
git add .gitignore
git commit -am "Add a makefile and ignore generated files"
git push
[main c8ba483] Add a makefile and ignore generated files
3 files changed, 12 insertions(+), 1 deletion(-)
create mode 100644 .gitignore
create mode 100644 Makefile
To github.com:alan-turing-institute/github-example.git
537950c..c8ba483 main -> main
Git clean¶
Sometimes you end up creating various files that you do not want to include in version control. An easy way of deleting them (if that is what you want) is the git clean
command, which will remove the files that git is not tracking.
%%bash
git clean -fX
Removing Scotland.pdf
Removing Wales.pdf
Removing lakeland.pdf
Removing test.pdf
%%bash
ls
Makefile
Scotland.md
Wales.md
__pycache__
lakeland.md
test.md
wsd.py
With -f: don’t prompt
with -d: remove directories
with -x: Also remote .gitignored files
with -X: Only remove .gitignore files
Hunks¶
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,?]?
GitHub pages¶
Yaml Frontmatter¶
GitHub will publish repositories containing markdown as web pages, automatically.
You’ll need to add this content:
--- ---
A pair of lines with three dashes, to the top of each markdown file. This is how GitHub knows which markdown files to make into web pages. Here’s why for the curious.
%%writefile test.md
---
title: Github Pages Example
---
Mountains and Lakes in the UK
===================
Engerland is not very mountainous.
But has some tall hills, and maybe a mountain or two depending on your definition.
Overwriting test.md
%%bash
git commit -am "Add github pages YAML frontmatter"
[main 12ee6ad] Add github pages YAML frontmatter
1 file changed, 7 insertions(+), 4 deletions(-)
The gh-pages branch¶
GitHub creates github pages when you use a special named branch.
By default this is gh-pages
although you can change it to something else if you prefer.
This is best used to create documentation for a program you write, but you can use it for anything.
os.chdir(working_dir)
%%bash
git checkout -b gh-pages
git push -uf origin gh-pages
Branch 'gh-pages' set up to track remote branch 'gh-pages' from 'origin'.
Switched to a new branch 'gh-pages'
remote:
remote: Create a pull request for 'gh-pages' on GitHub by visiting:
remote: https://github.com/alan-turing-institute/github-example/pull/new/gh-pages
remote:
To github.com:alan-turing-institute/github-example.git
* [new branch] gh-pages -> gh-pages
The first time you do this, GitHub takes a few minutes to generate your pages.
The website will appear at http://username.github.io/repositoryname
, for example:
Layout for GitHub pages¶
You can use GitHub pages to make HTML layouts, here’s an example of how to do it, and how it looks. We won’t go into the detail of this now, but after the class, you might want to try this.
%%bash
# Cleanup by removing the gh-pages branch
git checkout main
git push
git branch -d gh-pages
git push --delete origin gh-pages
git branch --remote
Your branch is ahead of 'origin/main' by 1 commit.
(use "git push" to publish your local commits)
Deleted branch gh-pages (was 12ee6ad).
origin/main
Switched to branch 'main'
To github.com:alan-turing-institute/github-example.git
c8ba483..12ee6ad main -> main
To github.com:alan-turing-institute/github-example.git
- [deleted] gh-pages