├── .gitignore ├── README.md ├── assets ├── branch-1.png ├── branch-2.png ├── branch-3.png ├── branch-4.png ├── branch-5a.png ├── branch-5a.svg ├── branch-5b.png ├── branch-5b.svg ├── branch-5c.svg ├── branch-5d.svg ├── branch-5e.svg ├── computer-society-logo.svg ├── head-symbolic.png ├── internals-3a.svg ├── internals-3b.svg ├── internals-3c.svg ├── linux-system.png ├── nuieee-logo.png └── workflow.svg ├── css └── main.css ├── index.html ├── js └── main.js ├── main.md └── slides ├── 00-template.md ├── 01_git_introduction.md ├── 02_git_workflow.md ├── 03_git_internals.md ├── 04_git_merge.md ├── 05_git_remote.md └── merge-slides.sh /.gitignore: -------------------------------------------------------------------------------- 1 | lib 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Workshop Introduction to Git 2 | 3 | This repository contains the presentation and exercises for the Git workshop, prepared and presented by **IEEE University of Porto Student Branch**. 4 | 5 | ## Workshop Content 6 | 7 | In the repository code you can find the presentation, developed using [Remark](https://remarkjs.com). It is a slideshow tool where each slide content is written in Markdown, and the presentation style can be customized through CSS. 8 | 9 | The presentation is hosted on GitHub pages: [https://ieeeupsb.github.io/workshop-git/](https://ieeeupsb.github.io/workshop-git/) 10 | 11 | The exercises and setup instructions are available on the [**Wiki**](https://github.com/ieeeupsb/workshop-git/wiki) (currently in portuguese, but will be in english soon). 12 | 13 | ## Topics 14 | 15 | This workshop material covers the basics of Git, it intends to cover all the useful comands for your Git workflow, as well view history through logs, organize your development with branches, and so on. 16 | 17 | - Introduction to Git 18 | - The three Git sections/trees: Working Directory, Staging Area or Index, and Repository/Database 19 | - Commands for the typical workflow: work, stage, commit, repeat! 20 | - Aditional commands such `log`, `status`, `diff` and its options. 21 | - A look inside into Git Internals 22 | - Introduction to branches 23 | - What are they and motivation to make use of them 24 | - How to merge 25 | - The three merge scenarios and how to deal with conflicts 26 | - Remote repositories 27 | - How Git manages and associates local repositories with remote ones 28 | - How to create remote branches 29 | - How to pull remote branches 30 | - Configure tracking branches 31 | 32 | ## Authors 33 | 34 | - **Fábio Gaspar** : Github (@fabiodrg666) | Twitter (@fabiodrg666) | [LinkedIn](https://www.linkedin.com/in/fabiodr-gaspar/) 35 | 36 | ## Revision history 37 | 38 | ### 21st March 2018 39 | 40 | - Initial presentation and Wiki 41 | 42 | ### 22nd March 2019 43 | 44 | - Moved from PowerPoint presentation to Remark (Markdown is love :heart:) 45 | - Enhanced diagrams in the presentation 46 | - More detailed and clear explanation of how local and remote repositories work 47 | -------------------------------------------------------------------------------- /assets/branch-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ieeeupsb/workshop-git/19d17a8dc4586f9b4b1645482ec92e93c9b36308/assets/branch-1.png -------------------------------------------------------------------------------- /assets/branch-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ieeeupsb/workshop-git/19d17a8dc4586f9b4b1645482ec92e93c9b36308/assets/branch-2.png -------------------------------------------------------------------------------- /assets/branch-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ieeeupsb/workshop-git/19d17a8dc4586f9b4b1645482ec92e93c9b36308/assets/branch-3.png -------------------------------------------------------------------------------- /assets/branch-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ieeeupsb/workshop-git/19d17a8dc4586f9b4b1645482ec92e93c9b36308/assets/branch-4.png -------------------------------------------------------------------------------- /assets/branch-5a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ieeeupsb/workshop-git/19d17a8dc4586f9b4b1645482ec92e93c9b36308/assets/branch-5a.png -------------------------------------------------------------------------------- /assets/branch-5a.svg: -------------------------------------------------------------------------------- 1 | 2 |
Commit
e9d71
[Not supported by viewer]
master
master
HEAD
HEAD
new-branch
new-branch
Commit
112f0
[Not supported by viewer]
Commit
aa156
[Not supported by viewer]
-------------------------------------------------------------------------------- /assets/branch-5b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ieeeupsb/workshop-git/19d17a8dc4586f9b4b1645482ec92e93c9b36308/assets/branch-5b.png -------------------------------------------------------------------------------- /assets/branch-5b.svg: -------------------------------------------------------------------------------- 1 | 2 |
Commit
e9d71
[Not supported by viewer]
master
master
HEAD
HEAD
new-branch
new-branch
Commit
112f0
[Not supported by viewer]
Commit
aa156
[Not supported by viewer]
-------------------------------------------------------------------------------- /assets/branch-5c.svg: -------------------------------------------------------------------------------- 1 | 2 |
HEAD
HEAD
new-branch
new-branch
master
master
Commit
112f0
[Not supported by viewer]
main.c (99666)
[Not supported by viewer]
Commit
e9d71
[Not supported by viewer]
main.c (1523f)
[Not supported by viewer]
Commit
bb156
[Not supported by viewer]
main.c (99666)
[Not supported by viewer]
list.c (023abe)
[Not supported by viewer]
Commit
aa156
[Not supported by viewer]
main.c (bbf10)
[Not supported by viewer]
test.c (4452a)
[Not supported by viewer]
-------------------------------------------------------------------------------- /assets/branch-5d.svg: -------------------------------------------------------------------------------- 1 | 2 |
Commit
112f0
[Not supported by viewer]
main.c (99666)
[Not supported by viewer]
Commit
e9d71
[Not supported by viewer]
main.c (1523f)
[Not supported by viewer]
Commit
bb156
[Not supported by viewer]
main.c (99666)
[Not supported by viewer]
list.c (023abe)
[Not supported by viewer]
Commit
aa156
[Not supported by viewer]
main.c (bbf10)
[Not supported by viewer]
test.c (4452a)
[Not supported by viewer]
Commit
aa156
[Not supported by viewer]
main.c (ffff0)
[Not supported by viewer]
test.c (4452a)
[Not supported by viewer]
list.c (023abe)
[Not supported by viewer]
new-branch
new-branch
HEAD
HEAD
master
master
-------------------------------------------------------------------------------- /assets/branch-5e.svg: -------------------------------------------------------------------------------- 1 | 2 |
HEAD
HEAD
new-branch
new-branch
master
master
Commit
112f0
[Not supported by viewer]
main.c (99666)
[Not supported by viewer]
Commit
e9d71
[Not supported by viewer]
main.c (1523f)
[Not supported by viewer]
Commit
bb156
[Not supported by viewer]
main.c (321a0)
[Not supported by viewer]
list.c (023abe)
[Not supported by viewer]
Commit
aa156
[Not supported by viewer]
main.c (bbf10)
[Not supported by viewer]
test.c (4452a)
[Not supported by viewer]
-------------------------------------------------------------------------------- /assets/computer-society-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 23 | 27 | 28 | 29 | 47 | 49 | 50 | 52 | image/svg+xml 53 | 55 | 56 | 57 | 58 | 59 | 64 | 67 | 72 | 77 | 82 | 87 | 92 | 97 | 102 | 107 | 112 | 117 | 122 | 127 | 132 | 137 | 142 | 147 | 152 | 157 | 161 | 166 | 167 | 172 | 177 | 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /assets/head-symbolic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ieeeupsb/workshop-git/19d17a8dc4586f9b4b1645482ec92e93c9b36308/assets/head-symbolic.png -------------------------------------------------------------------------------- /assets/internals-3a.svg: -------------------------------------------------------------------------------- 1 | 2 |
Commit
tree
author
description
[Not supported by viewer]
Tree
Associate filenames to blobs and other trees
[Not supported by viewer]
Blob
File content
[Not supported by viewer]
Object
+ size
+ sha1
[Not supported by viewer]
-------------------------------------------------------------------------------- /assets/internals-3b.svg: -------------------------------------------------------------------------------- 1 | 2 |
Blob
(12345)
[Not supported by viewer]
Blob
(daf12)
[Not supported by viewer]
Tree
(abcde)
blob 12345
blob daf12
[Not supported by viewer]
File1.txt
This is come content
[Not supported by viewer]
main.c
int main() {...
[Not supported by viewer]
.\
[Not supported by viewer]
Commit
tree abcde
author: fabio
description: Init project
[Not supported by viewer]
-------------------------------------------------------------------------------- /assets/internals-3c.svg: -------------------------------------------------------------------------------- 1 | 2 |
Commit
tree abcde
author: fabio
description:
[Not supported by viewer]
Commit
tree abcde
author: fabio
description:
[Not supported by viewer]
Commit
tree abcde
author: fabio
description:
[Not supported by viewer]
HEAD
HEAD
Snapshot B
Snapshot B
Snapshot C
Snapshot C
Snapshot A
Snapshot A
-------------------------------------------------------------------------------- /assets/linux-system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ieeeupsb/workshop-git/19d17a8dc4586f9b4b1645482ec92e93c9b36308/assets/linux-system.png -------------------------------------------------------------------------------- /assets/nuieee-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ieeeupsb/workshop-git/19d17a8dc4586f9b4b1645482ec92e93c9b36308/assets/nuieee-logo.png -------------------------------------------------------------------------------- /assets/workflow.svg: -------------------------------------------------------------------------------- 1 | 2 |
Repository
Repository
Staging area
Staging area
Working directory
Working directory
-------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Roboto'); 2 | @import url('https://fonts.googleapis.com/css?family=Oswald'); 3 | 4 | :root { 5 | --bg-dark: #212121; 6 | --accent-primary: #ff0036; 7 | } 8 | 9 | body { 10 | font-family: 'Roboto', sans-serif; 11 | font-size: 1.7rem; 12 | line-height:1.5; 13 | } 14 | 15 | .remark-slide-content { 16 | font-size: inherit; 17 | } 18 | 19 | h1, h2, h3 { 20 | font-family: 'Oswald', sans-serif; 21 | font-weight: normal; 22 | margin: 1rem 0; 23 | } 24 | 25 | /** 26 | * Used on the first slide 27 | * */ 28 | .slide_title { 29 | position: relative; 30 | background-color: var(--accent-primary); 31 | color: white; 32 | } 33 | 34 | /** 35 | * Used by title slides (first slide) to show the workshop title and authors, in addition to student branch logo and chapter logo. The logos must be contained in a div with class slide_logos 36 | */ 37 | .slide_logos { 38 | display: flex; 39 | padding: 1rem; 40 | position: absolute; 41 | bottom: 1em; 42 | left: 3em; 43 | right: 3em; 44 | } 45 | 46 | .slide_logos > img { 47 | flex: 1; 48 | margin: 0.5rem 1.5rem; 49 | } 50 | 51 | /** 52 | * Used to introduce new section topics 53 | */ 54 | .slide_section { 55 | background-color: var(--bg-dark); 56 | color: white; 57 | } 58 | 59 | 60 | /** 61 | * Code snippets 62 | */ 63 | .remark-code, .remark-inline-code { 64 | font-size: 0.8em; 65 | font-family: Hack, monospace; 66 | } 67 | 68 | .remark-inline-code { 69 | font-weight: bold; 70 | color: var(--accent-primary); 71 | } 72 | 73 | .remark-code-span-highlighted { 74 | color: white; 75 | background-color:rgba(255, 99, 0, 0.88); 76 | } 77 | 78 | .flex { 79 | display:flex; 80 | } 81 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Workshop Git 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | let slideshow = remark.create({ 2 | sourceUrl: 'main.md', 3 | ratio: '16:9', 4 | /* highlight */ 5 | highlightLanguage: 'bash', 6 | highlightStyle: 'zenburn', 7 | highlightLines: 'true', 8 | highlightSpans: 'false', 9 | }); 10 | -------------------------------------------------------------------------------- /main.md: -------------------------------------------------------------------------------- 1 | name: slide_title 2 | class: slide_title, center, middle 3 | layout: true 4 | 5 | {{content}} 6 | 7 |
8 | nuieee-logo 9 | cs-logo 10 |
11 | 12 | --- 13 | 14 | name: slide_section 15 | class: slide_section, center, middle 16 | layout: true 17 | 18 | {{content}} 19 | 20 | --- 21 | 22 | template: slide_title 23 | layout: false 24 | 25 | # Workshop Introduction to Git 26 | 27 | --- 28 | 29 | template: slide_section 30 | 31 | # Version controls 32 | 33 | --- 34 | 35 | layout: false 36 | 37 | # Version control 38 | 39 | - System that **tracks** one or more files over time 40 | - Lets you check the files state on the past 41 | - In theory any file can be tracked 42 | - However, some **features** are **only** possible in **text files** 43 | - Tracking very **large files can slow things down** 44 | - **Git** is **not the first source version control**, there are many 45 | - However, **developers are more happy with Git** than anything else 46 | 47 | --- 48 | 49 | # Version controls: types 50 | ## LCVS 51 | 52 | - Local Version Control Systems (LCVS) 53 | - **Local** repository 54 | - Doesn't allow collaborative work 55 | - Not pratical if you want to work on multiple devices 56 | 57 | --- 58 | 59 | # Version Controls: types 60 | ## CVCS 61 | 62 | - Centralized Version Control Systems (CVCS) 63 | - Repository is hosted in one or more servers 64 | - Clients download one version of the repository, work over it, then send it to the server 65 | - All operations are online (network overhead, can't work offline) 66 | - Not really realiable 67 | - What if the server is down? 68 | - What if there's an accident with physical damage in the servers? 69 | - Example: SVN, Perforce 70 | 71 | --- 72 | 73 | # Version Controls: types 74 | ## DVCS 75 | 76 | - Distributed Version Control Systems (DVCS) 77 | - Repository hosted in one or more servers (like CVCS) 78 | - Clients have a full repository copy 79 | - Most operations are local 80 | - Fast 81 | - No internet connection is needed 82 | - Examples: **Git**, Mercurial 83 | - May take several disk time and require several time for downloading and uploading new versions if: 84 | - Very long history 85 | - Very large binary files 86 | 87 | --- 88 | 89 | template: slide_section 90 | 91 | # Setting up Git 92 | 93 | --- 94 | 95 | layout: false 96 | 97 | # Installing 98 | 99 | - Windows: [https://git-scm.com/download/win](https://git-scm.com/download/win) 100 | - Mac: [https://git-scm.com/download/mac](https://git-scm.com/download/mac) 101 | - Linux: [https://git-scm.com/download/linux](https://git-scm.com/download/linux) 102 | 103 | --- 104 | 105 | # Initial configuration 106 | 107 | - Changes on the repository are identified by the author with a name and email 108 | - Global configuration 109 | 110 | ```bash 111 | $ git config --global user.name "example" 112 | $ git config --global user.email "example@ieee.com" 113 | ``` 114 | 115 | - Repository configuration (*overrides* global configurations) 116 | 117 | ```bash 118 | $ git config user.name "example" 119 | $ git config user.email "example@ieee.com" 120 | ``` 121 | 122 | --- 123 | 124 | template: slide_section 125 | 126 | # Git workflow 127 | ## Work. Stage. Commit. Repeat! 128 | 129 | --- 130 | 131 | layout: false 132 | 133 | # Git worflow 134 | ## The three sections/trees 135 | 136 | .center[ 137 | ![git trees](assets/workflow.svg) 138 | ] 139 | 140 | --- 141 | 142 | # Creating new local repositories 143 | 144 | - Create a new empty repository with `init` command. 145 | - Can be applied in empty or non-empty directories 146 | - Git won't initialize the reposity in either case 147 | - No files are automatically tracked 148 | - A new hidden directory **.git** is created 149 | - Repository configurations 150 | - Data 151 | 152 | --- 153 | 154 | # Creating new local repositories 155 | 156 | ```bash 157 | # create an empty directory 158 | $ mkdir workshop-git 159 | # go inside that directory 160 | $ cd workshop-git/ 161 | # initialize empty repository 162 | $ git init 163 | ``` 164 | 165 | --- 166 | 167 | # Staging 168 | 169 | - You edit and create files in your working directory 170 | - Next step is to stage 171 | - The **add** command creates a new snapshot of the current file(s) content 172 | - Whatever **snapshots** you create, that **are what will be added to the repository when you *commit*** 173 | - Staging is an intermidiate phase between what you do in the working directory and what will be recorded in the repository/database 174 | 175 | --- 176 | 177 | # Staging 178 | 179 | ```bash 180 | # add specific file 181 | $ git add 182 | # add everything (new | modified | deleted) 183 | $ git add . 184 | # add everything (new | modified | deleted) 185 | $ git add -A 186 | # add already-tracked files (modified | deleted) 187 | $ git add -u 188 | ``` 189 | 190 | --- 191 | 192 | # Commit 193 | 194 | - The *commit* act takes the new snapshots and stores them "permantely" in the database 195 | - Each *commit* has an author and message 196 | - The author depends on your global and local configurations (name + email) 197 | 198 | ```bash 199 | $ git commit -m "message" 200 | ``` 201 | 202 | - You can stage and *commit* with the following shortcut 203 | - Only known files (modified or deleted) are taken into account 204 | 205 | ```bash 206 | $ git commit -a -m "message" 207 | $ git commit -am "message" 208 | ``` 209 | 210 | --- 211 | 212 | template: slide_section 213 | 214 | # Useful Git commands 215 | 216 | --- 217 | 218 | layout: false 219 | 220 | # Status 221 | 222 | - The `status` command shows a summary of: 223 | - modified files 224 | - **staged** files (a snapshot for file was created) 225 | - new files, **untracked** 226 | - The same file can be modified and staged. Why? 227 | 228 | ```bash 229 | $ git status 230 | ``` 231 | 232 | --- 233 | 234 | # Compare the git trees (staging area, working directory, commits) 235 | 236 | - The `diff` command show changes between: 237 | - two commits 238 | - commits and the working directory 239 | - ... 240 | 241 | ```bash 242 | # compare the working directory with staging area 243 | # what would be staged if you run `git add` 244 | $ git diff 245 | ``` 246 | 247 | --- 248 | 249 | # Compare the git trees (staging area, working directory, commits) 250 | 251 | ```bash 252 | # Compare the changes which are staged relative to a given 253 | # If the is not given, it compares with the last commit 254 | # It shows what changes will be recorded if you run `git commit` 255 | $ git diff --cached [] 256 | ``` 257 | 258 | ```bash 259 | $ git diff 260 | # The changes between two commits 261 | # Commits can be identified with hashes (sha1) or via symbolic name HEAD (explained further) 262 | # If you run `git diff `, see it as: if I am at A and I walk to B, what has changed? 263 | # Running `git diff ` will show a symmetric output 264 | ``` 265 | 266 | --- 267 | 268 | # Compare the git trees (staging area, working directory, commits) 269 | 270 | ```bash 271 | $ git diff 272 | # Compares the modifications in the working directory relatively to a given commit 273 | ``` 274 | 275 | --- 276 | 277 | # Logs 278 | 279 | - Logs let you see the *commit* history over time 280 | - By default, it shows, for each *commit*: 281 | - an id 282 | - the author (name and email) 283 | - date & time 284 | - the message 285 | 286 | ```bash 287 | $ git log 288 | ``` 289 | 290 | --- 291 | 292 | # Logs 293 | ## Customize the output 294 | 295 | - If you wish a more condensed output (the id, first line of the message) 296 | 297 | ```bash 298 | $ git log --oneline 299 | ``` 300 | 301 | - You can see a short brief of the changes introduced by each *commit* 302 | 303 | ```bash 304 | # Which files were modified, and the ammount of insertions and deletions 305 | # IMPORTANT: Changing a line is removing a line and inserting a new one 306 | $ git log --stat 307 | ``` 308 | 309 | --- 310 | 311 | # Logs 312 | ## Customize the output 313 | 314 | - If you want, you can see the actual changes introduced on each *commit* 315 | 316 | ```bash 317 | $ git log -p 318 | ``` 319 | 320 | --- 321 | 322 | # Logs 323 | ## Filtering 324 | 325 | ```bash 326 | # show `N` commits 327 | $ git log -n N 328 | $ git log -N # shortcut 329 | 330 | # dates 331 | $ git log --since="1 week ago" 332 | $ git log --since="17/03/2019 20:00" 333 | $ git log --until="today" 334 | $ git log .. 335 | ``` 336 | 337 | --- 338 | 339 | # Logs 340 | ## Filtering 341 | 342 | ```bash 343 | # author (regular expression) 344 | $ git log --author="fabio" 345 | 346 | # files 347 | $ git log -- hello.c 348 | ``` 349 | 350 | - You can also see the changes of a particular *commit* 351 | 352 | ```bash 353 | $ git show # hash or symbolic names 354 | ``` 355 | 356 | --- 357 | 358 | template: slide_section 359 | 360 | # Git worflow 361 | ## HANDS ON 362 | 363 | --- 364 | 365 | template: slide_section 366 | 367 | # A look into Git Internals 368 | 369 | --- 370 | 371 | layout: false 372 | 373 | # Git internals 374 | 375 | .center[ 376 | ![internal objects](assets/internals-3a.svg) 377 | ] 378 | 379 | --- 380 | 381 | # Git internals 382 | 383 | .center[ 384 | ![internal objects](assets/internals-3b.svg) 385 | ] 386 | 387 | --- 388 | 389 | # Git internals 390 | 391 | .center[ 392 | ![internal objects](assets/internals-3c.svg) 393 | ] 394 | 395 | --- 396 | 397 | template: slide_section 398 | 399 | # Introduction to Git Branches 400 | 401 | --- 402 | 403 | layout: false 404 | 405 | # What is a branch? 406 | ## Abstraction 407 | 408 | - A branch let's you diverge the development of your project 409 | - A branch for a bugfix 410 | - A branch for a new feature 411 | - A branch for testing new ideas 412 | .center[![branches](assets/branch-1.png)] 413 | --- 414 | 415 | # What is a branch? 416 | ## Abstraction 417 | 418 | - Branches tipically have a common node (*commit*) 419 | - You can switch between branches and merge them 420 | - You have the main development branch 421 | - You fix a bug in a separate branch. Then you want to merge in the main branch 422 | 423 | --- 424 | 425 | # What is a branch? 426 | ## How it works in Git 427 | 428 | .flex[ 429 | - A branch is just a pointer to a *commit* 430 | - For example, `master` is pointing for the last *commit* of `master` branch 431 | - Ok, you have multiple branches. **How does Git know at which branch you are**? 432 | - Special symbolic pointer: **HEAD** 433 | - It points to the local branch you are currently on 434 | 435 | ![branch illustration](assets/branch-2.png) 436 | ] 437 | --- 438 | 439 | # Create a new branch 440 | 441 | - Use `branch` command 442 | 443 | ```bash 444 | $ git branch 445 | ``` 446 | 447 | .flex[ 448 | 449 | .div[ 450 | What happens internally? 451 | 452 | 1. A new branch (pointer) is created 453 | 2. Its pointing to the same *commit* as `HEAD` 454 | 3. However, `HEAD` is not updated, it doesn't point to the new branch 455 | ] 456 | 457 | .div[ 458 | ![branch illustration](assets/branch-3.png) 459 | ] 460 | ] 461 | 462 | --- 463 | 464 | # Switching between branches 465 | 466 | In order to switch to a new branch: 467 | 468 | ```bash 469 | $ git checkout 470 | ``` 471 | .flex[ 472 | .div[ 473 | What happens internally? 474 | 475 | 1. `HEAD` is updated. It points to the checked out branch 476 | 2. Working directory is updated 477 | ] 478 | .div[ 479 | ![branch checkout](assets/branch-4.png) 480 | ] 481 | ] 482 | 483 | --- 484 | 485 | # Understanding symbolic HEAD 486 | 487 | - Symbolic name `HEAD` can be used to refer branches, and therefore commits 488 | - `HEAD` itself is pointing to the current checked out branch 489 | - You can use two aditional operators: `^` and `~` 490 | 491 | --- 492 | 493 | # Understanding symbolic HEAD 494 | 495 | .flex[ 496 | .flex-child[ 497 | - `HEAD~1` or `HEAD~`: commit's first parent 498 | - `HEAD~2`: commit's first parent's first parent 499 | - ... 500 | 501 | 502 | - `HEAD^1` or `HEAD^`: commit's first parent 503 | - `HEAD^2`: commit's second parent 504 | - ... 505 | ] 506 | .flex-child[ 507 | ![head operators](assets/head-symbolic.png) 508 | ] 509 | ] 510 | 511 | --- 512 | 513 | # Create branches 514 | ## Alternatives 515 | 516 | If you want to create a branch pointing to a specific *commit* 517 | 518 | ```bash 519 | $ git branch 520 | $ git branch HEAD~n 521 | ``` 522 | 523 | In order to create a new branch and immediately checkout to that branch 524 | 525 | ```bash 526 | $ git checkout –b 527 | $ git checkout –b 528 | $ git checkout –b HEAD~n 529 | ``` 530 | 531 | --- 532 | 533 | # Introduction to merging 534 | 535 | - At some point you will want to merge branches 536 | - Telling Git to merge two branches is easy 537 | - However, it's important to understand how Git does it, and what problems may occur 538 | 539 | 540 | - Scenario: You have a branch `fix-10`, which diverged from `master` 541 | - You want merge the changes from `fix-10` to `master` 542 | 543 | 1. Checkout the branch that we will merge into (in this case, `master`) 544 | 2. Run the command `$ git merge ` (`fix-10` in our example) 545 | 3. Cross fingers 546 | 547 | --- 548 | 549 | # How merging works 550 | 551 | - There are three possible scenarios when you attempt to merge branches 552 | - **Fast-Forward** 553 | - **Non-Fast Forward** 554 | - **Conflict** 555 | 556 | --- 557 | 558 | # How merging works 559 | ## Fast-Forward 560 | 561 | - Git does **fast-forward** when one commit is directly reachable from another one 562 | - This is as simple as moving pointers, no further actions are needed 563 | 564 | .center[![example](assets/branch-5a.svg)] 565 | 566 | --- 567 | 568 | # How merging works 569 | ## Fast-Forward 570 | 571 | 1. We want to merge `new-branch` into `master` 572 | 2. We checkout `master` 573 | 3. `$ git merge new-branch` 574 | 575 | .center[![example](assets/branch-5b.svg)] 576 | 577 | --- 578 | 579 | # How merging works 580 | ## Non-Fast Forward 581 | 582 | - If the two branches being merged diverged at some point, Git can't simply move pointers 583 | - Git finds the common *commit* to both branches 584 | - Will see the changes performed on both branches 585 | - It sees that one or more files were modified, but at different chuncks 586 | - Then, Git can handle this automatically, it uses changes from both branches 587 | 588 | --- 589 | 590 | # How merging works 591 | ## Non-Fast Forward 592 | 593 | .center[![example](assets/branch-5c.svg)] 594 | 595 | --- 596 | 597 | # How merging works 598 | ## Non-Fast Forward 599 | 600 | .center[![example](assets/branch-5d.svg)] 601 | 602 | --- 603 | 604 | # How merging works 605 | ## CONFLICTS 606 | 607 | - Similar to the **non-fast forward scenarion** 608 | - However, the same file was modified on both branches on the same chuncks 609 | - Git doesn't know how to handle this, so it reports a conflict 610 | - The conflict is resolved manually by the user 611 | 612 | --- 613 | 614 | # How merging works 615 | ## CONFLICTS 616 | 617 | .center[![example](assets/branch-5e.svg)] 618 | 619 | --- 620 | 621 | # How merging works 622 | ## CONFLICTS 623 | 624 | - Upon conflict, git will report which files have conflicts 625 | - It inserts delimeters on those files around chuncks with conflicts 626 | 627 | ``` 628 | >>>>>>> master 629 | ... 630 | ======= 631 | ... 632 | <<<<<<< new-branch 633 | ``` 634 | 635 | - You edit the file manually 636 | - When done, stage files with conflicts and commit 637 | 638 | --- 639 | 640 | # Delete branches 641 | 642 | - To delete a local branch: 643 | 644 | ```bash 645 | $ git branch -d 646 | ``` 647 | 648 | - If the branch to be deleted is not totally merged with other branches (data loss), Git aborts the operation. To force, use `-D` 649 | 650 | ```bash 651 | $ git branch -D 652 | ``` 653 | 654 | --- 655 | 656 | template: slide_section 657 | 658 | # Working with remotes 659 | 660 | --- 661 | 662 | layout: false 663 | 664 | # Working with remotes 665 | 666 | - So far, you have worked locally 667 | - If you intend to collaborate with others, you need to host the repository on a server 668 | - Several questions arise: 669 | - How does git know where it should send data? 670 | - Where should it pull data from? How can I get changes done by others? 671 | - How to manage remote branches? 672 | 673 | --- 674 | 675 | # Working with remotes 676 | ## Listing the configured remote servers 677 | 678 | - You can view which remote servers are configured in the repository: 679 | 680 | ```bash 681 | $ git remote 682 | $ git remove -v # more detailed (show urls for Read and Write) 683 | ``` 684 | 685 | - For a repository created locally, the output is most likely empty 686 | 687 | --- 688 | 689 | # Working with remotes 690 | ## Listing the configured remote servers 691 | 692 | - If you clone the repository from GitHub, you will see at least one entry. 693 | - Most likely named **origin** - the default name given to the server you cloned the repository from 694 | 695 | ```bash 696 | $ git clone git@github.com:ieeeupsb/workshop-git.git 697 | $ cd workshop-git/ 698 | $ git remote -v 699 | ``` 700 | 701 | ``` 702 | origin git@github.com:ieeeupsb/workshop-git.git (fetch) 703 | origin git@github.com:ieeeupsb/workshop-git.git (push) 704 | ``` 705 | 706 | --- 707 | 708 | # Working with remotes 709 | ## Listing the configured remote servers 710 | 711 | - You can have several remote configurations 712 | - One configuration for each collaborator, for example 713 | 714 | ```bash 715 | bakkdoor https://github.com/bakkdoor/grit (fetch) 716 | bakkdoor https://github.com/bakkdoor/grit (push) 717 | cho45 https://github.com/cho45/grit (fetch) 718 | cho45 https://github.com/cho45/grit (push) 719 | defunkt https://github.com/defunkt/grit (fetch) 720 | defunkt https://github.com/defunkt/grit (push) 721 | origin git@github.com:mojombo/grit.git (fetch) 722 | origin git@github.com:mojombo/grit.git (push) 723 | ``` 724 | 725 | --- 726 | 727 | # Working with remotes 728 | ## Managing remote repositories 729 | 730 | - You can add new remote configurations: 731 | 732 | ```bash 733 | $ git remote add 734 | ``` 735 | 736 | - Remove them: 737 | 738 | ```bash 739 | $ git remote remove 740 | ``` 741 | 742 | --- 743 | 744 | # Working with remotes 745 | ## Managing remote repositories 746 | 747 | - Rename them: 748 | 749 | ```bash 750 | $ git rename 751 | ``` 752 | - **Remotes** are just a **friendly reference** to the repository URL 753 | - Instead of saying _"Hey Git, send my commits to **git@github.com:ieeeupsb/workshop-git.git**"_ 754 | - ... we say _"Git, send my commits to <**remote**>"_ 755 | 756 | --- 757 | 758 | # Remote branches 759 | 760 | - At this point, you know Git can be configured to communicate with remote repositories 761 | - Git also has **remote references** 762 | - Pointers to branches, tags, ..., on the remote repository 763 | - **Remote-tracking branches** are references to the state of remote branches (local references you can't move) 764 | - Everytime you do any network connection, Git updates the references 765 | 766 | --- 767 | 768 | # Remote branches 769 | 770 | - Remote-tracking branches take the form **<remote>/<branch>** 771 | - E.g. **origin/master** 772 | - In summary we have: 773 | - Local branches 774 | - Remote(-tracking) branches 775 | - A **local branch _can have_ a relationship with a remote branch** 776 | 777 | --- 778 | 779 | # Cloning repositories 780 | 781 | ```bash 782 | # clone a repository from a given URL (git supports several protocols) 783 | # automatically it creates a directory with the repository name 784 | # you can customize if you specify `` 785 | $ git clone [] 786 | 787 | $ git clone git@github.com:ieeeupsb/workshop-git.git example 788 | ``` 789 | 790 | - Clones the repository in a new directory 791 | - Creates remote-tracking branches for each branch in the cloned repository 792 | - Creates and checks out an initial branch (typically `master`) 793 | - You now have a local branch `master` tracking the remote `origin/master` 794 | 795 | --- 796 | 797 | # Pushing 798 | 799 | - You work locally on a branch. How to share it with the world? 800 | - Git doesn't automatically synchronize your local branches to remote branches 801 | - You have to explicitly **push** your changes 802 | 803 | ``` 804 | $ git push 805 | 806 | # You can have a local branch named `hello`, and the remote be `unit-test` 807 | $ git push : 808 | ``` 809 | 810 | --- 811 | 812 | # Fetching 813 | 814 | - Fetch downloads latest changes from the repository 815 | - Commits, files, ... 816 | - Lets you **see what everybody else has been working on** 817 | - It has **no effect on your local content** 818 | - Safe way to review *commits* before integrating them with your local repository 819 | 820 | ``` 821 | # Fetch all branches from the repository pointed by `remote` 822 | $ git fetch 823 | # Fetch a specific branch the repository `remote` 824 | $ git fetch 825 | # Fetch all data from all registered `remotes` 826 | $ git fetch --all 827 | ``` 828 | 829 | --- 830 | 831 | # Pulling 832 | 833 | - It fetches and merges the downloaded changes into your local content 834 | - `$ git fetch` 835 | - `$ git merge` 836 | - It only fetches and merges the local checked out branch (referenced by `HEAD`) 837 | - A merge is performed, can lead to **merge conflicts** 838 | 839 | --- 840 | 841 | # Pulling 842 | 843 | ```bash 844 | # Equivalent to `$ git fetch origin HEAD` 845 | # Followed by `$ git merge HEAD` 846 | $ git pull 847 | 848 | # Equivalent to above, but instead of remote `origin` use `` 849 | $ git pull 850 | 851 | # Fetches the remote branch /... 852 | # ... and merges to current branch `HEAD` 853 | $ git pull 854 | ``` 855 | 856 | --- 857 | 858 | # Tracking branches 859 | 860 | - A **local branch** can be configured to **track a remote branch** 861 | - This simplifies the previous operations 862 | - No longer have to specify the `remote` and `branch` fields 863 | 864 | 865 | - Lets say you tell Git _"The local branch `a` tracks the remote branch `origin/b`"_ 866 | - Now assume you are the at branch `a` 867 | - Operations such `pull`, `push` and `fetch` will get/send data to `origin/b` automatically 868 | 869 | --- 870 | 871 | # Tracking branches 872 | ## Configuration 873 | 874 | - At any time, you can change what remote branch a local branch is tracking 875 | 876 | ```bash 877 | $ git branch --set-upstream-to=/ [] 878 | $ git branch -u / [] 879 | ``` 880 | 881 | - **Tip**: Use `git branch -vv` to check relationship of local branches with remote ones 882 | 883 | --- 884 | 885 | # Tracking branches 886 | ## Configuration 887 | 888 | - For example, for the remote `origin`, remote branch `dev` and local branch `development`: 889 | 890 | ```bash 891 | $ git branch -u origin/dev development 892 | 893 | # If you are at the development branch, you can ommit the local branch name 894 | $ git branch -u origin/dev 895 | ``` 896 | 897 | - This configuration is possible if and only if the remote branch already exists 898 | - You may need to use `$ git fetch --all` to update remote references 899 | 900 | --- 901 | 902 | # Examples 903 | ## Create a new remote branch 904 | 905 | - Imagine you have a local branch `issue-12` with some work 906 | - How to create a remote branch `issue-12` so that other collaborators can access your work? 907 | 908 | ``` 909 | $ git push -u / 910 | ``` 911 | 912 | --- 913 | 914 | # Examples 915 | ## Working on a remote branch 916 | 917 | - You can't directly work on remote branches 918 | - You need to have a local branch which is tracking that remote branch 919 | 920 | **Method 1** 921 | - Create the local branch with `git branch` 922 | - Ensure you have the reference for the remote branch with `git branch -r` 923 | - Settup the upstream of the new branch with `$ git branch -u /` 924 | - Run `git pull` to merge remote branch with your local branch 925 | 926 | --- 927 | 928 | # Examples 929 | ## Working on a remote branch 930 | 931 | **Method 2** 932 | - Use the following commands 933 | - They create a local branch which is already tracking the desired remote branch 934 | - Examples assume you have local references for the remote branch 935 | 936 | --- 937 | 938 | # Examples 939 | ## Working on a remote branch 940 | 941 | ```bash 942 | $ git checkout -b / 943 | # shortcut for above (local branch with same name as the remote one) 944 | $ git checkout --track / 945 | # shortcut for the shortcut 946 | # works if: 947 | # a) the branch doesn't exist locally 948 | # b) matches a name of a single remote's branch 949 | $ git checkout 950 | ``` 951 | 952 | --- 953 | 954 | # Examples 955 | ## Delete a remote branch 956 | 957 | - Scenario: you have a local branch `A` tracking the remote branch `remote-A` 958 | - You delete your local branch `A` 959 | - The remote branch is not affected 960 | 961 | 962 | - If you really want to delete the remote branch, use: 963 | 964 | ```bash 965 | $ git push --delete 966 | ``` 967 | -------------------------------------------------------------------------------- /slides/00-template.md: -------------------------------------------------------------------------------- 1 | name: slide_title 2 | class: slide_title, center, middle 3 | layout: true 4 | 5 | {{content}} 6 | 7 |
8 | nuieee-logo 9 | cs-logo 10 |
11 | 12 | --- 13 | 14 | name: slide_section 15 | class: slide_section, center, middle 16 | layout: true 17 | 18 | {{content}} 19 | -------------------------------------------------------------------------------- /slides/01_git_introduction.md: -------------------------------------------------------------------------------- 1 | template: slide_title 2 | layout: false 3 | 4 | # Workshop Introduction to Git 5 | 6 | --- 7 | 8 | template: slide_section 9 | 10 | # Version controls 11 | 12 | --- 13 | 14 | layout: false 15 | 16 | # Version control 17 | 18 | - System that **tracks** one or more files over time 19 | - Lets you check the files state on the past 20 | - In theory any file can be tracked 21 | - However, some **features** are **only** possible in **text files** 22 | - Tracking very **large files can slow things down** 23 | - **Git** is **not the first source version control**, there are many 24 | - However, **developers are more happy with Git** than anything else 25 | 26 | --- 27 | 28 | # Version controls: types 29 | ## LCVS 30 | 31 | - Local Version Control Systems (LCVS) 32 | - **Local** repository 33 | - Doesn't allow collaborative work 34 | - Not pratical if you want to work on multiple devices 35 | 36 | --- 37 | 38 | # Version Controls: types 39 | ## CVCS 40 | 41 | - Centralized Version Control Systems (CVCS) 42 | - Repository is hosted in one or more servers 43 | - Clients download one version of the repository, work over it, then send it to the server 44 | - All operations are online (network overhead, can't work offline) 45 | - Not really realiable 46 | - What if the server is down? 47 | - What if there's an accident with physical damage in the servers? 48 | - Example: SVN, Perforce 49 | 50 | --- 51 | 52 | # Version Controls: types 53 | ## DVCS 54 | 55 | - Distributed Version Control Systems (DVCS) 56 | - Repository hosted in one or more servers (like CVCS) 57 | - Clients have a full repository copy 58 | - Most operations are local 59 | - Fast 60 | - No internet connection is needed 61 | - Examples: **Git**, Mercurial 62 | - May take several disk time and require several time for downloading and uploading new versions if: 63 | - Very long history 64 | - Very large binary files 65 | 66 | --- 67 | 68 | template: slide_section 69 | 70 | # Setting up Git 71 | 72 | --- 73 | 74 | layout: false 75 | 76 | # Installing 77 | 78 | - Windows: [https://git-scm.com/download/win](https://git-scm.com/download/win) 79 | - Mac: [https://git-scm.com/download/mac](https://git-scm.com/download/mac) 80 | - Linux: [https://git-scm.com/download/linux](https://git-scm.com/download/linux) 81 | 82 | --- 83 | 84 | # Initial configuration 85 | 86 | - Changes on the repository are identified by the author with a name and email 87 | - Global configuration 88 | 89 | ```bash 90 | $ git config --global user.name "example" 91 | $ git config --global user.email "example@ieee.com" 92 | ``` 93 | 94 | - Repository configuration (*overrides* global configurations) 95 | 96 | ```bash 97 | $ git config user.name "example" 98 | $ git config user.email "example@ieee.com" 99 | ``` 100 | -------------------------------------------------------------------------------- /slides/02_git_workflow.md: -------------------------------------------------------------------------------- 1 | template: slide_section 2 | 3 | # Git workflow 4 | ## Work. Stage. Commit. Repeat! 5 | 6 | --- 7 | 8 | layout: false 9 | 10 | # Git worflow 11 | ## The three sections/trees 12 | 13 | .center[ 14 | ![git trees](assets/workflow.svg) 15 | ] 16 | 17 | --- 18 | 19 | # Creating new local repositories 20 | 21 | - Create a new empty repository with `init` command. 22 | - Can be applied in empty or non-empty directories 23 | - Git won't initialize the reposity in either case 24 | - No files are automatically tracked 25 | - A new hidden directory **.git** is created 26 | - Repository configurations 27 | - Data 28 | 29 | --- 30 | 31 | # Creating new local repositories 32 | 33 | ```bash 34 | # create an empty directory 35 | $ mkdir workshop-git 36 | # go inside that directory 37 | $ cd workshop-git/ 38 | # initialize empty repository 39 | $ git init 40 | ``` 41 | 42 | --- 43 | 44 | # Staging 45 | 46 | - You edit and create files in your working directory 47 | - Next step is to stage 48 | - The **add** command creates a new snapshot of the current file(s) content 49 | - Whatever **snapshots** you create, that **are what will be added to the repository when you *commit*** 50 | - Staging is an intermidiate phase between what you do in the working directory and what will be recorded in the repository/database 51 | 52 | --- 53 | 54 | # Staging 55 | 56 | ```bash 57 | # add specific file 58 | $ git add 59 | # add everything (new | modified | deleted) 60 | $ git add . 61 | # add everything (new | modified | deleted) 62 | $ git add -A 63 | # add already-tracked files (modified | deleted) 64 | $ git add -u 65 | ``` 66 | 67 | --- 68 | 69 | # Commit 70 | 71 | - The *commit* act takes the new snapshots and stores them "permantely" in the database 72 | - Each *commit* has an author and message 73 | - The author depends on your global and local configurations (name + email) 74 | 75 | ```bash 76 | $ git commit -m "message" 77 | ``` 78 | 79 | - You can stage and *commit* with the following shortcut 80 | - Only known files (modified or deleted) are taken into account 81 | 82 | ```bash 83 | $ git commit -a -m "message" 84 | $ git commit -am "message" 85 | ``` 86 | 87 | --- 88 | 89 | template: slide_section 90 | 91 | # Useful Git commands 92 | 93 | --- 94 | 95 | layout: false 96 | 97 | # Status 98 | 99 | - The `status` command shows a summary of: 100 | - modified files 101 | - **staged** files (a snapshot for file was created) 102 | - new files, **untracked** 103 | - The same file can be modified and staged. Why? 104 | 105 | ```bash 106 | $ git status 107 | ``` 108 | 109 | --- 110 | 111 | # Compare the git trees (staging area, working directory, commits) 112 | 113 | - The `diff` command show changes between: 114 | - two commits 115 | - commits and the working directory 116 | - ... 117 | 118 | ```bash 119 | # compare the working directory with staging area 120 | # what would be staged if you run `git add` 121 | $ git diff 122 | ``` 123 | 124 | --- 125 | 126 | # Compare the git trees (staging area, working directory, commits) 127 | 128 | ```bash 129 | # Compare the changes which are staged relative to a given 130 | # If the is not given, it compares with the last commit 131 | # It shows what changes will be recorded if you run `git commit` 132 | $ git diff --cached [] 133 | ``` 134 | 135 | ```bash 136 | $ git diff 137 | # The changes between two commits 138 | # Commits can be identified with hashes (sha1) or via symbolic name HEAD (explained further) 139 | # If you run `git diff
`, see it as: if I am at A and I walk to B, what has changed? 140 | # Running `git diff ` will show a symmetric output 141 | ``` 142 | 143 | --- 144 | 145 | # Compare the git trees (staging area, working directory, commits) 146 | 147 | ```bash 148 | $ git diff 149 | # Compares the modifications in the working directory relatively to a given commit 150 | ``` 151 | 152 | --- 153 | 154 | # Logs 155 | 156 | - Logs let you see the *commit* history over time 157 | - By default, it shows, for each *commit*: 158 | - an id 159 | - the author (name and email) 160 | - date & time 161 | - the message 162 | 163 | ```bash 164 | $ git log 165 | ``` 166 | 167 | --- 168 | 169 | # Logs 170 | ## Customize the output 171 | 172 | - If you wish a more condensed output (the id, first line of the message) 173 | 174 | ```bash 175 | $ git log --oneline 176 | ``` 177 | 178 | - You can see a short brief of the changes introduced by each *commit* 179 | 180 | ```bash 181 | # Which files were modified, and the ammount of insertions and deletions 182 | # IMPORTANT: Changing a line is removing a line and inserting a new one 183 | $ git log --stat 184 | ``` 185 | 186 | --- 187 | 188 | # Logs 189 | ## Customize the output 190 | 191 | - If you want, you can see the actual changes introduced on each *commit* 192 | 193 | ```bash 194 | $ git log -p 195 | ``` 196 | 197 | --- 198 | 199 | # Logs 200 | ## Filtering 201 | 202 | ```bash 203 | # show `N` commits 204 | $ git log -n N 205 | $ git log -N # shortcut 206 | 207 | # dates 208 | $ git log --since="1 week ago" 209 | $ git log --since="17/03/2019 20:00" 210 | $ git log --until="today" 211 | $ git log .. 212 | ``` 213 | 214 | --- 215 | 216 | # Logs 217 | ## Filtering 218 | 219 | ```bash 220 | # author (regular expression) 221 | $ git log --author="fabio" 222 | 223 | # files 224 | $ git log -- hello.c 225 | ``` 226 | 227 | - You can also see the changes of a particular *commit* 228 | 229 | ```bash 230 | $ git show # hash or symbolic names 231 | ``` 232 | 233 | --- 234 | 235 | template: slide_section 236 | 237 | # Git worflow 238 | ## HANDS ON 239 | -------------------------------------------------------------------------------- /slides/03_git_internals.md: -------------------------------------------------------------------------------- 1 | template: slide_section 2 | 3 | # A look into Git Internals 4 | 5 | --- 6 | 7 | layout: false 8 | 9 | # Git internals 10 | 11 | .center[ 12 | ![internal objects](assets/internals-3a.svg) 13 | ] 14 | 15 | --- 16 | 17 | # Git internals 18 | 19 | .center[ 20 | ![internal objects](assets/internals-3b.svg) 21 | ] 22 | 23 | --- 24 | 25 | # Git internals 26 | 27 | .center[ 28 | ![internal objects](assets/internals-3c.svg) 29 | ] 30 | -------------------------------------------------------------------------------- /slides/04_git_merge.md: -------------------------------------------------------------------------------- 1 | template: slide_section 2 | 3 | # Introduction to Git Branches 4 | 5 | --- 6 | 7 | layout: false 8 | 9 | # What is a branch? 10 | ## Abstraction 11 | 12 | - A branch let's you diverge the development of your project 13 | - A branch for a bugfix 14 | - A branch for a new feature 15 | - A branch for testing new ideas 16 | .center[![branches](assets/branch-1.png)] 17 | --- 18 | 19 | # What is a branch? 20 | ## Abstraction 21 | 22 | - Branches tipically have a common node (*commit*) 23 | - You can switch between branches and merge them 24 | - You have the main development branch 25 | - You fix a bug in a separate branch. Then you want to merge in the main branch 26 | 27 | --- 28 | 29 | # What is a branch? 30 | ## How it works in Git 31 | 32 | .flex[ 33 | - A branch is just a pointer to a *commit* 34 | - For example, `master` is pointing for the last *commit* of `master` branch 35 | - Ok, you have multiple branches. **How does Git know at which branch you are**? 36 | - Special symbolic pointer: **HEAD** 37 | - It points to the local branch you are currently on 38 | 39 | ![branch illustration](assets/branch-2.png) 40 | ] 41 | --- 42 | 43 | # Create a new branch 44 | 45 | - Use `branch` command 46 | 47 | ```bash 48 | $ git branch 49 | ``` 50 | 51 | .flex[ 52 | 53 | .div[ 54 | What happens internally? 55 | 56 | 1. A new branch (pointer) is created 57 | 2. Its pointing to the same *commit* as `HEAD` 58 | 3. However, `HEAD` is not updated, it doesn't point to the new branch 59 | ] 60 | 61 | .div[ 62 | ![branch illustration](assets/branch-3.png) 63 | ] 64 | ] 65 | 66 | --- 67 | 68 | # Switching between branches 69 | 70 | In order to switch to a new branch: 71 | 72 | ```bash 73 | $ git checkout 74 | ``` 75 | .flex[ 76 | .div[ 77 | What happens internally? 78 | 79 | 1. `HEAD` is updated. It points to the checked out branch 80 | 2. Working directory is updated 81 | ] 82 | .div[ 83 | ![branch checkout](assets/branch-4.png) 84 | ] 85 | ] 86 | 87 | --- 88 | 89 | # Understanding symbolic HEAD 90 | 91 | - Symbolic name `HEAD` can be used to refer branches, and therefore commits 92 | - `HEAD` itself is pointing to the current checked out branch 93 | - You can use two aditional operators: `^` and `~` 94 | 95 | --- 96 | 97 | # Understanding symbolic HEAD 98 | 99 | .flex[ 100 | .flex-child[ 101 | - `HEAD~1` or `HEAD~`: commit's first parent 102 | - `HEAD~2`: commit's first parent's first parent 103 | - ... 104 | 105 | 106 | - `HEAD^1` or `HEAD^`: commit's first parent 107 | - `HEAD^2`: commit's second parent 108 | - ... 109 | ] 110 | .flex-child[ 111 | ![head operators](assets/head-symbolic.png) 112 | ] 113 | ] 114 | 115 | --- 116 | 117 | # Create branches 118 | ## Alternatives 119 | 120 | If you want to create a branch pointing to a specific *commit* 121 | 122 | ```bash 123 | $ git branch 124 | $ git branch HEAD~n 125 | ``` 126 | 127 | In order to create a new branch and immediately checkout to that branch 128 | 129 | ```bash 130 | $ git checkout –b 131 | $ git checkout –b 132 | $ git checkout –b HEAD~n 133 | ``` 134 | 135 | --- 136 | 137 | # Introduction to merging 138 | 139 | - At some point you will want to merge branches 140 | - Telling Git to merge two branches is easy 141 | - However, it's important to understand how Git does it, and what problems may occur 142 | 143 | 144 | - Scenario: You have a branch `fix-10`, which diverged from `master` 145 | - You want merge the changes from `fix-10` to `master` 146 | 147 | 1. Checkout the branch that we will merge into (in this case, `master`) 148 | 2. Run the command `$ git merge ` (`fix-10` in our example) 149 | 3. Cross fingers 150 | 151 | --- 152 | 153 | # How merging works 154 | 155 | - There are three possible scenarios when you attempt to merge branches 156 | - **Fast-Forward** 157 | - **Non-Fast Forward** 158 | - **Conflict** 159 | 160 | --- 161 | 162 | # How merging works 163 | ## Fast-Forward 164 | 165 | - Git does **fast-forward** when one commit is directly reachable from another one 166 | - This is as simple as moving pointers, no further actions are needed 167 | 168 | .center[![example](assets/branch-5a.svg)] 169 | 170 | --- 171 | 172 | # How merging works 173 | ## Fast-Forward 174 | 175 | 1. We want to merge `new-branch` into `master` 176 | 2. We checkout `master` 177 | 3. `$ git merge new-branch` 178 | 179 | .center[![example](assets/branch-5b.svg)] 180 | 181 | --- 182 | 183 | # How merging works 184 | ## Non-Fast Forward 185 | 186 | - If the two branches being merged diverged at some point, Git can't simply move pointers 187 | - Git finds the common *commit* to both branches 188 | - Will see the changes performed on both branches 189 | - It sees that one or more files were modified, but at different chuncks 190 | - Then, Git can handle this automatically, it uses changes from both branches 191 | 192 | --- 193 | 194 | # How merging works 195 | ## Non-Fast Forward 196 | 197 | .center[![example](assets/branch-5c.svg)] 198 | 199 | --- 200 | 201 | # How merging works 202 | ## Non-Fast Forward 203 | 204 | .center[![example](assets/branch-5d.svg)] 205 | 206 | --- 207 | 208 | # How merging works 209 | ## CONFLICTS 210 | 211 | - Similar to the **non-fast forward scenarion** 212 | - However, the same file was modified on both branches on the same chuncks 213 | - Git doesn't know how to handle this, so it reports a conflict 214 | - The conflict is resolved manually by the user 215 | 216 | --- 217 | 218 | # How merging works 219 | ## CONFLICTS 220 | 221 | .center[![example](assets/branch-5e.svg)] 222 | 223 | --- 224 | 225 | # How merging works 226 | ## CONFLICTS 227 | 228 | - Upon conflict, git will report which files have conflicts 229 | - It inserts delimeters on those files around chuncks with conflicts 230 | 231 | ``` 232 | >>>>>>> master 233 | ... 234 | ======= 235 | ... 236 | <<<<<<< new-branch 237 | ``` 238 | 239 | - You edit the file manually 240 | - When done, stage files with conflicts and commit 241 | 242 | --- 243 | 244 | # Delete branches 245 | 246 | - To delete a local branch: 247 | 248 | ```bash 249 | $ git branch -d 250 | ``` 251 | 252 | - If the branch to be deleted is not totally merged with other branches (data loss), Git aborts the operation. To force, use `-D` 253 | 254 | ```bash 255 | $ git branch -D 256 | ``` 257 | -------------------------------------------------------------------------------- /slides/05_git_remote.md: -------------------------------------------------------------------------------- 1 | template: slide_section 2 | 3 | # Working with remotes 4 | 5 | --- 6 | 7 | layout: false 8 | 9 | # Working with remotes 10 | 11 | - So far, you have worked locally 12 | - If you intend to collaborate with others, you need to host the repository on a server 13 | - Several questions arise: 14 | - How does git know where it should send data? 15 | - Where should it pull data from? How can I get changes done by others? 16 | - How to manage remote branches? 17 | 18 | --- 19 | 20 | # Working with remotes 21 | ## Listing the configured remote servers 22 | 23 | - You can view which remote servers are configured in the repository: 24 | 25 | ```bash 26 | $ git remote 27 | $ git remove -v # more detailed (show urls for Read and Write) 28 | ``` 29 | 30 | - For a repository created locally, the output is most likely empty 31 | 32 | --- 33 | 34 | # Working with remotes 35 | ## Listing the configured remote servers 36 | 37 | - If you clone the repository from GitHub, you will see at least one entry. 38 | - Most likely named **origin** - the default name given to the server you cloned the repository from 39 | 40 | ```bash 41 | $ git clone git@github.com:ieeeupsb/workshop-git.git 42 | $ cd workshop-git/ 43 | $ git remote -v 44 | ``` 45 | 46 | ``` 47 | origin git@github.com:ieeeupsb/workshop-git.git (fetch) 48 | origin git@github.com:ieeeupsb/workshop-git.git (push) 49 | ``` 50 | 51 | --- 52 | 53 | # Working with remotes 54 | ## Listing the configured remote servers 55 | 56 | - You can have several remote configurations 57 | - One configuration for each collaborator, for example 58 | 59 | ```bash 60 | bakkdoor https://github.com/bakkdoor/grit (fetch) 61 | bakkdoor https://github.com/bakkdoor/grit (push) 62 | cho45 https://github.com/cho45/grit (fetch) 63 | cho45 https://github.com/cho45/grit (push) 64 | defunkt https://github.com/defunkt/grit (fetch) 65 | defunkt https://github.com/defunkt/grit (push) 66 | origin git@github.com:mojombo/grit.git (fetch) 67 | origin git@github.com:mojombo/grit.git (push) 68 | ``` 69 | 70 | --- 71 | 72 | # Working with remotes 73 | ## Managing remote repositories 74 | 75 | - You can add new remote configurations: 76 | 77 | ```bash 78 | $ git remote add 79 | ``` 80 | 81 | - Remove them: 82 | 83 | ```bash 84 | $ git remote remove 85 | ``` 86 | 87 | --- 88 | 89 | # Working with remotes 90 | ## Managing remote repositories 91 | 92 | - Rename them: 93 | 94 | ```bash 95 | $ git rename 96 | ``` 97 | - **Remotes** are just a **friendly reference** to the repository URL 98 | - Instead of saying _"Hey Git, send my commits to **git@github.com:ieeeupsb/workshop-git.git**"_ 99 | - ... we say _"Git, send my commits to <**remote**>"_ 100 | 101 | --- 102 | 103 | # Remote branches 104 | 105 | - At this point, you know Git can be configured to communicate with remote repositories 106 | - Git also has **remote references** 107 | - Pointers to branches, tags, ..., on the remote repository 108 | - **Remote-tracking branches** are references to the state of remote branches (local references you can't move) 109 | - Everytime you do any network connection, Git updates the references 110 | 111 | --- 112 | 113 | # Remote branches 114 | 115 | - Remote-tracking branches take the form **<remote>/<branch>** 116 | - E.g. **origin/master** 117 | - In summary we have: 118 | - Local branches 119 | - Remote(-tracking) branches 120 | - A **local branch _can have_ a relationship with a remote branch** 121 | 122 | --- 123 | 124 | # Cloning repositories 125 | 126 | ```bash 127 | # clone a repository from a given URL (git supports several protocols) 128 | # automatically it creates a directory with the repository name 129 | # you can customize if you specify `` 130 | $ git clone [] 131 | 132 | $ git clone git@github.com:ieeeupsb/workshop-git.git example 133 | ``` 134 | 135 | - Clones the repository in a new directory 136 | - Creates remote-tracking branches for each branch in the cloned repository 137 | - Creates and checks out an initial branch (typically `master`) 138 | - You now have a local branch `master` tracking the remote `origin/master` 139 | 140 | --- 141 | 142 | # Pushing 143 | 144 | - You work locally on a branch. How to share it with the world? 145 | - Git doesn't automatically synchronize your local branches to remote branches 146 | - You have to explicitly **push** your changes 147 | 148 | ``` 149 | $ git push 150 | 151 | # You can have a local branch named `hello`, and the remote be `unit-test` 152 | $ git push : 153 | ``` 154 | 155 | --- 156 | 157 | # Fetching 158 | 159 | - Fetch downloads latest changes from the repository 160 | - Commits, files, ... 161 | - Lets you **see what everybody else has been working on** 162 | - It has **no effect on your local content** 163 | - Safe way to review *commits* before integrating them with your local repository 164 | 165 | ``` 166 | # Fetch all branches from the repository pointed by `remote` 167 | $ git fetch 168 | # Fetch a specific branch the repository `remote` 169 | $ git fetch 170 | # Fetch all data from all registered `remotes` 171 | $ git fetch --all 172 | ``` 173 | 174 | --- 175 | 176 | # Pulling 177 | 178 | - It fetches and merges the downloaded changes into your local content 179 | - `$ git fetch` 180 | - `$ git merge` 181 | - It only fetches and merges the local checked out branch (referenced by `HEAD`) 182 | - A merge is performed, can lead to **merge conflicts** 183 | 184 | --- 185 | 186 | # Pulling 187 | 188 | ```bash 189 | # Equivalent to `$ git fetch origin HEAD` 190 | # Followed by `$ git merge HEAD` 191 | $ git pull 192 | 193 | # Equivalent to above, but instead of remote `origin` use `` 194 | $ git pull 195 | 196 | # Fetches the remote branch /... 197 | # ... and merges to current branch `HEAD` 198 | $ git pull 199 | ``` 200 | 201 | --- 202 | 203 | # Tracking branches 204 | 205 | - A **local branch** can be configured to **track a remote branch** 206 | - This simplifies the previous operations 207 | - No longer have to specify the `remote` and `branch` fields 208 | 209 | 210 | - Lets say you tell Git _"The local branch `a` tracks the remote branch `origin/b`"_ 211 | - Now assume you are the at branch `a` 212 | - Operations such `pull`, `push` and `fetch` will get/send data to `origin/b` automatically 213 | 214 | --- 215 | 216 | # Tracking branches 217 | ## Configuration 218 | 219 | - At any time, you can change what remote branch a local branch is tracking 220 | 221 | ```bash 222 | $ git branch --set-upstream-to=/ [] 223 | $ git branch -u / [] 224 | ``` 225 | 226 | - **Tip**: Use `git branch -vv` to check relationship of local branches with remote ones 227 | 228 | --- 229 | 230 | # Tracking branches 231 | ## Configuration 232 | 233 | - For example, for the remote `origin`, remote branch `dev` and local branch `development`: 234 | 235 | ```bash 236 | $ git branch -u origin/dev development 237 | 238 | # If you are at the development branch, you can ommit the local branch name 239 | $ git branch -u origin/dev 240 | ``` 241 | 242 | - This configuration is possible if and only if the remote branch already exists 243 | - You may need to use `$ git fetch --all` to update remote references 244 | 245 | --- 246 | 247 | # Examples 248 | ## Create a new remote branch 249 | 250 | - Imagine you have a local branch `issue-12` with some work 251 | - How to create a remote branch `issue-12` so that other collaborators can access your work? 252 | 253 | ``` 254 | $ git push -u / 255 | ``` 256 | 257 | --- 258 | 259 | # Examples 260 | ## Working on a remote branch 261 | 262 | - You can't directly work on remote branches 263 | - You need to have a local branch which is tracking that remote branch 264 | 265 | **Method 1** 266 | - Create the local branch with `git branch` 267 | - Ensure you have the reference for the remote branch with `git branch -r` 268 | - Settup the upstream of the new branch with `$ git branch -u /` 269 | - Run `git pull` to merge remote branch with your local branch 270 | 271 | --- 272 | 273 | # Examples 274 | ## Working on a remote branch 275 | 276 | **Method 2** 277 | - Use the following commands 278 | - They create a local branch which is already tracking the desired remote branch 279 | - Examples assume you have local references for the remote branch 280 | 281 | --- 282 | 283 | # Examples 284 | ## Working on a remote branch 285 | 286 | ```bash 287 | $ git checkout -b / 288 | # shortcut for above (local branch with same name as the remote one) 289 | $ git checkout --track / 290 | # shortcut for the shortcut 291 | # works if: 292 | # a) the branch doesn't exist locally 293 | # b) matches a name of a single remote's branch 294 | $ git checkout 295 | ``` 296 | 297 | --- 298 | 299 | # Examples 300 | ## Delete a remote branch 301 | 302 | - Scenario: you have a local branch `A` tracking the remote branch `remote-A` 303 | - You delete your local branch `A` 304 | - The remote branch is not affected 305 | 306 | 307 | - If you really want to delete the remote branch, use: 308 | 309 | ```bash 310 | $ git push --delete 311 | ``` 312 | -------------------------------------------------------------------------------- /slides/merge-slides.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | shopt -s nullglob 3 | 4 | array=(*.md) 5 | a_size=${#array[@]} 6 | 7 | apost=\' 8 | 9 | for ((i = 0; i < a_size; ++i)); do 10 | if [[ i -eq a_size-1 ]]; then 11 | sed 's/src="..\//src="/g; s/src='$apost'..\//src='$apost'/g' ${array[$i]} >> main 12 | break 13 | fi 14 | sed 's/src="..\//src="/g; s/src='$apost'..\//src='$apost'/g' ${array[$i]} >> main 15 | echo -e "\n---\n" >> main 16 | done 17 | 18 | mv main ../main.md 19 | --------------------------------------------------------------------------------