How to use git
1 What is git?
Distributed version control system, which has basically become the de facto standard in open source projects. Developed in 2005 by Linus Torvalds in order to replace the closed source Bitkeeper software, which was in use to maintain the development of the Linux kernel.
From Wikipedia:
"git" can mean anything, depending on your mood.
- Random three-letter combination that is pronounceable, and not actually used by any common UNIX command. The fact that it is a mispronunciation of "get" may or may not be relevant.
- Stupid. Contemptible and despicable. Simple. Take your pick from the dictionary of slang.
- "Global information tracker": you're in a good mood, and it actually works for you. Angels sing, and a light suddenly fills the room.
- "Goddamn idiotic truckload of sh*t": when it breaks.
Main features:
- git saves versions as hashed diffs
- you always have the full history with all versions and branches in your local copy of the repository
- branches are cheap, fast and encouraged!
2 Before you start
Obviously, you will need to have git
installed. Get it from the
git official homepage, which also has a link to a complete
book on git.
- configure
git
: - settings will be stored in
$HOME/.gitconfig
git config --global user.name "Michael Olberg" git config --global user.email "michael.olberg@chalmers.se"
2.1 Getting help
git help <verb> git <verb> --help
3 Create your first repo
3.1 From an empty directory
git init foo
which is equivalent to
mkdir foo
cd foo
git init
3.2 From a directory with files
cd bar git init git add -A # add all files
4 Working with your repository
Git distinguishes between the following states of a file, (see here):
- untracked: a file not being part of your repo, e.g. a new file
- unmodified: a committed, unmodified file
- modified: a file in your repo which has been modified
- staged: a file which has been added (staged) but not comitted, yet.
touch foo git status # will show foo as untracked git add foo git status # will show foo tracked (and staged) but not committed edit foo git status # will show foo as not committed *and* modified git commit -m "add file foo" git status # the old version is now committed, the edited version is unstaged
4.1 Get the status
The status command typically suggests to you what you should be doing next, or, alternatively, how you can revert your last step.
git status git status -uno # useful if you have lots of untracked files
4.2 Logging
To see the history of your commits
git log git log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short
You could create an alias for the above command
git config --global alias.hist 'log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short'
git hist
4.3 Tagging
Tag your versions, rather than referring to them by commit hash
git tag v1.0 # a light weight tag git tag -a v1.2 -m "my new version v1.2" # an annotated tag with commit message
5 Branching
5.1 Create a branch
git branch # show which branches exist and which one we are on git branch newfeature # create a new branch ... git checkout newfeature # ... and start working on it edit file1 git add file1 git commit -m "add file1" git diff master # show differences wrt other branch git checkout master git merge newfeature
5.2 Keep a .gitignore file
A git repository is mainly for ASCII files, so put all binary files
in .gitignore
, so you won't commit by mistake:
A typical .gitignore file might look like
*~
*.o
*.a
*.so
dist/
.DS_Store
Don't forget to add the .gitignore
to your repository:
git add .gitignore
git commit -m "add .gitignore file"
6 Working with remote repositories
Remote repositories can be
- on github, gitlab, bitbucket, gogs, … all with basically the same web interface
- a different directory and/or machine (in the latter case a git server is running)
- you will typically have to get an account on the web site where you want to host your project
6.1 Create the remote repository first
- Follow the instructions of the web interface to create a new project
- typically choose to add README.md and .gitignore file
- it is recommended to add a LICENSE file
- on your local machine clone the repository
git clone https://whatever/foo.git
cd foo
6.2 Create the local repository first
- Follow the instructions of the web interface to create a new project
- typically do not add any default files
On your local machine
git remote add https://whatever/foo.git git push -u origin master git push --tags # also push tags if you have some
6.3 Pull requests
This is a feature of web based git repositories, not really git itself.
- go to somebody else's repository on github (or similar) and click fork, this will create a copy of the repository on github but now owned by you.
git clone https://github.com/molberg/tool.git
cd tool
git branch mychange
git checkout mychange
edit <file>
git add file
git push -u origin mychange
- your modification should now show up as a pull request in the repository of somebody else
7 Examples
7.1 Working on the command line
Example: fakeobs
tar xzvf Fakeobs_v0.4.tar.gz
cd Fakeobs_v0.4
git status
This will tell us that the current directory is not under git version control. Initialize it and remove files that won't be part of the repository
git init rm *.pyc mytasks.py fakeobs_cli.py fakeobs.py echo mytasks.py > .gitignore echo fakeobs_cli.py >> .gitignore echo fakeobs.py >> .gitignore echo '*.pyc' >> .gitignore echo '*~' >> .gitignore git add fakeobs.xml INSTALL LICENSE task_fakeobs.py .gitignore git status git commit -m "initial commit" git status git log
Make your first changes. Rename INSTALL to README.md and reformat to markdown syntax.
git mv INSTALL README.md # edit README.md git add README.md git commit -m "rename INSTALL to README.md and reformat"
Make a branch and fix Python syntax
git branch # list all branches git branch autopep git checkout autopep # reformat task_fakeobs.py git add task_fakeobs.py git commit -m "reformat using autopep" # maybe do some testingh on branch autopep git checkout master git merge autopep git branch -d autopep # autopep branch no longer needed
7.2 Working with VS Code
Example: checkres
We will start with a casa 5
version already hosted on github and convert to casa 6
,
following a procedure outlined in the casa 6
documentation for
buildmytasks. I will be using a python virtual environment with
casatools
and casatasks
installed:
python -m venv casa6
source casa6/bin/activate
pip install --upgrade pip
pip install numpy
pip install scipy
pip install matplotlib
pip install --index-url https://casa-pip.nrao.edu/repository/pypi-casa-release/simple casatools
pip install --index-url https://casa-pip.nrao.edu/repository/pypi-casa-release/simple casatasks
pip install --index-url https://casa-pip.nrao.edu/repository/pypi-casa-release/simple casadata
pip install flake8
Now, inside the virtual environment, prepare the casa 6
version,
starting with the existing github repository for the casa 5
version. Create a new branch for this.
git clone git@github.com:onsala-space-observatory/checkres.git
cd checkres
git branch casa6
git checkout casa6
Now continue in codium
(or code
).
codium .
- select virtualenv for
casa6
- open file
task_checkres.py
- run linter on code and fix print statement
- in terminal:
python /home/michael/Python/casa6/buildmytasks --upgrade checkres.xml rm checkres.xml.bak mkdir private git mv task_checkres.py private/ echo '__name__ = "checkres"' > __init__.py echo '__all__ = [ "checkres" ]' >> __init__.py echo 'from .checkres import checkres' >> __init__.py
In VS code:
- update installation instructions
- stage all files
- commit changes
Finally, push branch to github:
git push origin casa6