Commit 5668c144 authored by Laurent Heirendt's avatar Laurent Heirendt
Browse files

Merge branch 'develop' into 'master'

Regular merge of develop

See merge request !47
parents 8968c03c 0f9b330e
Pipeline #14279 passed with stage
in 1 minute and 23 seconds
# 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.
# Theory: Git Amend
* Enables to change the specifics of the commit on HEAD (the last commit)
\ No newline at end of file
# Practical: Git Amend
* Start by creating and committing a file
```bash
$ echo "This file contains errors and needs to be amended" > amend.txt
$ git add amend.txt
$ git commit -m "this file needs to be amended"
```
* Check the commit
```bash
$ git log
```
\ No newline at end of file
# Practical: Git Amend - Commit Message
* Verify that your staging area is clear:
```bash
$ git status
```
* use the `commit --amend` with the `-m` flag to edit only the commit message:
```bash
$ git commit --amend -m "This commit title has been amended"
```
* See the commit message in the log has changed:
```bash
$ git log
```
# Practical: Git Amend - Commit Content
* In your editor, change the text in the amend.txt file:
```bash
"This file's content have been corrected"
```
* Check if the changed file is in the staging area:
```bash
$ git status
```
* With the changes stages use the following command to commit the changes into the previous commit:
```bash
$ git commit --amend -no-edit
```
* This will create and commit a new commit with the staged changes added.
* Force push your changes to develop
# 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"
```
# Theory: Git Cherry-picking
* It enables the user to pick specific commits from a list of commits.
Careful!
Cherry picking only picks the selected commit,
not everything up to that commit.
<div style="top: 15em; left: 30%; position: absolute;">
<img src="slides/img/cherryPick.png">
</div>
\ No newline at end of file
# Practical: Git Cherry-picking
* In your branch, create and commit a reference file
```bash
$ echo "This is the start of a commit chain" > reference.txt
$ git add reference.txt
$ git commit origin myBranch
```
* Create and commit two files in the develop branch
```bash
$ echo "This is a commit to keep" > keep.txt
$ git add keep.txt
$ git commit origin develop
$ echo "Ignore this commit" > ignore.txt
$ git add ignore.txt
$ git commit origin develop
```
\ No newline at end of file
# Practical: Git Cherry-picking
* Check the commit reference of the two commits in develop
* Chose the commit to keep and add it to your branch
```bash
$ git checkout myBranch
$ git cherry-pick <commit reference>
```
* Check the log again and see if the changes were applied correctly
* push the changes to the develop branch
```bash
$ git push origin myBranch -f
```
* The `-f` flag is used to force push into develop
\ No newline at end of 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
# Theory: Conflict resolution
* A conflict emerges when two files push two different changes
to a one target branch
* Some conflict may be resolved automatically, but major conflicts
always need to be resolved manually
* Tools exist to streamline conflict resolutions, we use kdiff3
\ No newline at end of file
# Practical: Conflict resolution using kdiff3
* create a branch named changeMicheal and in the editor you change
the content of `Michael.md`:
```bash
$ git checkout develop
$ git checkout -b changeMichael
```
Change Michael file...
```bash
$ git fetch upstream
$ git checkout develop
$ git merge upstream/develop
```
summary:
michael.md on develop:
```
# Michael
```
michael.md on changeMichael (example)
```
## Michael Evans
```
\ No newline at end of file
# Practical: Conflict resolution using kdiff3
If then there is a rebase done on develop:
```bash
$ git rebase develop
```
A conflict should emerge
* When facing the merge conflict message, use the command
```bash
$ git mergetool
```
* This opens kdiff3 if it was properly set up. Selecting A will keep the changes of the target branch,
while B will keep your changes. Selecting A and B will combine both changes to the merged file.
# Practical: Conflict resolution using kdiff3
* After resolving the conflicts, continue in your terminal
```bash
$ git rebase --continue
```
* Then check the status:
```bash
$ git status
```
* It shows you a `.orig` file. This `.orig` file contains information about the conflict.
```bash
$ rm _attendees/michael.md.orig
```
* You can either `rm` the `.orig` file, or you can use `git clean -fdx`.
\ No newline at end of file
# Getting Started
# Getting Started (1)
Fork and clone the tutorial repository
Make sure that your git is configured properly:
```bash
$ git clone ssh://git@git-r3lab-server.uni.lu:8022/<yourName>/presentations-internal.git
$ git config --global user.name "Firstname Lastname"
$ git config --global user.email "first.last@uni.lu"
```
Add a remote upstream
Test whether your username and email have been registered
```bash
$ git remote add upstream ssh://git@git-r3lab-server.uni.lu:8022/R3/school/advanced-git/presentations-internal.git
$ git config --list
```
Go to the develop branch
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 checkout develop
$ git clone ssh://git@git-r3lab-server.uni.lu:8022/<first.last>/advanced-practice.git
```
And create your own branch using the `-b` flag
# 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 checkout -b myNameBranch
```
\ No newline at end of file
$ 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`
# Theory: Amending with Git Rebase
* The same operations can be made with `git rebase -i`
* The flag HEAD~X will let you amend the X previous commits instead of just the last one
* In the Interactive rebase menu, be sure to select the `edit` option.
\ No newline at end of file
# Practical: Amending with Git Rebase
```bash
$ git rebase -i HEAD~3
```
\ No newline at end of file