Verified Commit 23d3369d authored by Laurent Heirendt's avatar Laurent Heirendt
Browse files

content from previous advanced training

parent 593d7ac4
# 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 (1)
Make sure that your git is configured properly:
```bash
$ git config --global user.name "Firstname Lastname"
$ git config --global user.email "first.last@uni.lu"
```
Test whether your username and email have been registered
```bash
$ git config --list
```
Fork and then clone the tutorial repository
<a href="https://git-r3lab.uni.lu/R3/school/git/advanced-practice">https://git-r3lab.uni.lu/R3/school/git/advanced-practice</a>
```bash
$ git clone ssh://git@git-r3lab-server.uni.lu:8022/<first.last>/advanced-practice.git
```
# Getting Started (2)
* Please generate your SSH before with `$ ssh-keygen -t rsa` and set it in Gitlab!
* Add a remote `upstream`
```bash
$ cd advanced-practice
# add upstream URL
$ git remote add upstream ssh://git@git-r3lab-server.uni.lu:8022/R3/school/git/advanced-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
```
# Install the mergetool `kdiff3`
* Download it here: http://kdiff3.sourceforge.net/
* Setting up `kdiff3`:
```bash
$ git config --global --add merge.tool kdiff3
$ git config --global --add mergetool.kdiff3.path "<kdiff3 path>"
```
* omit `""` when setting up on Linux or macOS
**Note**: On UNIX, you can find the path of `kdiff3` by typing:
```bash
$ which kdiff3
```
On Windows, the path might be `C:/Program Files/KDiff3/kdiff3.exe`.
# A note on common commands:
This workshop will not cover in detail the following commands, assuming you are familiar with them:
- `git checkout`
- `git add`
- `git commit`
- `git log`
- `git show`
Feel free to ask any questions if you run into any issues!
For your reference:
```bash
$ git <command> --help
```
Replace `<command>` with the command you want help for.
Exit with `q`
../../2019-09-24_advancedGitTraining/slides/img
\ No newline at end of file
# Presentation Title
# Advanced Git Training
## Month XYth, 2019
## September 24, 2019
<div style="top: 6em; left: 0%; position: absolute;">
<img src="theme/img/lcsb_bg.png">
......@@ -9,11 +9,11 @@
<div style="top: 5em; left: 60%; position: absolute;">
<img src="slides/img/r3-training-logo.png" height="200px">
<br><br><br>
<h1>A catchy title</h1>
<h1>Advanced Git Concepts</h1>
<br><br><br>
<h4>
Firstname LastName, Title<br><br>
firstname.lastname@uni.lu<br><br>
<h2>
Laurent Heirendt, PhD<br><br>
laurent.heirendt@uni.lu<br><br>
<i>Luxembourg Centre for Systems Biomedicine</i>
</h4>
</h2>
</div>
[
{ "filename": "index.md" },
{ "filename": "overview.md" },
{ "filename": "gettingStarted.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
0. Subject 1
1. Subject 2
1. Installation and getting started
2. Amend last commit
3. Resetting to a previous commit
4. Reverting commits
5. Rebasing in Git
6. Git cherry-picking
7. Merging branches
8. 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.