Git Basi, workflow e concetti avanzati (pt2) - Andrea Fornaia, Ph.D - DMI Unict
←
→
Page content transcription
If your browser does not render page correctly, please read the page content below
Git Basi, workflow e concetti avanzati (pt2) Andrea Fornaia, Ph.D. Department of Mathematics and Computer Science University of Catania Viale A.Doria, 6 - 95125 Catania Italy fornaia@dmi.unict.it https://www.dmi.unict.it/fornaia/ A.A. 2020/2021
• A home for free public git repositories • Interface for exploring git repositories • Real open source – immediate, easy access to the code • Fork it, try it, learn it • Social Coding
Forking Projects • Contribute to an existing project to which you don’t have push access • GitHub will make a copy of the project that is entirely yours • No need to add users to projects as collaborators to give them push access • People can push their changes back to the original repository by Pull Requests (PR)
Issues • Requests for contribution: – Bugfix – Enhancement – New Feature • It opens an issue discussion • A good way to start with GitHub open-source projects: – fork the project – work on one of the issues – propose your solution with a Pull Request [https://github.com/mauricioaniche/repodriller]
Due modi per contribuire • Merge request (push abilitato): ß Molto usato in GitLab – Lo sviluppatore deve avere accesso in scrittura (push abilitato), facendo parte dei contributors del progetto (origin) – Consiste nell richiedere il merge di due branch nello stesso repository – Tipicamente tra un topic branch e il master in origin – Tipicamente il master è protetto, e solo il maintainer può approvarne i commit • Pull request (push disabilitato): ß Molto usato in GitHub – Lo sviluppatore ha accesso solo in lettura, ma ha fatto un fork del progetto nel suo namespace – Upstream è il riferimento (remote) al repository da cui è stato fatto il fork – Le modifiche vengono aggiunte ad un topic branch sul respository privato (origin) – Viene avviata una pull request per fare il merge di due branch in repository diversi – Tipicamente tra un topic branch in origin e il master in upstream
GitHub Flow 1 2 3 4 5 6 1. Creare un topic branch dal master 2. Fare dei commit per migliorare il progetto 3. Aprire una Pull Request 4. Gli sviluppatori discutono le modifiche, e potenzialmente aggiungono altri commit 5. Si fa il pull e il test delle modifiche 6. Si fa il merge del topic branch nel master
Issues • Requests for contribution: – Bugfix – Enhancement – New Feature • It opens an issue discussion • A good way to start with GitHub open-source projects: – fork the project – work on one of the issues – propose your solution with a Pull Request [https://github.com/mauricioaniche/repodriller]
Pull Request Example [https://github.com/mauricioaniche/repodriller/pull/99]
PR and Code Coverage • Code coverage (test coverage): – percentage of source code executed by an automated test suite ( hits / total_lines ) – a code with high coverage has lesser chances of containing undetected bugs • Include coverage report into the CI pipeline: – focus on sound integrations • refine unit tests to increase coverage before merge – promote healthy pull requests • where new features and bug fixes commonly occur
How does it work • Source code instrumentation: – adds instrumentation statements to the source code and use a normal compiler to produce an instrumented application • Intermediate code instrumentation: – adds instrumentation bytecode to the compiled files, generating a new instrumented application • Runtime information collection: – collects information from the runtime environment during (non-instrumented) code execution to determine coverage
CodeCov • Code coverage tool – coverage report – supports different languages • Easy to integrate: – GitHub – Travis CI • Check coverage for: – commits – branches – files and folders – pull requests [https://codecov.io]
[https://agostini.tech/2017/07/16/code-coverage-with-codecov/]
Advanced Workflows
Gitflow master: always reflects a production- ready state. Only has tags tags: to mark production ready releases develop: latest delivered changes for next release (integration branch) feature branch: to develop a single new feature. May exist in developer repos only, not in origin release branch: (e.g. release-1.2) to prepare develop content for next production release hotfix branch: (e.g. hotfix-1.2.1) when a critical bug in a production version must be resolved immediately
Git Flow setup in SourceTree
Other well known workflows • Central Repository – For who comes from CVCS (like SVN) – Local changes are made on master branch – In case of conflicts while pushing, use rebase – Produces a linear history • Feature Branching – Use only one long-running branch (master) – Use topic branches to develop new features of fixes – Use tags to mark production ready releases – Is easier then gitflow, you could start from this! • Forking Workflow – Each contributor (or group) refers to two git repositories: a private one and a public (official) one – Developer pushes to their own private (server-side) repository – Only the project maintainer can push to the official repository (handling developer’s pull requests)
Forking Workflow dev1 fork maintainer fork dev2 private repo public repo privaterepo push push push dev1 mainteiner dev2 local repo local repo commit local repo commit commit
Create the Workflow for your needs GitHub repository official repo push pull pull testing repo development repo Server with GPU Laptop with IDE & refactoring tools
SCM & Pipelines
Branches and Environments Note: example with ‘feature branching’ workflow [https://blog.kontena.io/continuous-delivery-with-gitlabci/]
SCM and pipelines • A pipeline is a group of jobs that get automatically executed in stages • Triggered by updates in the code repository (SCM: Source Code Management) • All of the jobs in a stage (i.e. Tests) can be executed in parallel • if they all succeed, the pipeline moves on to the next stage • if one of the jobs fails, the next stage is not (usually) executed
test: stage: test script: - apt-get update -qy GitLab Pipelines - apt-get install -y nodejs - bundle install --path /cache - bundle exec rake db:create RAILS_ENV=test developer - bundle exec rake test staging: push code stage: deploy script: - gem install dpl - dpl --provider=heroku --app=gitlab-ci-ruby-test- repository staging --api-key=$HEROKU_STAGING_API_KEY only: - master pipeline triggered production: stage: deploy run jobs runner script: - gem install dpl if commit if tagged - dpl --provider=heroku --app=gitlab-ci-ruby-test- on master commit prod --api- key=$HEROKU_PRODUCTION_API_KEY only: - tags staging production when: manual .gitlab-ci.yml [https://gitlab.com/help/ci/examples/test-and-deploy-ruby-application-to-heroku.md]
Tutorial Heroku + GitLab CI/CD • Codice: https://github.com/dmi-lab-isd/heroku-cicd • Il codice è ospitato su GitHub, ma deve essere clonato in un repository GitLab per poter usufruire di GitLab CI • È necessario creare un account su Heroku (free) – Limite di 500 ore al mese di esecuzione • L’applicazione verrà eseguita da Heroku in un container (dyno) eseguendo il comando definito in Procfile – L’app va in sleep dopo 30 minuti senza richieste – Si riattiva alla prossima richiesta (delay di avvio) • È consigliabile installare anche la command line di heroku, es. per vedere i log delle applicazioni (heroku logs --app name --tail)
Maven Pipeline [https://www.bevuta.com/en/blog/continuous-delivery-with-gitlab-ci-and-ansible-part-2/]
Advanced Topics
Fast Forward Merge • Using FF you lose any reference in the history about the branch! • Even if FF is possible, you may avoid it – commit history will be a record of what actually happened • FF makes the history linear when is possible • To force linear history, use rebase instead of merge
HEAD ~ and ^ HEAD~1: il commit precedente ad HEAD HEAD^1: il primo parent di HEAD HEAD^2: il secondo parent di HEAD [http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde]
Detached HEAD • With "git checkout” you determine which revision of your project you want to work on. • Normally, you use a branch name to communicate with "git checkout” (if none, HEAD is assumed). • This move also HEAD to point the specific branch. • When a specific commit is checked out instead of a branch you will have a "detached HEAD”: HEAD is not pointing to branch! $ git graph * 76d9801 (HEAD, master) C3 * f7c2337 C2 * 1026c96 C1 $ git checkout f7c2337 Note: checking out 'f7c2337'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. …
Detached HEAD … If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b new_branch_name $ git graph * 76d9801 (master) C3 * f7c2337 (HEAD) C2 * 1026c96 C1 $ touch C4.txt && git add C4.txt && git commit -m C4 $ git graph –all * 024c5e5 (HEAD) C4 | * 76d9801 (master) C3 |/ * f7c2337 C2 * 1026c96 C1
Detached HEAD Option 1: SAVE CHANGES Option 2: DISCARD CHANGES $ git checkout -b mod $ git checkout master Switched to a new branch 'mod’ Warning: you are leaving 1 commit behind, not connected to any of your $ git graph --all branches: 024c5e5 C4 * 024c5e5 (HEAD, mod) C4 | * 76d9801 (master) C3 If you want to keep them by creating a new branch, this may be a good time to |/ do so with: * f7c2337 C2 * 1026c96 C1 git branch new_branch_name 024c5e5 git reflog Switched to a new branch 'master’ Usefull to recover the name (SHA1) of a $ git graph --all recently deleted commit! (024c5e5) * 76d9801 (HEAD, master) C3 * f7c2337 C2 It shows the history of all your pointer * 1026c96 C1 operations (checkout, branch…)
Git reflog $ git reflog 76d9801 HEAD@{0}: checkout: moving from 024c5e537aff2d53f531dc0e1c58dc7a34d2807f to master 024c5e5 HEAD@{1}: commit: C4 f7c2337 HEAD@{2}: checkout: moving from master to f7c2337 76d9801 HEAD@{3}: commit: C3 f7c2337 HEAD@{4}: commit: C2 1026c96 HEAD@{5}: commit (initial): C1 $ git branch mod 024c5e537aff2d53f531dc0e1c58dc7a34d2807f $ git graph --all * 024c5e5 (mod) C4 | * 76d9801 (HEAD, master) C3 |/ * f7c2337 C2 * 1026c96 C1
Rebase vs Merge master C1 C2 C3 C6 master C4 C5 C1 C2 C3 feature C4 C5 feature master C1 C2 C3 C4* C5* feature
Rebase vs Merge MERGE REBASE git checkout master git checkout feature git merge feature git rebase master git branch –d feature (optional) (move feature commits on top of master) git checkout master git merge feature (is ff) git branch –d feature (optional) PRO PRO commit history is a record of what Linear and clean history actually happened CONS CONS Non-linear history can be hard changing the commit history you’re to understand lying about what actually happened Take the best from both: rebase local changes before pushing them, to clean up your history but never rebase anything you’ve pushed somewhere
Rebase Conflicts error: could not apply fa39187... something to add to patch A When you have resolved this problem, run "git rebase --continue". If you prefer to skip this patch, run "git rebase --skip" instead. To check out the original branch and stop rebasing, run "git rebase --abort". Could not apply fa39187f3c3dfd2ab5faa38ac01cf3de7ce2e841... Change fake file • You can run git rebase --abort to completely undo the rebase. – Git will return you to your branch's state as it was before git rebase was called. • You can run git rebase --skip to completely skip the commit. – None of the changes of by the problematic commit will be included. – It is very rare that you would choose this option (don’t do it!) • You can fix the conflict. [https://help.github.com/articles/resolving-merge-conflicts-after-a-git-rebase/]
Interactive Rebase and Squash
Interactive Rebase and Squash
Stashing • When you want to switch branches • But you don’t want to commit what you’ve been working on yet – You can’t change branch if changes couldn’t be applied without conflicts with the new branch • Takes the dirty state of your working directory – staged changes (index) – modified tracked files (working dir) • Saves it on a stack of unfinished changes that you can reapply at any time [https://git-scm.com/book/en/v1/Git-Tools-Stashing]
Stashing $ git status On branch master Changes to be committed: new file: bar.txt Changes not staged for commit: modified: foo.txt Untracked files: baz.txt $ git stash Saved working directory and index state WIP on master: e0ad866 C1 HEAD is now at e0ad866 C1 $ git status On branch master Untracked files: baz.txt $ git stash list stash@{0}: WIP on master: e0ad866 C1 ... do something else ... $ git stash pop (index and working dir status restored; stash dropped)
Reset vs Checkout • git checkout HEAD -- revert the dir/file content from working tree to a specific commit version – you can use or instead of HEAD • git reset HEAD -- remove file/dir from index tree (staging area) – used to unstage modifications
Reset vs Checkout • git checkout modifies the working tree content to a specific commit (typically a branch) and updates HEAD • git reset moves the current branch pointer to the given commit (HEAD will be also updated) $ git graph --all $ git checkout mod $ git reset f7c2337 * 024c5e5 (mod) C4 | * 76d9801 (HEAD,master) C3 $ git graph --all $ git graph --all |/ * 024c5e5 (HEAD,mod) C4 * 76d9801 (master) C3 * f7c2337 C2 | * 76d9801 (master) C3 * f7c2337 (HEAD,mod) C2 * 1026c96 C1 |/ * 1026c96 C1 * f7c2337 C2 * 1026c96 C1 $ git status C4.txt untracked
That’s all! (for now)
References • S. Chacon and B. Straub: Pro Git. [https://git-scm.com/book/en/v2] • K. Broman and S.G. Younkin: A brief introduction to git & GitHub. [https://www.biostat.wisc.edu/~kbroman/talks/GitPrimer.pdf] • R. Dudler: git - the simple guide. [http://rogerdudler.github.io/git-guide/] • V. Driessen: A successful Git branching model. [http://nvie.com/posts/a-successful-git-branching-model/] • Understanding the GitHub Flow. [https://guides.github.com/introduction/flow/] • Git Cheat Sheet: https://education.github.com/git-cheat-sheet- education.pdf • R. E. Silverman: Git Pocket Guide: A Working Introduction • Parth Shandilya: Integrating Travis CI and Codecov into a Python- based Project. [https://hackernoon.com/integrating-travis-ci-and-codecov-into-a-python-based- project-6f658074ff63]
You can also read