owned this note
owned this note
Published
Linked with GitHub
---
title: Reproducible Research 3 - Git
tags: RR2023 - DS/QF
description:
slideOptions:
theme: night
---
<style>
.reveal {
font-size: 30px;
}
</style>
## Reproducible Research 3 - Git
Wojciech Hardy
<!-- Put the link to this slide here so people can follow -->
link: https://hackmd.io/@WHardy/RR-git2

---
### How does it work? (quick recap)

----

----

----

----

----

----

----

----

----

----

----

----

---
## Some additional info
### How to deal with the line endings

Git Bash is stylised as a Unix environment.
In Unix: the end of a line is represented as a Line Feed (LF).
In Windows: the end of a line is represented by a carriage return (CR) and a line feed (LF). Hence CRLF.
By default, Git tries to settle the conflict for you (e.g. converts LF to CRLF when saving to Windows and the other way when saving in Git)
Most editors handle this anyway but the warning might be annoying
----
### We can tweak some options
Change how automated conversion works:
[`git config --system core.autocrlf [true/false/input]`](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration)
Change whether warnings should be issued:
[`git config --system core.safecrlf [true/false]`](https://git-scm.com/docs/git-config)
Provide specific rules on handling formats, by [creating a `.gitattribute` file](https://git-scm.com/docs/gitattributes).
---
## Cheatsheet: Basic commands

----
## Cheatsheet: Advanced commands

----
### Useful links
[Read more on `git reset`](https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified)
[Other cheat sheet 1 (Atlassian)](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet)
---
## Answering questions from last week
1) What if we move our HEAD backwards?
Check [this tutorial for an easy step-by-step description](https://www.cloudbees.com/blog/git-detached-head) (the image comes from there)

Or [try this one if you like X-Men](https://hashrocket.com/blog/posts/x-men-days-of-future-past-explained-in-git) - it's actually helpful (if you watched Days of Future Past)!
Typically HEAD points to the branch ("you're currently here").
----
## Answering questions from last week
You can point it to an older commit instead: `git checkout 87ec91d`

This puts you in a "detached HEAD state".
----
## Answering questions from last week
Here you can:
1) panic and go back simply by redirecting it back to the branch, e.g. `git checkout master`
2) check what was done in this commit
3) create an alternate history:

(and turn it into a new branch if you want to keep it)
---
## Answering questions from last week
2) Grabbing only one file from a Git repository
Not that intuitive (Git sort of wants to look at whole snapshots), but here's how [you can download single files from e.g. GitHub (and similar) repositories](https://stackoverflow.com/a/14779969). E.g. if you accidentally delete something...
3) What's up with single - and double -- when writing terminal commands
It seems to be a remnant of two different conventions (one using single letters, and the other longer words), see [here](http://www.catb.org/esr/writings/taoup/html/ch10s05.html).
---
## Git commands: working with a central repository
<!-- .slide: style="font-size: 24px;" -->
**`git init --bare`** to create barebones for a central repository (with no initial commits)
**`git clone [repo_name] [clone_name]`** to create a linked copy of the **`repo_name`** repository.
**`git fetch`** grab information about new commits/branches from the central repository.
**`git pull`** to grab the (new) commits from the central repository to our repository.
**`git push`** to put our (newly created) commits in the central repository.
We're going to pretend we have two developers and a central repository.
---
## Quick recap
1. In our workspace, let's create a new folder RR_git2 and go inside
`mkdir RR_git2`
`cd RR_git2`
2. Let's create a repository named RecapRepo and go inside
`git init RecapRepo`
`cd RecapRepo`
`git status`
3. Change local user.name to "RecapRepoUser"
`git config --local user.name "RecapRepoUser"`
----
3. Create three files: commit the first; only stage the second; do nothing to the third
`echo "this file will be commited" > file1.txt`
`echo "this file will be staged" > file2.txt`
`echo "this fille will be in the working directory" > file3.txt`
`git add file1.txt`
`git commit -m "Added file1.txt"`
`git add file2.txt`
`git status`
----
4. In RR_git2 create a clone of the first repository; go inside
`cd ..`
`git clone RecapRepo RecapCloned`
`cd RecapCloned`
5. View the contents; check the status
`ls`
`git status`
6. View the `config` file in the `.git` folder.
---
## Exercise 5: simulating central repo with two locals
1. In your RR_git2 directory create a new, **bare** repository called "CentralRepo"
`git init CentralRepo --bare`
----
2. In your RR_git2 directory create a clone of the CentralRepo, named Dev1
`git clone CentralRepo Dev1`
----
3. In your RR_git2 directory create a clone of the CentralRepo, named Dev2
`git clone CentralRepo Dev2`
4. Set the local **`user.name`** for Dev1 repository to "Developer_1"
`cd Dev1`
`git config --local user.name "Developer_1"`
----
5. Set the local **`user.name`** for Dev2 repository to "Developer_2"
`cd ../Dev2`
`git config --local user.name "Developer_2"`
---
## So far all repositories are empty. Let's imagine:
1. Dev1 kick-starts the project by creating the branch with one commit and sending it `upstream`
`echo "This will be the file with code" > code.R`
`git add .`
`git commit -m "Added the file with code"`
`git status`
`git push`
`git status`
2. Dev2 wants to get up-to-speed so grabs the changes
`git pull`
---
## Divergence without conflicts
(graphs will appear later in the week)
---
## Exercise 6: fetching and updating before pushing
<!-- .slide: style="font-size: 24px;" -->
1. Create a readme.txt file in your Dev1 repository.
`cd ../Dev1`
`echo "some text" > readme.txt`
----
2. Stage, commit and push the file.
`git add .`
`git commit -m "Added readme.txt"`
`git push`
----
3. Go to the Dev2 repository.
`cd ../Dev2`
----
4. Run `git status`
`git status`
----
5. Fetch information about changes from the central repository. Run **`git status`**.
`git fetch`
`git status`
----
6. Pull the information. Check folder contents.
`git pull`
`ls` (or in explorer/finder)
----
7. Add a new line to readme.txt and create a readme.md file.
`echo "another line" >> readme.txt`
`echo "a markdown readme file" > readme.md`
----
8. Stage, commit and push the file to the central repository.
`git add .`
`git commit -m "Modified readme.txt and added readme.md"`
`git push`
----
9. In Dev1, create a text3.txt file with the line "A line added by Dev1". Stage, commit and push - what happens? Resolve the issue following the hints.
`cd ../Dev1`
`echo "A line added by Dev1" > text3.txt`
`git add .`
`git commit -m "Dev1 created text3.txt"`
`git push` (read the hints)
`git pull` (add a comment to the merge commit)
`git push`
---
## Divergence with conflict - merging
(graphs will appear here later in the week)
---
## Exercise 7: a merge conflict
<!-- .slide: style="font-size: 24px;" -->
Sometimes two different versions of a file exist. Git will try to make us merge them.
1. In Dev2, create a new file called text3.txt with the line "A line added by Dev2". Stage, commit and push.
`cd ../Dev2`
`echo "A line added by Dev2" > text3.txt`
`git add .`
`git commit -m "Dev2 creates a text3.txt file"`
`git push` Git will tell us we need to do a pull first. Let's try that.
`git pull` (read the hints and go to step 2)
----
2. There's a conflict because Dev1 committed a different text3.txt file earlier.
We're in a merging mode. We can edit the file (e.g. in Notepad) to figure out what should remain. Then stage it and commit it.
The merge becomes a new commit (try **`git log`**)
`git commit -m "Merged two versions of text3.txt"`
`git push`
---
## Let's talk: BRANCHES
`git branch [-l]` list/create/delete branches
`git checkout` move the HEAD pointer (switch between branches)
`git fetch` sync cached branches with remote
`git rebase [x]` make a branch [x] start from a different point
`git merge [x]` combine two branches (by joining [x] to the current)
---
## Stuck in VIM?
If you forgot about adding a message to your commit, you might have ended up in VIM. It's a free, text-editting software that sometimes feels like a trap.
*Tl;dr:* hit [ESC], then type **`:q`* * and press **`Enter`** .
Repeat your commit with a helpful description.
You can also try adding the comment in VIM instead, and then exit with **`:wq`** instead, which should do the commit with the comment.
See more in this [helpful Stackoverflow answer](https://stackoverflow.com/a/11828573).
---
## Useful links
[Read more on the three trees with the **`git reset`** guideline](https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified)
[Cheat sheet 1 (Atlassian)](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet)
[Git-scm in general](https://git-scm.com)
[Atlassian in general](https://www.atlassian.com/git)
If you need more, just Google tutorials/blog posts/YouTube videos until you find one that makes it clear :) Lots to choose from!
---