class: center, middle # Git: the bare minimum [Nicolas Rinaudo] • [@NicolasRinaudo@functional.cafe] --- class: center, middle # Vocabulary --- ## Important terms * `commit` ??? * `commit`: state of the project at a given point in time -- * `repository` ??? * `repository`: set of commits representing the history of a project, where a project is a set of file -- * `branch` ??? * `branch`: active line of development, the last commit having a permanent alias to HEAD -- * `remote` ??? * `remote`: version of the repository hosted somewhere else (might be a different directory on the same computer) -- * `staging area` ??? * `staging area`: list of modifications selected for inclusion in a commit -- * `tag` ??? * `tag`: named commit -- (See [https://git-scm.com/docs/gitglossary](https://git-scm.com/docs/gitglossary)) --- class: center, middle # Preparing to work --- ## Retrieving a remote repository * retrieving it for the first time ```console $ git clone [URI] ``` -- * updating a local version ```console $ git pull ``` ??? `git pull` is dangerous, as it will not only fetch differences (`git fetch`) but also attempt to merge them (`git merge`). There are various options to make it safer (such as `--ff-only`). In theory, you should only `pull` from `master`, which you're not allowed to change locally. --- ## Branching out * step-by-step ```console $ git branch [BRANCH] $ git checkout [BRANCH] ``` -- * shortcut ```console $ git checkout -b [BRANCH] ``` --- ## Exercise * clone repository https://github.com/nrinaudo/workshop-minimum-git.git -- * branch out to your name, eg `nicolas.rinaudo` --- ## Check your work ```console $ git branch ``` 2 branches, `master` and yours (flagged as the current one) ```console $ git diff ``` Empty --- class: center, middle # Basic modifications --- ## Staging modifications * staging a file: ```console $ git add [FILE] ``` -- * deleting a file: ```console $ git rm [FILE] ``` -- * renaming a file: ```console $ git mv [FILE] [NEW_FILE] ``` --- ## Pre-commit health check * status of staging area / non-staged modifications: ```console $ git status ``` -- * staged changes: ```console $ git diff --staged ``` -- * non-staged changes: ```console $ git diff ``` --- ## Commiting your work ```console $ git commit ``` --- ## Post-commit health check * commited changes: ```console $ git show ``` -- * Summarised differences: ```console $ git show --summary $ git show --stat ``` -- * Commit list: ```console $ git log ``` --- ## Exercise * delete `DELETEME.md` -- * move `MOVEME.md` to `MOVED.md` -- * create `README.md` ```plaintext FOO BAR BAZ ``` -- * commit your work --- ## Check your work * compare with tag `basic_modifications`: ```console $ git diff basic_modifications ``` * 3 commits in the log * no diff, staged or non-staged --- class: center, middle # Selective modifications --- ## Patching * Staging parts of a file: ```console $ git add -p [FILE] ``` -- * Possible actions on each atomical change (_hunk_): * `y`: stage it -- * `a`: stage all -- * `n`: do not stage it -- * `q`: do not stage it, nor any subsequent one -- * `s`: split it --- ## Exercise * edit `README.md` to contain: * _hint_: note the obvious typo on the last line ```plaintext foo bar baZ ``` -- * stage the first paragraph only * _hint_: don't worry if you made a mistake, we'll fix that in the next section --- ## Check your work * no new commit * staged changes: first line lower-cased * non-staged changes: second and third line lower-cased --- class: center, middle # Fixing things before a commit --- ## Unstaging * a file: ```console $ git reset [FILE] ``` -- * part(s) of a file: ```console $ git reset -p [FILE] ``` --- ## Exercise * stage all modifications of `README.md` -- * create one commit per modified paragraph * _hint_: do not hesitate to play around with `reset` --- ## Check your work * compare with tag `fixing_things_before_commit` * 6 commits in the logs * no staged or non-staged modifications --- class: center, middle # Fixing things: in the last commit --- ## Amending the last commit ```console $ git commit --amend ``` --- ## Exercise * fix the last commit so that `README.md` is: ```plaintext foo bar baz ``` --- ## Check your work * compare with tag `fixing_things_last_commit` * 6 commits in the logs * no staged or non-staged modifications --- class: center, middle # Fixing things: older commits (not yet pushed) --- ## Interactive rebasing ```console $ git rebase -i [REF] ``` Where `[REF]` is a reference to *the parent* of the oldest commit you want to edit. For example: * `master` * `cf69ed7` * `HEAD~2` --- ## Interactive rebasing Allows you to: -- * delete one or more commits -- * re-order commits -- * merge ("squash") commits -- * edit commits -- * update a commit's message --- ### Safety net * tag the current state ```console $ git tag QUICKSAVE ``` -- * do the rebase -- * if the result is not what you wanted, restore the saved state ```console $ git reset --hard QUICKSAVE ``` -- * otherwise, delete the tag ```console $ git tag -d QUICKSAVE ``` --- ### Aborting While in the process of rebasing, you can always abort ```console $ git rebase --abort ``` --- class: center, middle # Merging commits --- ### Merging commits * rebase interactively -- * reorder things so that the commits to merge are adjacent -- * `squash` or `fixup` the "youngest" commit --- ## Exercise * create a new commit with `README.md`: ```plaintext foo2 bar2 baz2 ``` -- * merge the 3 commits that lower case the content of `README.md` * _hint_: don't hesitate to play with `fixup` and `squash` * _hint_: don't hesitate to tag before attempting the rebase --- ## Check your work * compare with tag `merging_commits` * 5 commits in the logs * no staged or non-staged modifications --- class: center, middle # Changing a commit message --- ## Changing a commit message * rebase interactively -- * `reword` the desired commit(s) --- ## Exercise * update the "lower case" commit's message --- ## Check your work * compare with tag `merging_commits` * check your log message --- class: center, middle # Fixing existing commits --- ## Fixing an existing commit * rebase interactively and `edit` that commit -- * stage your fixes -- * `amend` the last commit -- * run `git rebase --continue` --- ## Splitting an existing commit * rebase interactively and `edit` that commit -- * `reset` the desired file to the previous commit's state: ```console $ git reset HEAD~1 [FILE] ``` -- * stage and commit your various changesets, amending when necessary -- * run `git rebase --continue` --- ## Exercise * split the second to last commit (_lowercase_) into 3, one per paragraph --- ## Check your work * compare with tag `fixing_existing_commits` * 7 commits in the logs * no staged or non-staged modifications --- class: center, middle # Dropping a commit --- ## Dropping a commit * rebase interactively -- * remove the commit from the list --- ## Exercise * drop the last commit --- ## Check your work * compare with tag `dropping_commits` * 6 commits in the logs * no staged or non-staged modifications --- class: center, middle # Sharing your work --- ## Syncing with `origin` * Make sure your version of `master` is up to date ```console $ git checkout master $ git pull $ git checkout [BRANCH] ``` -- * Incorporate changes ```console $ git rebase master ``` --- ## Publishing your work * For the first time: ```console $ git push --set-upstream origin [BRANCH] ``` -- * Once the upstream has been set: ```console $ git push ``` -- * If you've modified commits rather than just added some: ```console $ git push -f ``` --- ## Exercise * make sure your branch is in a state you're happy with -- * push it (might not work, I have to figure this out) --- ## What have we learned? * How to retrieve a remote repository -- * How to stage and commit modifications -- * How to fix errors, before or after committing them -- * How to share the result of your work --- class: center, middle name: questions # Questions? [Nicolas Rinaudo] • [@NicolasRinaudo@functional.cafe] [Nicolas Rinaudo]:https://nrinaudo.github.io/ [@NicolasRinaudo@functional.cafe]:https://functional.cafe/@NicolasRinaudo