Commit 78c1b858 authored by Laurent Heirendt's avatar Laurent Heirendt
Browse files

Merge branch 'develop' into 'master'

Regular merge of develop

See merge request R3/school/courses!55
parents 227340d8 3c05119b
Pipeline #16370 passed with stage
in 2 minutes and 2 seconds
......@@ -71,7 +71,7 @@ shall **be avoided**!
# How to update my fork?
As you have your own fork, it will not automatically update once the original repository is update.
As you have your own fork, it will not automatically be updated once the original repository is updated.
![bulb](slides/img/bulb.png) You have to update it yourself!
......
......@@ -76,7 +76,7 @@ shall **be avoided**!
# How to update my fork?
As you have your own fork, it will not automatically update once the original repository is update.
As you have your own fork, it will not automatically be updated once the original repository is updated.
![bulb](slides/img/bulb.png) You have to update it yourself!
......
......@@ -3,9 +3,7 @@
<img src="https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png" alt="GitHub" style="width: 200px;"/>
<img src="https://gitlab.com/gitlab-com/gitlab-artwork/raw/master/logo/logo-extra-whitespace.png" alt="GitLab" style="width: 200px;"/>
GitHub and GitLab are VCS systems.
GitHub/Gitlab are both **publicly available**, but GitLab can be **on-premise**.
GitHub and GitLab are online platforms for developing code using the VCS system `git`.
Positive point: GitHub and GitLab are (almost) the same.
......
......@@ -65,5 +65,5 @@ $ mv myFile.m myNewDirectory/.
Rename a file or a directory
```bash
$ mv myFile.m myNewFile.m
$ mv myNewDirectory myDirectory
$ mv myDirectory myNewDirectory
```
\ No newline at end of file
# Amend a commit
* Enables to change a commit on `HEAD` (the last commit)
* Start by creating and committing a file in the `attendees` directory:
```bash
$ cd attendees
$ echo "# Firstname Lastname" > myName.md
$ git add myName.md
$ git commit -m "Add firstname lastname to attendees"
```
* Check the commit in the `log`:
```bash
$ git log
```
# Example 1: change the commit message
* Verify that your staging area is clear:
```bash
$ git status
```
* Use `git commit --amend` to change the commit
* Alternatively, you can use the `-m` flag to edit only the commit message:
```bash
$ git commit --amend -m "Add title"
```
* Check the commit message in the `log`:
```bash
$ git log
```
# Example 2: change the commit content
* In your editor, change the text in the `myName.md` file. For instance:
```bash
My biography ...
```
* You can see that the file changed:
```bash
$ git status
```
* With the changes staged use the following command to commit the changes into the previous commit:
```bash
$ git add myName.md
$ git commit --amend --no-edit
```
* Check the commit content:
```bash
$ git show HEAD
```
* This will create and commit a new commit with the staged changes added and the same commit message.
# Cherry-picking
* Cherry-picking allows to pick one (or more) specific commits from a list of commits.
* Only the chosen commit(s) are picked, not everything up to that commit.
<div style="top: 8em; left: 25%; position: absolute;">
<img src="slides/img/cherryPick.png" height=500px>
</div>
# Example (1)
* Create and commit two files in the `develop ` branch
```bash
$ git checkout develop
$ echo "# Venue details" > location.md
$ # add and commit the file location.md
$ echo "# Speakers" > speakers.md
$ # add and commit the file speakers.md
```
# Example (2)
* Check the `log` and note down the `SHA1` of the commits you want to cherry-pick. Then:
```bash
$ git checkout myBranch
$ git cherry-pick <SHA1>
```
* Check the log again and see if the changes were applied correctly. Note the new SHA1!
```bash
$ git show <newSHA1>
```
* Repeat for the second commit
* Push the changes to `myBranch`
```bash
$ git push origin myBranch
```
* Note that the `-f` flag is not needed to force push (no history has been rewritten)
# Partial chery-picking
* Partial cherry-picking allows you to unpack the changes from a commit.
* Imagine you committed many files, and you want to remove certain files.
* In practice:
- You commited all files, and you realize that there is your data inside!
- You have committed accidentally sensitive data, such as your password
- You committed hidden files, for instance `.DS_Store` files
- ...
# Example (1)
* Hard reset the `myBranch` branch:
```bash
$ git checkout myBranch
$ git reset --hard HEAD~2 # do not preserve files
```
* Reset the `develop` branch:
```bash
$ git checkout develop
$ git reset HEAD~2 # preserve files
```
* Add the `location.md` and the `speakers.md` files as 1 commit:
```bash
$ git add location.md speakers.md
$ git commit -m "add location and speakers files"
```
# Example (2)
Cherry-pick the commit from `develop` over to `myBranch`:
```bash
$ git checkout myBranch
$ git cherry-pick -n <SHA1>
$ git status
```
Now, remove the file `location.md`:
```bash
$ git restore --staged location.md # old version of git: $ git reset HEAD location.md
$ rm location.md
```
Commit the changes:
```bash
$ git commit -m "add speakers file"
```
# Conflict resolution
* A conflict occurs when two changes change the same line in a file
* Some conflict may be resolved automatically, but major conflicts
always need to be resolved manually
* Tools exist to streamline conflict resolutions, we use `kdiff3`
* Conflicts can happen during `merge`, `cherry-pick`, and `rebase`
# Example 1: Conflict resolution when locally merging (1)
* Checkout the branch `myNewBranch` and change the file `template.md`:
```bash
$ git checkout myNewBranch
```
* Use your favorite editor and type:
```bash
# Advanced git training course
## Firstname Lastname
```
* Add and commit that change.
* Checkout the branch `myBranch` and change the file `template.md`:
```bash
# Advanced git training -- Course
## Firstname Lastname
```
* Then, save, add, and commit that change.
# Example 1: Conflict resolution when locally merging (2)
* Merge the `myNewBranch` into the `myBranch` branch:
```bash
$ git merge myNewBranch
```
* A conflict appears:
```bash
$ git merge myNewBranch
Auto-merging attendees/template.md
CONFLICT (content): Merge conflict in attendees/template.md
Automatic merge failed; fix conflicts and then commit the result.
```
* Start the merge tool:
```
$ git mergetool
```
# Example 1: Conflict resolution when locally merging (3)
* This opens kdiff3 if it was properly set up. There are 3 versions:
- **A**: version on `myBranch` before the recent change.
- **B**: version on `myNewBranch`
- **C**: version on `myBranch` after the recent change
* Resolve the conflict and save. Then:
```bash
$ git merge --continue
```
* If you check the status, you will find a `.orig` file. This is a backup and contains the conflict.
```bash
$ git status
$ cat template.md.orig
```
* If you do not need anymore the backup file, you can remove it.
* You can either `rm` the `.orig` file, or you can use `git clean -fdx`. **Tip:** use `--dry-run` first to list all files that would be deleted.
# Example 2: Conflict resolution when cherry-picking (1)
If you follwed **Example 1**, reset the `myBranch` branch:
```
$ git checkout myBranch
$ git reset --hard HEAD~1
```
Get the SHA1 of the commit on the `myNewBranch` branch:
```bash
$ git show myNewBranch HEAD
```
Then, cherry-pick that commit:
```bash
$ git cherry-pick <SHA1>
```
# Example 2: Conflict resolution when cherry-picking (2)
You will get a message that there is a conflict:
```
error: could not apply e3ffc09... edit content of template
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
```
* Start the merge tool as before:
```
$ git mergetool
```
* Resolve the conflict and save. Then:
```bash
$ git cherry-pick --continue
```
The remaining steps are the same as explained in **Example 1**.
\ No newline at end of file
# Getting Started
* Fork and then clone the tutorial repository
<a href="https://github.com/LCSB-BioCore/advanced-git-practice">https://github.com/LCSB-BioCore/advanced-git-practice</a>
```bash
$ git clone git@github.com:<first.last>/advanced-git-practice.git
```
* Add a remote `upstream`
```bash
$ cd advanced-git-practice
# add upstream URL
$ git remote add upstream git@github.com:LCSB-BioCore/advanced-git-practice.git
$ git fetch upstream
```
* Check the remotes with:
```bash
$ git remote -v
```
* Create the `develop` branch and your own branch `myBranch` based on the `develop` branch from `upstream` using the `-b` flag
```bash
$ git checkout -b develop upstream/develop
$ git checkout -b myBranch
```
\ No newline at end of file
# Ignore files
In the file `.gitignore`, all untracked files that should be ignored by `git` are listed:
```
.DS_Store
data
*.csv
```
If you want to exclude certain files from this list:
```
!*.yml
config/*.yml
```
This tracks changes in all yml file, but not in the `config` folder.
Examples: www.gitignore.io
\ No newline at end of file
../../2019-09-24_advancedGitTraining/slides/img
\ No newline at end of file
# Advanced Git Training - SIU
## October 10, 2019
<div style="top: 6em; left: 0%; position: absolute;">
<img src="theme/img/lcsb_bg.png">
</div>
<div style="top: 5em; left: 60%; position: absolute;">
<img src="slides/img/r3-training-logo.png" height="200px">
<br><br><br>
<h1>Advanced Git Concepts</h1>
<br><br><br>
<h2>
Laurent Heirendt, PhD<br><br>
laurent.heirendt@uni.lu<br><br>
<i>Luxembourg Centre for Systems Biomedicine</i>
</h2>
</div>
[
{ "filename": "index.md" },
{ "filename": "overview.md" },
{ "filename": "gettingStarted.md" },
{ "filename": "ignore.md" },
{ "filename": "amend.md" },
{ "filename": "reset.md" },
{ "filename": "revert.md" },
{ "filename": "rebase.md" },
{ "filename": "chPick.md" },
{ "filename": "merge.md" },
{ "filename": "conflict.md" },
{ "filename": "thanks.md" }
]
# Merging branches locally
* Merge a branch into another one locally
* Combines all the commits from a source branch onto a target branch
* In practice, this is very useful if you 'just want to try out something', or 'draft' something
# Example (1)
* Create a new branch from your `myBranch` branch:
```bash
$ git checkout myBranch
$ git checkout -b myNewBranch
```
* Add two files to the `myNewBranch` branch in two separate commits:
```bash
$ echo "# Trevor Westman" > trevor.md
$ # add and commit the file trevor.md
$ echo "# Gustav Bergen" > gustav.md
$ # add and commit the file gustav.md
```
# Example (2)
* Check the `log` of the `myNewBranch` and `myBranch` branches:
```bash
$ git log myBranch
$ git log myNewBranch
```
* Go to `myBranch` and merge the `myNewBranch` branch into it
```bash
$ git checkout myBranch
$ git merge myNewBranch
$ git log myBranch
```
# Overview
1. Installation and getting started
2. Ignoring files
3. Amend last commit
4. Resetting to a previous commit
5. Reverting commits
6. Rebasing in Git
7. Git cherry-picking
8. Merging branches
9. Conflict Resolution
# Rebasing (1)
* `git rebase` enables to shift forward your commits in time
* Move/combine a sequence of commits to a new base commit
* Avoid discrepancies when multiple people work on the same project
* Linear git history (no merge commits)
* Rebasing is like saying, “I want to base my changes on what everybody has already done.”
Imagine the following situation:
<div style="top: 14em; left: 25%; position: absolute;">
<img src="slides/img/beforeRebase.png" height="500px">
</div>
* There are commits on `develop` that aren't in `myBranch`.
# Rebasing (2)
* After rebase, the commits in the `myBranch` branch will be place on top of `develop`.
<div style="top: 5em; left: 25%; position: absolute;">
<img src="slides/img/afterRebase.png" height="500px">
</div>
# Example (1):
* A merge request against `develop` is still open. **Repository maintainer: review, and merge it.**
* Create a file in your branch `myBranch`
```bash
$ git checkout myBranch # if necessary
$ echo "# List of attendees" > list.md
$ # add and commit the file
```
* Then, update your `develop` branch from the `upstream` remote:
```bash
$ git fetch upstream
$ git checkout develop
$ git merge upstream/develop
$ git checkout myBranch
```
* Check the histories of both branches
```bash
$ git log
```
# Example (2):
* Rebase `myBranch` on top of the updated `develop`:
```bash
$ git checkout myBranch
$ git rebase develop
```
* Check the history of your branch again
```bash
$ git log
```
* If you pushed previously your branch `myBranch`, you need to rewrite its history remotely - you need to **force push**.
# Interactive Rebasing - flag `-i`
* An interactive rebase is performed with the `-i` flag:
```bash
git rebase -i <branch>
```
* Enables more precise control over the rebased commits
* Before committing many actions are available
```bash
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
```
# Example 1: Reword and fixup (1)
* Switch to your own branch `myBranch`
* Add and commit two files to this branch:
```bash
$ # git checkout myBranch && cd attendees
$ echo "# William Odell" > william.md
$ # add and commit the file william.md with the message 'add william to attendee list'
$ echo "# Roberta Ross" > roberta.md
$ # add and commit the file roberta.md with the message 'add roberta to attendee list'
$ git push origin myBranch
```
Now, we want to:
- Reword the first commit's message to: `Add William and Roberta to attendee list`
- Combine the second and first commit into one
- Omit the commit message of the second commit.
# Example 1: Reword and fixup (2)
* Perform an interactive rebase with the two last commits:
```bash
$ git rebase -i HEAD~2
```
* The dialog shows up (example):
```bash