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:
Fork repository.
Clone into your local dir.
Create new branch and add your code (do not forget to add tests!).
Commit & push, create PR on your forked repo, merge.
Create PR to the base project so this change can go upstream (and then the whole community benefits from it).
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).
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
// "UNDO" COMMANDS
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
// COMMIT COMMANDS:
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
// LIST COMMANDS
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
# IF CONFLICTS:
# 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
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...
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)
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...