Tag: Git

Releasing Python Packages

When you need to fix a bug, add feature or change existing functionality in a library that you are using there are several ways to do this. Here I will show you how to do this properly:

  1. Fork repository.
  2. Clone into your local dir.
  3. Create new branch and add your code (do not forget to add tests!).
  4. Commit & push, create PR on your forked repo, merge.
  5. Create PR to the base project so this change can go upstream (and then the whole community benefits from it).
  6. Release your updated version of this lib.

Step 3 can be a bit tricky to do because often you need to test this new code in your existing project. My favourite way to test if your new code works is to install this lib (package) in "develop mode":

pip install -e /src/my_modified_lib

Step 6 is needed if you have continuous integration like TravisCI. For this you also need your own private pypi server or have an account on official python pypi server. To create a release package that you can upload on pypi server just type:

python setup.py sdist --formats=zip

When releasing package, MANIFEST.in file is very important so if your files are missing in the .zip package, the problem is with MANIFEST.in file.

Then just upload this package (located in `dist` folder) to pypi server. Next thing you will need to do is to tell your buildout process where this new package is located. This is unfortunately very different based on which buildout tool you use (e.g. if you are using buildout tool you need to add link to this package to the "find-links" list).

Git branch naming convention

The naming convention, I propose, have four sections:

  1. Story Type:
    • add == Add Feature
    • fix == Fix, Hotfix, Bug, ...
    • clean == Cleanup, Chore, ...
    • modify  == Modify existing functionality
  2. Short Summary: 2-3 words about what the branch contains
  3. Tracker ID (Planio, GitHub, ... )

First section is group and is separated with dash. 2nd and 3rd sections are separated with hyphens. The end result looks like this:

{story type}/{2-3 word summary}-{tracker id}


Git basics: workflow, pull request, rebasing, …

When I started using git (several years ago) I use only git command line. After a few years I decided to start using SourceTree. I regret this decision to this day :). The problem is that  you can't do a lot of things. Another big problem is that when you change your develop environment where you can't install SourceTree (e.g. remote via SSH) you are "lost". Because there aren't that many git command (that you should be using on a daily basis) there is no good reason that you should't learn them.

So here are some git commands that I use frequently.


git checkout LOCAL_OR_REMOTE_BRANCH #  switches to local or remote branch
git reset # undo add files
git checkout . # discard all changes
git checkout dir/file # discard changes in dir or specific file
git clean -f # delete all untracked files

git commit --amend # append commit changes to the last commit. This is VERY useful. e.g. you forgot to add some file or did some minor  mistake.
git rebase -i HEAD~6 # this will get last 6 commits and you will be able to modify the commits

git branch  # list of local branches
git remote -v # list remotes

// DIFF commands
git diff --name-status master..BRANCH  # shows a list of files that were changed
git diff --stat --color master..BRANCH # shows a list of files that were changed. More detailed view
git diff master..BRANCH  # you can cycle through changes
git diff commit_id HEAD # shows difference between current version and `commit_id` version

If you are working on some branch but the master is several commits ahead you can use rebase to add local changes on top. Here is detailed workflow:

git fetch origin  # get fresh version of origin master
git rebase origin/master  #  merge origin/master into your curr branch and add local changes on top
# reslove conflicts & git add
git rebase --continue

Git general workflow:

git pull
git checkout -b BRANCH_NAME
// do your work...
git commit
git checkout master
git merge BRANCH_NAME
git push

"Github" workflow (i.e. creating pull-request):

git pull
git checkout -b BRANCH_NAME
// do your work...
git commit
git push origin BRANCH_NAME

The main difference between general git workflow and github workflow is that on github you (should) always create pull-request. So after you push your branch to remote origin (line 5) you go to this github repository select your new branch and click on that green button "New pull request" (see Image 1).

Image 1: Creating pull request
Image 1: Creating pull request


Very useful command is also `revert`. If you already merged your branch into master (which is protected) and you wish to "undo" you can do the folowing.

git revert SHA

SHA is the branch ID that you wish to undo. You can read more about undoing, fixing, etc here: link

NOTE: there are probably a lot more things you should know so I strongly suggest that you use "uncle Google" 🙂 (also there are several great YouTube videos you can watch if you are an absolute beginner).


Reset tree to original commit and use rebase not merge:

git reset --hard d27dce5129715f3c32aed376eeca348d142f5398 # initial commit
git fetch -p
git rebase origin/master
# fix merge conflicts (this is not merge, wording is a bit confusing)
git rebase --continue
git cherry-pick dac0848faf4219058b59dce8deb80084ade74828 # Update alembic script down_revision. fix merge conflicts (this is not merge, wording is a bit confusing) etc 
git push...


Force “git pull” to overwrite local files:

git fetch --all
git reset --hard origin/<branch_name>

git fetch fetch downloads the latest from remote without trying to merge or rebase anything.

Then the git reset  resets the master branch to what you just fetched. The  --hard option changes all the files in your working tree to match the files in origin/master (Source: link)


Changing the timestamp of a previous Git commit:

git filter-branch --env-filter \
"if test \$GIT_COMMIT = '06387f3c078f9f36dc4074d90550eb0b11013607'
    export GIT_AUTHOR_DATE='Thu Apr 5 19:54:26 2018 +0200'
    export GIT_COMMITTER_DATE='Thu Apr 5 19:54:26 2018 +0200'
fi" && rm -fr "$(git rev-parse --git-dir)/refs/original/"


Some additional reading:

  • A really good post about git rebase: link

Deploy website with Git bare

I tried to follow a few tutorials / howtos but non of them worked perfectly so I decided to write my own how-to. If nothing else I will know which one to follow the next time I came across this problem 🙂

One of the problems (as always) was that some of them were obsolete or did not tell for which git version that how-to is written for...

I was doing this with git version

This were my steps:

Server side:

git init --bare
git config core.bare false
git config core.worktree /home/gasper/website
git config receive.denycurrentbranch ignore
cat > hooks/post-receive
git checkout -f
chmod +x hooks/post-receive

NOTE: if you want to deploy a specific branch and not 'master' branch then you must change hooks/post-receive to:

cat > hooks/post-receive
git checkout -f [BRANCH_NAME]

Local machine:

git remote add web ssh://myserver/home/gasper/git/somesite.git
git push web +master:refs/heads/master


Here are some references:

If you have any questions leave a comment.