Git Basi, workflow e concetti avanzati (pt2) - Andrea Fornaia, Ph.D - DMI Unict

Page created by Harry Torres
 
CONTINUE READING
Git Basi, workflow e concetti avanzati (pt2) - Andrea Fornaia, Ph.D - DMI Unict
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
Git Basi, workflow e concetti avanzati (pt2) - Andrea Fornaia, Ph.D - DMI Unict
• 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
Git Basi, workflow e concetti avanzati (pt2) - Andrea Fornaia, Ph.D - DMI Unict
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)
Git Basi, workflow e concetti avanzati (pt2) - Andrea Fornaia, Ph.D - DMI Unict
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]
Git Basi, workflow e concetti avanzati (pt2) - Andrea Fornaia, Ph.D - DMI Unict
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
Git Basi, workflow e concetti avanzati (pt2) - Andrea Fornaia, Ph.D - DMI Unict
GitLab protect branch
Git Basi, workflow e concetti avanzati (pt2) - Andrea Fornaia, Ph.D - DMI Unict
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
Git Basi, workflow e concetti avanzati (pt2) - Andrea Fornaia, Ph.D - DMI Unict
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]
Git Basi, workflow e concetti avanzati (pt2) - Andrea Fornaia, Ph.D - DMI Unict
Issue Example

[https://github.com/mauricioaniche/repodriller/issues/89]
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